AgE 2.7 : Actions Implementation

Model logiczny

Mechanizm akcji

W systemie jAgE istnieją dwa rodzaje akcji:

  • proste (SingleAction)
  • złożone (ComplexAction)

Klasa SingleAction reprezentuje pojedynczą akcję (akcję prostą). Zawiera adres agenta, na którym ma być wykonana akcja oraz kontekst akcji. Agregat, przyjmując zlecenie wykonania akcji w metodzie doAction, tworzy odpowiednie zdarzenie - obiekt klasy AgentActionEvent i dodaje je do swojej kolejki zdarzeń EventQueue.

Wszystkie dane konieczne do wykonania akcji są zawarte w jej tzw. kontekście, który jest dowolnym obiektem implementującym interfejs IActionContext

Akcje złożone (ComplexAction) nie zawierają same w sobie żadnych czynności do wykonania. Są natomiast kontenerami na inne akcje (proste lub złożone). Akcje te przechowywane są w strukturze drzewiastej, co zapewnia stałą kolejność wykonania akcji składowych oraz możliwość tworzenia dużych akcji z mniejszych akcji prostych lub złożonych. Dostęp do nich realizowany jest przez iterator zaimplementowany w abstrakcyjnej klasie Action.

Przykładową akcją złożoną może być wymiana energii pomiędzy dwoma agentami, w zależności od parametrów agentów uczestniczących w wymianie Powyższy diagram przedstawia hierarchię takiej akcji. Akcja ta składa się w dwóch akcji prostych:

  • Pobranie od pierwszego agenta określonej ilości energii, zawartej w kontekście akcji SubtractEnergyActionContext)
  • Dodanie drugiemu agentowi tej samej ilości energii (która opisana jest w obiekcie AddEnergyActionContext)

Poniższy fragment dokumentacji dotyczy implementacji akcji w wersji 2.2 jAgE i różni się od obecnego stanu.

Kod tworzący taką akcję może wyglądać następująco:

ComplexAction subtract = new ComplexAction();
subtract.addChild(new SingleAction(this.getAddress(), new SubtractEnergyActionContext(new Energy(energyValue))));
subtract.addChild(new SingleAction(toWhom, new AddEnergyActionContext(new Energy(energyValue))));

Akcje wykonywane przez agregat

Typ akcji do wykonania jest rozpoznawany na podstawie adnotacji - konteksty są adnotowane typem AgentActionContext, a adnotacją może być łańcuch znaków bądź ich tablica (na powyższym diagramie adnotacją jest tablica "example" i "otherAction"). Adnotowanie tablicą łańcuchów znaków oznacza, że dany kontekst może być użyty w wielu różnych akcjach.

Mechanizm wykonywania akcji w agregacie przewiduje implementację akcji jako metody agregatu. Taka metoda (na diagramie "performExampleAction") musi być oznaczona adnotacją @AgentAction (z nazwą akcji - na diagramie "example") oraz przyjmować dwa argumenty: agenta na którym ma być wykonana akcja oraz jej kontekst.

Przykładowa implementacja akcji, która usuwa agenta, przedstawiona jest poniżej:

@AgentAction("killAgent")
protected void performKillAgentAction(ISimpleAgent target, IActionContext context) {
  try {
    removeAgent(target);
    AgentActionEvent event = new AgentActionEvent(this, new SingleAction(target.getAddress(), context), null);
    // notifying aggregate monitors
    for (IAgentMonitor monitor : MonitorUtil.getCopy(_aggregateMonitors)) {
      monitor.agentKilled(event);
    }
    target.finish();
    target.objectDeleted(event);
  } catch (AgentException e) {
    _log.info("Cannot kill the agent [agent: " + target.getAddress() + ", parent: " + this.getAddress() + "]");
  }
}

Akcje wykonywane jako strategie

