{"id":20772656,"url":"https://github.com/rcardin/pcd-actors","last_synced_at":"2025-04-30T15:02:46.935Z","repository":{"id":82060620,"uuid":"47492203","full_name":"rcardin/pcd-actors","owner":"rcardin","description":"A system that implements the actor model.","archived":false,"fork":false,"pushed_at":"2016-10-02T08:23:30.000Z","size":147,"stargazers_count":8,"open_issues_count":0,"forks_count":31,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-03-30T17:11:11.486Z","etag":null,"topics":["actor-model","actor-system","java","teaching-materials"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rcardin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2015-12-06T10:27:23.000Z","updated_at":"2023-04-07T16:20:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"4f6a9d4f-3fc2-4b4c-a49d-1877b06a0c05","html_url":"https://github.com/rcardin/pcd-actors","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcardin%2Fpcd-actors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcardin%2Fpcd-actors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcardin%2Fpcd-actors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcardin%2Fpcd-actors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rcardin","download_url":"https://codeload.github.com/rcardin/pcd-actors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251725802,"owners_count":21633663,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actor-model","actor-system","java","teaching-materials"],"created_at":"2024-11-17T12:22:27.894Z","updated_at":"2025-04-30T15:02:46.873Z","avatar_url":"https://github.com/rcardin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pcd-actors\nA mock system that abstract a simplified implementation of the [actor model](https://en.wikipedia.org/wiki/Actor_model). \nThe system has to be considered as a mock because the main components are intentionally left abstract.\n\nThe main abstract types of the system are the following:\n\n * `Actor`: this type represents an actor, which can receive a message and react accordingly\n * `Message`: the message actors can send each others. A message should contain a reference to the sender actor\n * `ActorRef`: a reference to an instance of an actor. Using this abstraction it is possible to treat in the same way\n   local actors and actors that execute remotely\n * `ActorSystem`: an actor system provides the utilities to create new instances of actors and to locate them\n\nThe system was intended as a mock to realize the project of the Java course I run in the bachelor-level informatics \ncurriculum at the University of Padova (please, refer to \n[Programmazione Concorrente e Distribuita](http://www.math.unipd.it/~rcardin/pcd.html), in italian).\n\n## Logical architecture \n \nAll together they build the software architecture that in the figure below.\n\n![Class diagram of the logical architecture of the pcd-actor system](http://www.math.unipd.it/~rcardin/pcd/pcd-actors/Actor%20model_1.png)\n\nIn blue are colored the interfaces of the system. in order to let the system properly working, every interface MUST have \nat least a concrete implementation. In green are colored the type that have to be implemented / extended / completed.\n \nIt follows a brief description of each of the main logical types of `pcd-actors`.\n\n### Actor\nAn actor belonging to the type `Actor` holds the \"interface\" of the actor. The interface of an actor is identified by\nthe message it can respond to. The actor interface is fully defined by the method\n\n    void receive(T message) \n\nMessages received by an actor are not immediately processed. They must be placed inside a dedicated queue, called \n**mail box**. Messages inside mail box have to be processed *asynchronously*, which means that the processing of a \nmessage has not to block the receiving loop of other messages by the actor.\n  \nThe implementation of the actor must optimize the use of synchronized threads to satisfy the above requirements.\n\nAn actor has an actor reference (see the below type `ActorRef`) to itself and to the sender of the current processed\nmessage.\n\n#### Unknown messages\n\nIn the simple implementation requested by `pcd-actors`, if an actor does not know how to respond to a particular message \ntype, an `UnsupportedMessageException` is thrown. This is not the standard behaviour of an actor model. In a full\nimplementation of an actor model it should be a responsibility of the user to decide which action to take with respect\nto an unknown message.\n\nMoreover, the policy that let us thrown an exception in response to an unknown message is possible because in \n`pcd-actors` an actor cannot change its interface through time. Actually, throwing an exception will stop the actor,\nmaking useless any possible change of interface.\n \n### ActorRef\nA reference to an actor (formally an `ActorRef`) is an abstraction of the model used to address actors. There are two\ndifferent modes to address actors:\n\n * Local mode: the actor is running in the local machine\n * Remote mode: the actor may be running in a remote machine\n \nUsing this abstraction a remote actor can be used as a local actor, simplify the model of processing. (**WARNING: This \nfeature is not requested anymore**)\n \nOnce an instance of `ActorRef` was obtained, it is possible to send a messages to the corresponding actor using the \nfollowing method:\n \n    void send(T message, ActorRef to);\n\nTo do the magic, it is necessary to use the instance of `ActorSystem` described below. Messages can be sent only among \nactors. No other type can send a message to an actor.\n\n#### Actor reference for testing purpose\n\nFor *testing purpose*, it is necessary to give the possibility to retrieve the `Actor` associated to a reference. For \nthis reason, among the `test` types it's present the class `TestActorRef`. This class is a \n[*decorator*](http://www.slideshare.net/RiccardoCardin/design-pattern-strutturali) of the `ActorRef`\ntype, that adds a single method:\n    \n    protected abstract Actor\u003cT\u003e getUnderlyingActor(ActorSystem system);\n    \nUsing this method it is possible to retrieve the corresponding `Actor`. The above method **must be implemented**.\n\n### Message\nA `Message` is the piece of information that actor send among each others. Each message should be logically divided into\nthree parts:\n\n * A *tag*, which represents the operation requested by the message\n * A *target*, which represents the address of the actor receiving the message\n * A *payload*, which may represent the data that have to be sent with the message\n \n![Graphical representation of the structure of a message](http://www.math.unipd.it/~rcardin/pcd/pcd-actors/Message%20structure.png)\n\n### Actor system\nThe actor system (`ActorSystem`) has the responsibility to maintain reference to each actor created. Using the actor\nsystem should be the only way to build a new instance of an actor. The factory methods exposed by the `ActorSystem` type\nare:\n\n    ActorRef\u003c? extends Message\u003e actorOf(Class\u003cActor\u003c?\u003e\u003e actor);\n    ActorRef\u003c? extends Message\u003e actorOf(Class\u003cActor\u003c?\u003e\u003e actor, ActorMode mode);\n    \nThe former lets to build a local instance of an actor of the given type. The latter lets to decide if a local instance\nor a remote instance has to be built.\n\nThe actor system maintain the relationship between each actor and its reference, using a map. The map is indexed by\n`ActorRef` and it is located inside the `AbsActorSystem` type. Accesses to the map have to be properly synchronized.\n\nThe actor system has also the responsibility to stop an actor and to stop the entire system, using the following \nmethods:\n\n    void stop();\n    void stop(ActorRef\u003c?\u003e actor);\n\nStopping an actor means that it cannot receive any message after the stopping operation. This operation must be accomplished\n*gracefully*, which means that an actor has to process the messages that are already present in the mailbox before\nstopping.\n\nTrying to do any operation on a stopped actor must rise an `NoSuchActorException`. An actually stopped actor \nshould be eligible for garbage collection by the JVM an no thread should be associated to it anymore.\n\nThe `stop` method stops all the actors that are active in the actor system. Every actor has to be stopped *gracefully*,\nas stated in above sentences.\n    \n#### Singleton view of the actor system\nThe actor system MUST have a single active instance. This instance have to be necessarily initialized in the `main` \nmethod of the program.\n\nIn order to implement correctly the remote system, this instance have to be serializable. The best way to achieve this \nfunctionality is to use a *dependence injection* framework, such as [Google Guice](https://github.com/google/guice), \n[Spring](http://projects.spring.io/spring-framework/) or [CDI](http://docs.oracle.com/javaee/6/tutorial/doc/giwhl.html). \nHowever, the use of an DI framework is far beyond the scopes of this little project. \n\nSo, the above property must be fulfilled using other techniques, that do not use explicitly any form of design pattern\nSingleton\n\n### Type's interactions\n\nThis section shows how the above types interact with each other to fulfill the relative functionality.\n \n#### Actor creation \nTo create a new actor, ask the actor system to do the dirty job.\n \n![Actor creation](http://www.math.unipd.it/~rcardin/pcd/pcd-actors/Actor%20creation.png)\n\nSo, first of all, a client must obtain a reference to the actor system. Using this reference, it asks the system to \ncreate an new instance of an actor. The result of this request is the actor reference to the actor.\n\n#### Message sending\n\nOnce a client have obtained the references to two actors it can ask the first to send a message to the second. Clearly,\nto obtain the real instance of an actor (not its actor reference) the actor system must be queried.\n\n![Message sending](http://www.math.unipd.it/~rcardin/pcd/pcd-actors/Message%20sending_1.png)\n\nClearly, the `ActorRef` cannot be directly responsible of the `receive` method call on an `Actor`. The responsibility of\nan `ActorRef` is managing to let a `Message` to be put inside the `Actor`'s mailbox.\n\nMost of time, the client will be an actor itself, that ask to the self reference to send a message to another actor.\n\n## Building\n\nThe `pcd-actors` project is configured as a [Maven](https://maven.apache.org/) project. In detail, it was generated using the following command line:\n \n    mvn archetype:generate -DarchetypeGroupId=it.unipd.math.pcd.actors -DarchetypeArtifactId=pcd-actors -DarchetypeVersion=1.0-SNAPSHOT\n\nThe folder tree generate is the following:\n\n    project\n    |-- pom.xml\n    `-- src\n        |-- main\n        |   `-- java\n        |       `-- App.java\n        `-- test\n            `-- java\n                `-- AppTest.java\n\nAs usual, put the source files under the folder called `scr/main/java`; Put the test files (unit / integration) under\nthe folder `scr/test/java`.\n\nTo build the actor system library use the following command\n\n    $ mvn package\n    \nThe output library will be created by Maven inside the folder `target`, with name `pcd-actors.jar`. \n\nTo run the tests use the command\n\n    $ mvn test\n     \nThe output of the console will tell you if the build and the test processes have finished correctly.  \n\n## Testing\n\nTesting of each entity is done with [JUnit 4](http://junit.org/). As `pcd-actors` is a Maven project, tests are located\nin the `scr/test/java` folder. Integration tests will be added in the next weeks. These tests aim to verify that the\nwhole system satisfies above requirements.\n\nYou're free (which means that you're expected) to add your own tests to your implementation of the actor system.\n\n### Create an instance of `ActorSystem`\nTests need to create an instance of a concrete class that implements `ActorSystem`. Using the current architecture of\n`pcd-actors`, it is not possible to know which is the concrete class *a priori*. One solution to instantiate an object of \na concrete implementation of `ActorSystem` is using *reflection* mechanism. \n\nIn detail, the class `ActorSystemFactory` scans the classpath searching for all subtypes of class `AbsActorSystem`. \nThrough the method `buildActorSystem` it builds an instance of the first class found.\n \n    ActorSystemFactory.buildActorSystem()\n \nTo accomplish this need an external library is used. Such library is [`org.reflections`](https://github.com/ronmamo/reflections).\nThe library is added as dependency to the project only during testing process. Then, it cannot be used main code. \n\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.reflections\u003c/groupId\u003e\n        \u003cartifactId\u003ereflections\u003c/artifactId\u003e\n        \u003cversion\u003e0.9.10\u003c/version\u003e\n        \u003cscope\u003etest\u003c/scope\u003e\n    \u003c/dependency\u003e\n\n## F.A.Q.\n\n\u003e **Q**: The meta framework contains four interfaces and two abstract classes. What should I have to implement?\n\nIf you think about the testing process, you will sure understand that tests cannot be run on types that do not exist in\nthe original process. Then, you're not expected to implement the `Message` interface, nor to give a concrete \nimplementation of `AbsActor`.\n\n\u003e **Q**: Implementations should create abstract or concrete type?\n\nIt depends: a user of `pcd-actors` has not to give an implementation of `ActorSystem`, then it is up to you to give a \nfull implementation of this type. Also `ActorRef` needs at least two implementation: one that refers to local actors,\nand one that refers to remote actors.\n\n\u003e **Q**: We have to implement some synchronized data structures. `Actor` and `ActorSystem` have to be implemented has\n  thread their own?\n  \nNo, they don't. These two types probably generates many threads to accomplish to their scope, but they are not intended\nto be thread on their own.\n\n\u003e **Q**: `ActorSystem` is a Singleton?\n\nIn an idyllic and perfect world we would used a *dependency injection* framework, to guarantee that `ActorSystem` will be\ninstantiated only once. Unfortunately, we can't use such frameworks, due to their complexity. You can't implement \n`ActorSystem` as a Singleton neither. Then, you have to be sure that every object that has to use an instance of \n`ActorSystem` will use the same one.\n\n\u003e **Q**: Can a user of `pcd-actors` extend `ActorSystem`?\n\nNo, she definitely can not\n\n\u003e **Q**: How will `ActorRef` interact with the rest of the system? Which is its role?\n\n`ActorRef` decouples the implementation of an actor from the way it is invoked by another actor. Then, there will be\nat least two implementation of this type: one that refers to local actors, and one that refers to remote actors. Its\ninteraction with the rest of system is summarized in the following sequence diagram:\n\n![Message sending](http://www.math.unipd.it/~rcardin/pcd/pcd-actors/Message%20sending_1.png)\n\n\u003e **Q**: The logical view that was given of the `Message` type is equal to its physical view (a.k.a. implementation), \n  isn't it?\n    \nNo, the logical view was given to describe the generic actor model. In `pcd-actors` `Message`s are completely free of\nimplementation, from a library point of view.\n\n\u003e **Q**: How does an `Actor` instance acquire the reference to the sender `ActorRef`\n\nYou don't have to use the `Message` to implement this feature.\n\n\u003e **Q**: A user of `pcd-actors` can use only the methods of the interfaces that are defined in the meta-framework, \n  can't she?\n  \nDefinitely yes. You can add which ever method you desire, but these will not be tested and valuated.\n\n\u003e **Q**: Why can we send only messages of type `Message` to actors?\n\nThis is a simplification. This way, we can define a custom protocol of communication among actors that is the same in\nall the implementations of the library and relies on the object oriented principles.\n\n\u003e **Q**: If the meta-framework gives only the abstract class `AbsActorSystem`, how the hell will the tests to use the\n  library?\n  \nThis is a good question. I think I will use some reflection to discover which of your classes extends `AbsActorSystem`.\n\n\u003e **Q**: Do we have to implement the `receive` method of the type `Actor` for the project? \n\nNo, you don't. That is the hook that a user of `pcd-actors` have to implement to use the library.\n\n\u003e **Q**: A client that intends to use both local and remote actors might interacts with them in the same way, \n  doesn't she?\n  \nLocal and remote actors have to expose the same interface to a client.\n\n\u003e **Q**: How can I guess when the actor have to process the next message?\n\nThis is the focal point of the project and I can't tell you how to implement this feature ;)\n\n\u003e **Q**: Can a `Message` contain some logic or is it a simple placeholder that tells an actor what to do?\n  \nAs previously stated a `Message` must not have any implementation. Refer to \n[Akka/Java: Handling multiple message types inside a custom actor?](http://stackoverflow.com/questions/25917613/akka-java-handling-multiple-message-types-inside-a-custom-actor)\non Stackoverflow to understand why.\n\n\u003e **Q**: An `Actor` is an immutable object? Can an `Actor` change its interface?\n\nAn actor can change it's interface in the original actor model. In `pcd-actors` we can operate a simplification and **we\ndon't allow an actor to change its interface during time**. An actor has an internal state that changes during time. So\nit cannot be consider as an immutable object.\n\n\u003e **Q**: An actor that sends a message to another actor have to receive back an ack/nack message, doesn't she?\n\nNope. We do not want to implement any predefined protocol of communication between actors. It will be up to the end-user\nto define a protocol such that.\n\n\u003e **Q**: Can we use some external framework to implement the meta-framework, such as Spring?\n\nI prefer that you don't add any additional framework to the original project. The only framework you can use is \n[Mockito](http://mockito.org/) during unit test process\n\n\u003e **Q**: Can we use external tools to check the style of the code we will produce?\n\nYes, you can (and you should do too). \n\n\u003e **Q**: Can we add some methods to the given classes? \n\nYes, sure. You can add whatever method you think it could help. But, be aware: Do not modify the public interface of \nthese types because unit tests cannot rely on your custom interface.\n\n\u003e **Q**: Should an `ActorRef` call directly the method `receive` of the corresponding `Actor`?\n \nUsing the current architecture it is not possible. First of all, a `Message` has to be put into the `Actor`'s mailbox. \nThen the `Message` becomes eligible for elaboration.\n\n## License\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Riccardo Cardin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated \ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the \nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit \npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the \nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE \nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR \nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR \nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frcardin%2Fpcd-actors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frcardin%2Fpcd-actors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frcardin%2Fpcd-actors/lists"}