bethibande / actors Goto Github PK
View Code? Open in Web Editor NEWA actor framework and KSP processor/generator for kotlin.
License: Apache License 2.0
A actor framework and KSP processor/generator for kotlin.
License: Apache License 2.0
Improve code quality.
KotlinPoet is currently generating code with only 2 space indents instead of 4, it also declares everything as public which is redundant. Kotlin classes, functions and properties are public by default.
DoD:
The processor needs to be cleaned up a bit. Also the class names for commands, behaviors and other generated classes should be generated before the source files are generated.
The fact that class names are generated only when the source file is generated has caused some issues when adding the actor-system, as two classes required each others class name for generation.
Equals comparisons are not always possible right now since the getById function for example returns a new API instance every time it is called. These instances are all using the same actor instance to send their commands to, however without an equals function it will be imposible to compare them.
I just realized, there is no point to having an Actor class for every actor. The generated Actor classes are pretty much empty, they just implement the constructor of AbstractActor and have a companion object field which is the BehaviorMap of the actor.
If this field is moved to the API class instead, we can make the AbstractActor class non-abstract and use it as the default implementation.
This will make writing custom actors without code generation easier and further reduce the package size.
This should make generating source code easier. It will also allow for the customization of the code style for generated code.
Add a super-class (i.e interface or abstract class) for the Api classes generated by the processor.
This class should contain boilerplate code like the close function or another interface for the localActorSystem function of the companion object.
The super-class should also delegate some functions of the wrapped AbstractActor instance like isClosed and isRunning,
the send function may also become part of the super-class.
This will reduce the boilerplate generated by the processor. Chaning this boilerplate code or adding functionallity will be easier and may not even require a change to the code-generation after this change.
Implementing this change will also make implementing custom actors without the processor easier.
Add multiplatform support for the lib and processor.
The ActorSystem needs to store a reference to all actors it created, until they are closed.
Currently it is possible to create two actors with the same id, possibly allowing two instances of the same actor to exist at the same time.
In order to fix this the ActorSystem will need to have a list of map of all the actors it created and their ids. This will allow the ActorSystem to just return an existing instance if an actor with an existing id is created.
Just makes more sense at this point, especially now that reference counting for actors is implemented, the ActorAPI classes act as a reference to the actor with some additional API functions.
After #29, it will be possible that an actor has been closed but is still running in the background.
This renders it impossible to work with the actor.
This should be handled gracefully by simply waiting for the old actor to complete when calling ActorSystem.new with the id of an actor that is already closing.
When calling the close function of a generated API object and then immediately checking if the actor is closed will not work as the command may not have been processed at that point in time
Add "add" and "remove" functions, possibly also a "contains" function to all applicable fields.
Currently it's possible for an actor to exist twice if you close the actor and then re-create it. The problem with this is that the old actor may still exist in the background, processing all commands left in it's inbox from before it was closed.
In the worst case the closed actor may even write to the database whilst a new actor already exists causing inconsistent state.
Add documentation that shows how to manually create actors.
The base module was never really used and no contains no code and one, unused, proto-file which was supposed to be used for sharding.
The sharding module already has a new proto-file which does the exact same thing so there really is no need to keep this module around any longer.
Automatically running unit-tests is always good.
The will reduce the number of generated files.
Implementing commands this way should become the standard since it is easier and faster then having to create two classes just to add one command.
This should improve safety, letting the user and compiler know the actor is a resource that should be closed once it's not needed anymore
Code quality & stuff
Support sharding actor systems across multiple shards.
Increase stability and code quality.
This function will allow to explicitly fetch an existing actor. The 'new' requires to specify a state object, this can be inconvenient if you simply wish to fetch an existing actor, why should you have to supply a state?
I want to try and implement mustache for code-generation, however, I also do not want to remove the old kotlin-poet implementation.
The new mustache implementation will be experimental and should speed up development.
With mustache, generating docs and source code should be easier, with this it will also be possible to control the code style of the generated code. Kotlin poet does not support this.
As of right now it can be difficult to determine when to call an actors close function since an actor may be shared between two completely unrelated threads. If one thread calls the close function and the other thread still needs to use the actor this will cause the other thread to become unable to interact with the actor and encounter exceptions.
Reference counting will make this really easy as you can just get the actor you need and call its close function once you don't need the actor anymore. This will allow the framework to determine when it is safe to actually close the actor under the hood.
Sometimes the source files are not generated correctly. When rebuilding gradle/intellij seems to clear the generated source files, if you didn't modify the state class before rebuilding, all generated files are now gone and won't be regenerated.
This is likely due to KSP knowing the state file was not modified since the last build thus not regenerating the files.
DoD:
It's just annoying always having to open the gradle folder in order to edit the versions.toml file.
BehaviorMap is currently not thread-safe, if a BehaviorMap is modifier whilst actors already use it, the map could break or even throw exception. The behavior in such a situation is unknown.
Making the class thread-safe could be challenging due to the fact that read operations occur in a coroutine context but write operations don't, also the get method used to read the map is not suspending (could be though).
Simply synchronizing the map with a ReentrantReadWriteLock is not a good idea since that could lead to coroutine worker threads getting locked.
The current names for these functions may be confusing 'setCommand()', 'getCommand()' rename them to 'commandSet()', 'commandGet()'.
The same thing applies to the behavior functions 'getBehavior', 'setBehavior' and so on.
The closeCommand() function in the ActorStateType class should be renamed to commandClose() aswell.
With this the function names will also be more in line with the class names of the generated classes.
These classes are fine for the most part, but they are just not properly thread-safe. Some proper synchronization is needed to ensure these classes will work properly.
the LocalActorSystem.new function for example doesn't lock the id properly and if called twice with the same id from two threads it could cause the same actor to be created twice.
Creating an actor if it doesn't exist also doesn't work properly, using
if (system.exists(id)) system.getById(id) else system.new(id, state)
just isn't thread-safe.
Another issue is persisting an actor once it's completed. Currently actors already have a CompletableDeferred that can be used to wait for an actors completion however this is only used internally.
Adding a way to load and store actors to the ActorSystem should be usefull.
The LocalActorCache uses a Map which is also not synchronized, this could cause undefined behavior.
Making actor systems composabel could also be interesting.
Do not generate getters or setters for fields marked as transient.
Special handling for the MutableList class is needed as returning a MutableList will leak mutable state.
Filter classes annotated with @ActorState properly, it should not be possible to generate actors from object classes or interfaces for example. The processor should also throw an error if there are classes annotated with @ActorState that are not allowed.
The sharding module won't be usable for the foreseeable future and just gets in the way. Currently gradle cannot even build becaus of it.
A way to check if it is still possibly to interact with an actor. Sending a command to a closed actor will cause an IllegalStateException.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.