# Problem 2: Actors ## Setup Use the following commands to make a fresh clone of your repository: ``` git clone -b concpar21final02 git@gitlab.epfl.ch:lamp/student-repositories-s22/cs206-GASPAR.git concpar21final02 ``` If you have issues with the IDE, try [reimporting the build](https://gitlab.epfl.ch/lamp/cs206/-/blob/master/labs/example-lab.md#troubleshooting), if you still have problems, use `compile` in sbt instead. ## Useful links * [A guide to the Scala parallel collections](https://docs.scala-lang.org/overviews/parallel-collections/overview.html) * [The API documentation of the Scala parallel collections](https://www.javadoc.io/doc/org.scala-lang.modules/scala-parallel-collections_2.13/latest/scala/collection/index.html) * [The API documentation of the Scala standard library](https://www.scala-lang.org/files/archive/api/2.13.4) * [The API documentation of the Java standard library](https://docs.oracle.com/en/java/javase/15/docs/api/index.html) ## Exercise Your task is to implement a couple of actors in Discord like service. You will only focus on two actors in the system: (1) the `NotificationService` and (2) and a `DiscordChannel`. A user will be able to post messages on the channel and retrieve the messages from the channel. A user also has the ability to (un)register from the notifications. Before it can receive requests, each channel is initialized with a notification service. When a message is posted to the channel, it tells its notification service to notify the users. The following diagram shows how the communication between actors works. Requests are within `()` and responses are within `[]`. ```none (Post) [Active] (GetLastPosts) ┏━━━━━━━━━━━━━━━━━━┓ [AlreadyActive] ┏━━━━━━━━━┓ ┌──────────────────────>┃ ┃──────────────────►┃ ┃ │ ┃ DiscordChannel ┃ ┃ System ┃ │ ┃ ┃◄──────────────────┨ ┃ │ [Posts] ┗━┯━━━━━━━━━━━━━━━┯┛ (Init) ┗━━━━━━━━━┛ ┏━━┷━━━┓ [NotActive] │ │ ┃ ┃◄────────────────────┘ │ ┃ User ┃ │ ┃ ┃◄────────────────┐ │ ┗━━┯━━━┛ [Registered] │ │ (NotifyAll) │ [Notification] │ │ │ │ │ │ ┏━━━━┷━━━━━━━━━━━━━━━━┓ │ └───────────────►┃ ┃ │ (Register) ┃ NotificationService ┃◄─┘ (UnRegister) ┃ ┃ ┗━━━━━━━━━━━━━━━━━━━━━┛ ``` Your tasks in the exercise will be to: TASK 1: Complete the implementation of the `NotificationService` by implementing method `receive` to handle messages from `NotificationService.Protocol`: ```scala def receive: Receive = ??? ``` TASK 2: Complete the implementation of the `DiscordChannel` by implementing methods `nonActive` and `active` to handle messages from `DiscordChannel.Protocol`: ```scala def nonActive: Receive = ??? def active(notificationService: ActorRef): Receive = ??? ``` ### NotificationService protocol * __Register__: Registers the user for notifications and responds with a `Registered(true)`. * __UnRegister__: Un-registers the user for notifications and responds with a `Registered(false)`. * __NotifyAll__: Sends a `Notification` to all registered users. ### DiscordService protocol The channel can be in one of two states: _non-active_ or _active_. * __Init__: When _non-active_, responds with `Active` and the state becomes _active_. Otherwise responds `AlreadyActive`. * __Post__: When _active_, stores the message and sends `NotifyAll` to its `NotificationService`. Otherwise responds `NotActive`. * __GetLastPosts__: When _active_, responds with `Posts` containing the latest messages (ordered from most to least recent). Otherwise responds `NotActive`. ### Running the code Apart from the grading tests, we include a `@main def debug` method, where you can write your own tests to help you debug your implementation. This method is __not__ graded. It can be executed using `run` within SBT.