Comments (10)
We haven't released 0.6
yet but the latest version of the code in master is extremely modular and should make it possible to implement this easily on top.
For example, you can implement your own event-loop that regularly persistents an actor's state: https://github.com/Restioson/xtra/blob/master/xtra/examples/custom_event_loop.rs
I doubt that we will ever include something like this in xtra
itself. One of the design goals is to remain small and simple. It would be interesting to see this built on top and I am happy to discuss changes to any of the APIs if our building blocks don't fit your needs.
from xtra.
Thanks for the quick answer, appreciated.
Looks like with custom event loops this could be easily archived. However, I'm a bit worried about compatibility with other libraries that would also like to instrument actors in a similar fashion.
Imagine the situation where a library X would like to gather performance metrics. It would also need their own custom event loop to archive this.
Could it be possible to augment the current implementation to support this? A series of traits that would allow anything to hook up to an existing event loop lifecycle, based on something familiar like the tower::Service
trait.
from xtra.
library X would like to gather performance metrics. It would also need their own custom event loop to archive this.
Why would a library provide an event loop? I'd say providing the event loop is the job of the final application that composes all the actors.
Could it be possible to augment the current implementation to support this? A series of traits that would allow anything to hook up to an existing event loop lifecycle, based on something familiar like the
tower::Service
trait.
Possible yes, likely no. Mostly because:
a. We want to keep xtra small and focused
b. I don't understand the requirements well and thus whatever we'd build is likely wrong
Once 0.6
is out the door (no ETA because little time), we aim to be conservative with breaking changes so you are welcome to build your own library on top of xtra
that provides instrumentation primitives.
from xtra.
Also not that Actor
s already have lifecycle hooks and you can do whatever you want in those. Persisting another actor's state could even be an actor wrapping another actor, similar to a supervisor.
from xtra.
I understand, it was just a bit of brainstorming before doing anything.
I played with the idea and came up with this https://github.com/Altair-Bueno/xtra-persistence. Is still a rough prototype, but it does something.
My current idea is there are three kinds of Actors involved: The trigger (not implemented yet), the persistence provider and the targets (Actors to be persisted).
- Trigger: Has the address of other actor and sends them
TakeSnapshot
messages when something happens (control c, for example) - Persistence Providers: Handle the snapshot fetch and save
- Targets: The actual user actors. They take snapshots and sends them to the persistence providers. At startup they also ask the persistence providers if any snapshots are present.
The example https://github.com/Altair-Bueno/xtra-persistence/blob/08c707cd13560828d1f090843dcfe23e18ccd298/examples/mem.rs showcases an in memory persistence provider.
I think this could work, but is still a lot of boilerplate to set up. While you don't need to create a custom event loop, you still need to pass around the PersistenceProvider. And still, I have no idea on how to do journaling of the mailboxes. I tried the supervisor idea, but it feels like too much noise. If you have some spear time to look at project, I would love to hear some feedback!
from xtra.
from xtra.
Does it make sense to track all messages in that case?
Not every message needs to be track down. Persistence should be always opt in.
Maybe a wrapper type like PersistingMessage could help, for only messages
that should be persisted and return a ().
I though of something similar, but again a wrapper around the message just overcomplicates things.
I think the solution would be to replace Mailbox and Address with traits. They are tightly coupled with xtra, making it imposible to use another implementation. By using traits the following could be achieved.
// Clasic Mailbox
xtra::spawn_tokio(actor, MemoryMailbox::new_unbounded());
// With a given persistence provider. Loads the mailbox if it exists
xtra::spawn_tokio(actor, PersistentMailbox::new(persistence_provider));
Also, no custom event loop would be required.
from xtra.
I think the solution would be to replace Mailbox and Address with traits. They are tightly coupled with xtra, making it imposible to use another implementation. By using traits the following could be achieved.
What is xtra
then if not the Address
and Mailbox
types?
They are essentially an mpmc channel with typed reference-counters. If you take those away, there isn't anything left lol.
Everything around it are just helper functions that we settled on including to make life a bit more convenient. In your project, you should actually write your own spawn functions and event loop to exactly fit your needs (and reduce boilerplate).
from xtra.
Also, no custom event loop would be required.
You seem to misunderstand my/our1 design goals. An event loop is just that; a loop. There should be nothing special about it such that you'd want to reuse it.
Instead, being able to write your own loop is the whole point. It offers so much more flexibility without having to roll your own address and mailbox. Those are the bits that are tricky to get right.
Footnotes
-
Hopefully I am speaking for you too here @Restioson :) ↩
from xtra.
I played with the idea and came up with this https://github.com/Altair-Bueno/xtra-persistence. Is still a rough prototype, but it does something.
My current idea is there are three kinds of Actors involved: The trigger (not implemented yet), the persistence provider and the targets (Actors to be persisted).
- Trigger: Has the address of other actor and sends them
TakeSnapshot
messages when something happens (control c, for example)- Persistence Providers: Handle the snapshot fetch and save
- Targets: The actual user actors. They take snapshots and sends them to the persistence providers. At startup they also ask the persistence providers if any snapshots are present.
The example https://github.com/Altair-Bueno/xtra-persistence/blob/08c707cd13560828d1f090843dcfe23e18ccd298/examples/mem.rs showcases an in memory persistence provider.
I think this could work, but is still a lot of boilerplate to set up. While you don't need to create a custom event loop, you still need to pass around the PersistenceProvider. And still, I have no idea on how to do journaling of the mailboxes. I tried the supervisor idea, but it feels like too much noise. If you have some spear time to look at project, I would love to hear some feedback!
Had a quick look. Like I mentioned above, a custom event loop would make this a lot more concise. You can create a trait that needs to be implemented for each actor. That allows you to bypass the message queue and access the actors directly at the correct life-cycle point.
Sending messages won't work reliably because there is no guaranteed delivery. If an actor decides to stop, the next "Persist" message won't be delivered and you'll be missing the state updates since the last persist message.
If you write your own loop, you can directly hook into the lifecycle and persist directly after shutdown, thus capturing the entire state.
from xtra.
Related Issues (20)
- Way to mark time spent in queue and handler as follows_from request span HOT 4
- Have `Error::Disconnected` contain the actor name HOT 8
- Document features of `Context::stop_all` HOT 7
- Switch `WaitingSender` implementation to a oneshot channel implementation
- Re-organise cargo workspace
- trait for actors handling multiple message types HOT 4
- Actor with a CPU-bound task HOT 8
- wait for actor to finish processing entire mailbox HOT 10
- Review changelog and sort by priority HOT 2
- `as_either` for `MessageChannel`? HOT 3
- See if we can simplify `TickFuture` HOT 4
- Switch to IntoFuture trait instead of modifying SendFuture
- wasm_bindgen::JsValue within Actor? HOT 4
- Feature Request: relax return type in into sink HOT 2
- Receiver<M> support HOT 7
- Context::notify_later replacement examples HOT 6
- Should we still recommend `spaad` in the README? HOT 3
- Experiment with nightly async fn in traits
- Atomicity of handlers HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from xtra.