Programowanie reaktywne w jezyku Scala


Projektowanie systemu aktorów

Przykłady

  • git clone https://github.com/balis/reactive-lab2
        

    Uruchomienie w konsoli:

    cd reactive-lab2
    sbt "runMain reactive2.BankApp"
    sbt "runMain reactive2.ToggleApp"
        

    Uruchomienie w IntelliJ:

    Po otwarciu projektu wybieramy "sbt shell" na dolnej belce i po uruchomieniu środowiska wpisujemy:
    sbt "runMain reactive2.BankApp"
    sbt "runMain reactive2.ToggleApp"
        
    Ewentualnie sposob prostszy: klikamy prawym przyciskiem myszy na
    object BankApp
    i wybieramy
    Run: BankApp

    Konfiguracja logowania znajduje się w pliku src/main/resources/application.conf

  • Przykład BuddyChat
  • Zaktualizowana wersja znajduje się tutaj: https://github.com/agh-reactive/buddychat

    Uruchomienie przykładu:
    git clone https://github.com/agh-reactive/buddychat.git
    cd buddychat
    sbt run
      

Zadanie -- e-Sklep

Zadanie polega na zaimplementowaniu fragmentu systemu e-Sklepu złożonego z następujących aktorów:
  1. Cart: aktor reprezentujący koszyk na zakupy, który ma działać według następującej maszyny stanów:

  2. Checkout: aktor, który reprezentuje operację finalizacji zakupu, działający wg następującej maszyny stanów:

Separacja logiki dziedzinowej

Dobrą praktyką w projektowaniu systemu aktorów jest oddzielenie logiki dziedzinowej od logiki komunikacji. Przykładowo aktor Cart nie powinien implementować jednocześnie stanu koszyka i protokołu komunikacji, bo utrudnia to testowanie samej logiki biznesowej (stanu koszyka) -- można to robić tylko przez asynchroniczny protokół komunikacji. W tym przypadku najlepiej wydzielić klasę Cart reprezentującą obiekt dziedzinowy i aktora CartActor implementującego protokół komunikacji:
  case class Cart(items: Seq[Any]) {
    def contains(item: Any): Boolean = ???
    def addItem(item: Any): Cart     = ???
    def removeItem(item: Any): Cart  = ???
    def size: Int                    = ???
  }


 class CartActor extends Actor {
    def receive = {
      case AddItem(item, count) => ???
      ...
    }
  }

  object CartActor {
    def apply(): Behavior[Command] = Behaviors.receiveMessage {
      case AddItem(item, count) => ???
      ...
    }
  }

Zadania do wykonania:
  1. (20 pkt) Proszę zaimplementować aktorów CartActor i Checkout
    • Proszę zaprojektować wiadomości jako Case Class'y. Proszę pamiętać o rozróżnieniu na wiadomości-komendy (np. AddItem(...)) i wiadomości-zdarzenia (np. ItemAdded(...)) (ewentualnie również wiadomości-dokumenty). Więcej tutaj.
        object CartActor {
          sealed trait Command
          case class AddItem(id: String) extends Command
          ...
          sealed trait Event
          case class ItemAdded(id: String) extends Event
        }
              
    • Do sterowania maszyną stanów proszę wykorzystać standardowy mechanizm become.
    • Proszę stworzyć aplikację, która wykonuje prosty test stworzonych aktorów.
    • Do implementacji limitów czasowych proszę wykorzystać mechanizm timerów (do przeczytania również rozdział o Schedulerach). Aktor powinien zaplanować wysłanie wiadomości do samego siebie oznaczającej upłyniecie określonego terminu:
      • CartTimer: czas po jakim koszyk jest automatycznie opróżniany.
      • CheckoutTimer: czas po jakim rozpoczęta operacja finalizacji zakupu jest anulowana.
      • PaymentTimer: maksymalny czas oczekiwania na zrealizowanie płatności, po którym operacja zakupu jest anulowana.

  2. (10 pkt) Proszę wykorzystać Akka Typed do implementacji Aktora TypedCartActor.
  3. (10 pkt) Proszę wykorzystać Akka Typed do implementacji Aktora TypedCheckout.

Do implementacji powyższych zadań proszę wykorzystać przygotowany szablon z początkowymi testami znajdujący się tutaj: https://github.com/agh-reactive/reactive-scala-labs-templates Testy uruchamiamy komendą:

sbt test
Szablon został stworzony, aby ułatwić implementację zadań domowych i pozwolić na skupienie większej uwagi na implementacji istotnych części zadania. Może się zdarzyć, iż szablon w niktórych miejsach będzie wymagał poprawek. Takie poprawki można zgłaszać jako PR do odpowiedniego repozytorium na githubie - będzie to premiowane punktami za aktywność. Przy odbiorze zadań większy nacisk zostanie położony na zrozumienie poszczególnych fragmentów programów i mechanizmów akki.


Bartosz Baliś, balis at agh edu pl
Maciej Malawski, malawski at agh edu pl
Katarzyna Rycerz, kzajac at agh edu pl
Krzysztof Borowski, kborowski at agh edu pl