Stiffstream / sobjectizer

An implementation of Actor, Publish-Subscribe, and CSP models in one rather small C++ framework. With performance, quality, and stability proved by years in the production.

Home Page:https://stiffstream.com/en/products/sobjectizer.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Asynchrony of register_coop

ilpropheta opened this issue · comments

Hi there,
following up my recent question (#53), I have another one on the cooperation registration process. As described here, it seems to me that returning from register_coop guarantees that the steps from 1 to 5 are performed. Thus, it seems to me that all subscriptions created during the step 2 ("The so_define_agent method has to be called for all agents from the new coop) are made.

It being understood that the return from register_coop doesn't mean that agents already started their work, does it mean that any messages sent to the channels they subscribed to will be discarded until step 6 is done?

Related: does the same hold for introduce_child_coop?

I am trying to understand if some parts of my agent registration actually need to wait until the process is fully completed.
For example, this way:

void Register()
{
	some_kind_of_event done;
	so_5::introduce_child_coop(parent_coop, [&](so_5::coop_t& c) {
	   c.add_reg_notificator([&](so_5::environment_t&, const so_5::coop_handle_t&) noexcept {
		done.set();
	   });
	   c.make_agent<...>(...);
	});
	done.wait();
}

Thanks!

commented

Hi!

does it mean that any messages sent to the channels they subscribed to will be discarded until step 6 is done?

No. If SObjectizer works correctly (I hope it does mostly) then agent will accept messages since steps 3 and 4 complete. When agent gets its event_queue from the dispatcher (at step 3) all messages sent to that agent will go to the agent's queue.

It allows to have logic like that: agents A and B are placed into the same coop (but bound to different dispatchers), agent A sends a message M to agent B in A's so_evt_start. The B will receive that message even if B's so_evt_start isn't called by the B's dispatcher. And all those actions could happen just inside register_coop.

Related: does the same hold for introduce_child_coop?

Yes. introduce_child_coop is just a handy wrapper around introduce_coop.

Thanks for the clarification!

In my scenario, I am only interested that my agents do not miss any messages. Starting to process such messages later is totally fine for me.

Imagine that all my agents subscribe to a certain channel X the typical way, that is inside so_define_agent. They are all in their own cooperation (to be able to commit suicide, as we discussed in the old #28) that is under a common parent cooperation (just for convenience, since they can all be deregistered at once).

All such agents are registered in a function similar to that I mentioned before:

void Register(...)
{
   so_5::introduce_child_coop(parent_coop, [&](so_5::coop_t& c) {
      c.make_agent<...>(...);
   });
}

Imagine something like this: a for loop that calls such Register function for every agent that needs to join the party.
Only after this for loop messages can start to arrive to that channel X I was mentioning before.

Am I on the safe side? To be clear again: I am not interested that messages are processed straight after that for loop, just that messages are not discarded (and then processed later when agents actually start).

I think it's the case and mine is probably just a doubt - since SObjectizer works correctly :)

commented

It seems to me that you are on the safe side.

It was just an unfounded doubt actually. Thanks @eao197 for your support and keep up with the great work!