Interfejs IStrategyActionContext to interfejs znacznikowy (rozszerzajacy interfejs IActionContext), informujący agregat, że akcja odpowiadająca adnotowanemu kontekstowi ma być wykonana przez strategię.

Interfejs IActionStrategy jest wspólny dla wszystkich implementacji akcji opartych o strategie. Posiada metodę performAction pozwalającą na wykonanie akcji na dostarczonym agencie z dostępnymi parametrami, zawartymi w kontekście. Strategie pobierane są przez agregat na podstawie nazwy zawartej w adnotacji kontekstu akcji (AgentActionContext). Do pobrania odpowiedniej implementacji strategii wykorzystywany jest obiekt typu IComponentInstanceProvider, który pełni rolę Service Locatora - dostarcza na żądanie referencje do obiektów na podstawie zarejestrowanych wcześniej nazw. W przykładzie przedstawionym na diagramie konieczne byłoby, aby w konfiguracji pod nazwą "SampleAction" została zarejestrowana strategia SampleActionStrategy.

Zlecenie wykonania akcji

Powyższy diagram przedstawia proces zlecania wykonania akcji prostej. Podczas wykonywania obliczeń (w czasie wykonania metody step) obiekt typu SimpleAgent może zlecić swojemu rodzicowi wykonanie pewnej akcji (poprzez środowisko ISimpleAgentEnvironment). Agent tworzy nowy kontekst wykonania akcji (obiekt klasy np. SampleActionContext, jak w poprzednich przykładach), w którym zawarte będą wszystkie dane potrzebne do wykonania akcji. Następnie obiekt kontekstu jest opakowywany w odpowiednie obiekty typu Action, gdzie podawany jest także adres agenta, na którym ma zostać wykonana akcja. Taki obiekt akcji jest przekazywany do agregatu przez metodę doAction, celem dodania do kolejki akcji do wykonania. Agregat przyjmuje zlecenie wykonania akcji, tworząc odpowiednie zdarzenie (obiekt AgentActionEvent) i dodając je do swojej kolejki zdarzeń (EventQueue).

Wykonanie akcji

Wstępne przetwarzanie akcji

  • Agregat podczas przetwarzania zdarzeń wykonuje metodę processEvent
  • Pobiera ze zdarzenia akcje złożoną (obiekt action)
  • Inicjalizuje iterator i za jego pomocą przegląda wszystkie akcje proste, sprawdzając poprawność adresów agentów
  • Następnie z wykorzystaniem iteratora pobierane są kolejne akcje proste
  • Z pobranej akcji prostej pobierany jest adres agenta, na którym ma być wykonana akcja (target) oraz kontekst akcji
  • Na podstawie uzyskanych danych wybierana i wywoływana jest metoda implementująca akcję (patrz niżej)

Właściwe wykonanie akcji

  • Z kontekstu akcji pobierane są obecne w nim adnotacje
  • Jeśli kontekst jest adnotowany tylko jedną nazwą akcji, do wykonania jest wyznaczana ta nazwa
  • Jeśli kontekst jest adnotowany więcej niż jedną nazwą, nazwa akcji do wykonania pobierana jest z obiektu akcji SingleAction (metoda getActionToExecute). Dokonywana jest weryfikacja czy kontekst obsługuje akcję żądaną w SingleAction.
  • Po ustaleniu nazwy akcji do wykonania wyszukiwana jest jej implementacja
  • Jeśli kontekst jest typu IStrategyActionContext, odpowiednia strategia pobierana jest z kontenera za pomocą odpowiedniego {{IComponentInstanceProvider}}a
  • W przeciwnym razie (kontekst nie jest kontekstem akcji strategicznej) wyszukiwana i wywoływana jest odpowiednia metoda implementująca akcję w agregacie.

Attachments:

complex-action.png (image/png)
action-agent.png (image/png)
action-strategic.png (image/png)
action-hier.png (image/png)
singleaction-create.png (image/png)
action-validation.png (image/png)
action-execution.png (image/png)