Cachowanie query
Wykonywanie obliczeń za każdym razem gdy wywoływane jest query było by bardzo nieefektywne. W związku z tym przygotowano mechanizm cachowanie rezultatów uzyskanych query.
Cache został zaimplementowany jako dekorator query. Wyspecyfikowano interfejs IQueryCache nieposiadający żadnych dodatkowych metod a jedynie będący znacznikiem że dana implementacja query jest cachem.
Najprostszą implementacją cache'a jest AbstractQueryCache. De facto ta klasa nie pracuje jako cache a jedynie opakowuje query oraz jego rezultaty dla poszczególnych agregatów. Poszczególne metody implementujące interfejs IQuery delegują wykonanie do opakowanego query. AbstractQueryCache jest ClassPropertyContainerem i udostępnia query jako property które może być wstrzyknięte za pomocą konfiguracji jAgE.
Rozszerzeniem klasy AbstractQueryCache jest QueryStepCache, opierający się na krokach które wykonywane są przez agenta. Definiuje limit odświeżania (natychmiastowego i odroczonego) jako liczbę kroków od ostatniego odświeżania.
Na potrzeby tej klasy (a w przyszłości zapewne także innych implementacji cache'a) zdefiniowano klasę CacheQueryResult będącą dekoratorem dla rezultatu query i w rzeczywistości agregującą rezultat, znacznik ostatniego odświeżania (w przypadku QueryStepCache jest to numer kroku) oraz boolowski znacznik określający czy w aktualnie wykonywanym wywołaniu query(IQuery, IAddressSelector) konieczne jest pełnie odświeżenie rezultatu.
W klasie QueryStepCache metoda init(IAgent) na opakowanym query jest wywoływana wyłącznie gdy opakowany rezultat jest jeszcze nullem lub został przekroczony limit kroków. W takim wypadku w CacheQueryResult znacznik boolowski jest ustawiany na true. W metodzie shouldStop(IAgent, IQueryResult) zwracana wartość zależy od ustawionego wcześniej w CacheQueryResult znacznika boolowskiego shouldRefresh. W metodzie update(IPropertiesSet, IQueryResult) rezultat jest rozpakowywany z CacheQueryResultu, przetwarzany przez query a następnie z powrotem pakowany i zwracany. Metoda finish(IAggregate, IQueryResult) jest wywoływana na opakowywanym query w zależności od tego czy przeprowadzono aktualizację. Cache przeznaczony jest do stosowania w dowolnym agregacie.
Prawdopodobnie konieczne będzie także zaimplementowanie klasy QueryTimeCache, opierającej się na timeotach i definiującej natychmiastowy oraz odroczony update (ten drugi wraz ze zwróceniem starej wartości). Cache taki byłby przeznaczony do stosowania na poziomie workplace'a, w szczególności w środowisku rozproszonym gdzie komunikacja między workplace'ami może być zaburzona lub nieefektywna.
Dostępne implementacje IQueryCache są ClassPropertyContainerami, więc mogą być definiowane w konfiguracji jAgE. Zaleca się aby implementować cache właściwy dla swoich potrzeb poprzez rozszerzenie klasy AbstractQueryCache i nadpisanie odpowiednich metod init(IAgent), shouldStop(IAgent,IQueryResult), update(IPropertiesSet,IQueryResult), finish(IAgent,IQueryResult).