Comments (10)
Ah I see, thank you very much for the help! The linked example makes it very clear.
from xtra.
Ideally, I would structure such an example so that all the actors naturally finish when their work is done. With this, and the use of weak addresses, the final actor would have no strong references to it, so it would stop. Then, you can just await the actor future and return the relevant data from Stopped
. Otherwise, it could stop itself when done, presuming it has some level of introspection as to when it is done. If it does not, I would try and design it so that when there is no more input, then there are no more strong addresses to the actor, so the actor will naturally stop. That is the ideal use of the xtra actor lifecycle, imo.
Let me know if this doesn't work for any reason (clarification would be appreciated!)
from xtra.
Ok, I think I understand the idea, and it sounds exactly like what I would want. Am I correct in assuming that by "await the actor future" you're referring to the join
function?
I have something like this now:
let first_adr = xtra::spawn_tokio(MyActor::new(), None);
first_adr.send(DoSomething {}).await.unwrap();
// ...
// somewhere along the line there's a last future
last_adr = xtra::spawn_tokio(MyLastActor::new(), None);
let weakadr = last_adr.downgrade();
drop(last_adr);
// the following will wait for all copies of the strong address to be dropped
weakadr.join().await;
The only thing that's not working is to get something when it's stopped- it doesn't seem to be possible when spawning actors like this (it requires Stop = ()
). I that correct or am I missing something?
Thanks for your help!
from xtra.
Ok, I think I understand the idea, and it sounds exactly like what I would want. Am I correct in assuming that by "await the actor future" you're referring to the join function?
I am referring to the actor itself's future. See this example for more. join
simply returns when the actor itself stops, so it will return at the same time but not with the value of Stop
. Based on your example, I would try this:
let (first_adr, context) = Context::new(None);
let run_future = context.run(MessageCounter::default()); // `run_future` will resolve to `Actor::Stop`.
let handle = tokio::spawn(run_future);
let first_adr = xtra::spawn_tokio(MyActor::new(), None);
first_adr.send(DoSomething {}).await.unwrap();
// ...
// somewhere along the line there's a last future
let last_adr = xtra::spawn_tokio(MyLastActor::new(), None);
drop(last_adr);
// the following will wait for all copies of the strong address to be dropped [or the actor to call Context::stop]
let result = handle.await;
The only thing that's not working is to get something when it's stopped- it doesn't seem to be possible when spawning actors like this (it requires Stop = ()). I that correct or am I missing something?
This is an artificial limit to prevent users from throwing away the Stop
value by spawning an actor. You can use context.run(actor)
in this case instead.
from xtra.
Glad I could be of assistance!
from xtra.
I have one more question about how actors stop:
When there are no more strong Addresses left, does the actor stop immediately, or does it first finish processing all messages in its mailbox? I wasn't able to find anything about this in the documentation.
Also, I assume that when the actor is busy processing the last message in its mailbox, address.len()
will be zero, correct?
from xtra.
When there are no more strong Addresses left, does the actor stop immediately, or does it first finish processing all messages in its mailbox? I wasn't able to find anything about this in the documentation.
It will finish processing all messages. This should probably be mentioned explicitly in the docs but it isn't, like you noted.
Also, I assume that when the actor is busy processing the last message in its mailbox, address.len() will be zero, correct?
Yes.
from xtra.
Ok great, thanks for clearing that up. I'm collecting some small suggestions for the documentation and will make a pull request when it's ready.
There's some unexpected behavior I came across when trying to make sure that I don't have any more strong addresses to an actor left.
In my main function, I pass around a strong address (by cloning) to various actors, which will be dropped when the actors finish. I then want to overwrite the remaining variable in the main function by a weak address, using: let adr = adr.downgrade();
. The adr
at the left is weak, on the right-hand side it is strong. In my understanding, this should drop the strong address.
However, that doesn't seem to be the case. The statement above is not equivalent to the following:
let adr = {
let a = adr.downgrade();
drop(adr);
a
};
What am I missing here?
from xtra.
This doesn't drop the strong address as Address::downgrade
takes &self
, so it is not consumed. You could also do
let weak = addr.downgrade();
drop(addr);
from xtra.
This doesn't drop the strong address as
Address::downgrade
takes&self
, so it is not consumed. You could also do
Aah, I see.. should have taken a look at the signature. Thanks for clearing that up!
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
- 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
- Actor persistence and journaling HOT 10
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.