Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default dispatcher binder of child coops #14

Closed
zumm opened this issue Jun 20, 2020 · 7 comments
Closed

Default dispatcher binder of child coops #14

zumm opened this issue Jun 20, 2020 · 7 comments
Assignees
Milestone

Comments

@zumm
Copy link

zumm commented Jun 20, 2020

There is a way to set dispatcher binder for coop. This binder will be used for all agents of that coop by default instead of the default binder from environment infrastructure. Is there a way to force child coops of that coop use this binder by default too?

@eao197
Copy link
Member

eao197 commented Jun 20, 2020

No, the current versions of SObjectizer do not support this. You have to store a dispatcher handle (or disp_binder) somewhere and use it during the creation of the child coops.

@zumm
Copy link
Author

zumm commented Jun 20, 2020

It feels hard to manage dispatchers. I want to use single dispatcher for all application, but see no way to do it simple. Is there a way to set my own dispatcher as default dispatcher for environment infrastructure may be?

@eao197
Copy link
Member

eao197 commented Jun 20, 2020

You can create your own environment infrastructure and return a binder to your dispatcher in overridden make_default_disp_binder() method. Your infrastructure can use one of the standard infrastructures under the hood and delegates all calls from environment_infrastructure_t interface (except make_default_disp_binder) to the instance of the standard infrastructure.

But maybe it is easier to make a reference to your dispatcher available for the whole SOEnv via your own layer (you can see an example here).

@ilpropheta
Copy link

ilpropheta commented Aug 6, 2023

I came across this discussion while searching for the very same question. @eao197 since agents can access their own cooperation handle by calling so_coop(), wouldn't be acceptable to provide so_binder() (or such) that returns the installed binder as disp_binder_shrptr_t ? This way, one can do:

introduce_child_coop(so_coop(), so_binder(), [](so_5::coop_t& c) {
	c.make_agent<test>();
});

or:

so_environment().introduce_coop([this](so_5::coop_t& c) {
	c.make_agent_with_binder<test>(so_binder());
});

Storing the binder just for this purpose can lead to weird code like this:

env.environment().introduce_coop([&](so_5::coop_t& c) {
	auto tpool = so_5::disp::thread_pool::make_dispatcher(env.environment(), 4);
       c.make_agent_with_binder<test>(
             tpool.binder(), // expected
             tpool.binder(),  // weird to pass twice...
            ... other stuff ...);
});

@eao197
Copy link
Member

eao197 commented Aug 6, 2023

Hi, @ilpropheta !

Your example:

env.environment().introduce_coop([&](so_5::coop_t& c) {
       auto tpool = so_5::disp::thread_pool::make_dispatcher(env.environment(), 4);
       c.make_agent_with_binder<test>(
             tpool.binder(), // expected
             tpool.binder(),  // weird to pass twice...
            ... other stuff ...);
});

can be rewritten this way:

auto tpool = so_5::disp::thread_pool::make_dispatcher(env.environment(), 4);
env.environment().introduce_coop(
   tpool.binder() /* the default binder for the whole coop */,
   [&](so_5::coop_t& c) {
       // There is no need to call make_agent_with_binder because
       // the new agent will use the default binder for the coop.
       c.make_agent<test>(
         tpool.binder(),  // expected...
         ... other stuff ...);
    });

but I understand that there can be cases when the parent coop uses one default dispatcher binder, but an agent in it uses another dispatcher binder.

So I think that it's possible to add two new methods:

  • so_5::coop_t::default_coop_binder() that returns the default binder for the coop (the default binder for a coop can be specified via so_5::environment_t::make_coop() method);
  • so_5::agent_t::so_this_agent_disp_binder() that returns the binder used for the agent.

And we'll have a possibility to write this way:

so_environment().introduce_coop(
   // Use the same binder as our coop.
   so_coop().default_coop_binder(),
   [&](so_5::coop_t & coop) {
      coop.make_agent<test>(...);
   });

or that way:

so_environment().introduce_coop( // No explicit default coop binder.
   [&](so_5::coop_t & coop) {
      coop.make_agent_with_binder<test>(
         // Use the binder that was used for the agent.
         so_this_agent_disp_binder(),
         ...);
   });

NOTE. Since v.5.8 the method so_this_agent_disp_binder() can easily be implemented because the agent's binder is now stored inside so_5::agent_t.

@ilpropheta
Copy link

Thanks @eao197 ! I didn't remember that shorthand, good point.
The only remaining issue is the child cooperation:

void so_evt_start() override
{
	introduce_child_coop(*this, [rec, this](so_5::coop_t& c) {		
		c.make_agent<test>(...);
	}); // the binder of this is not inherited
}

So introducing so_this_agent_disp_binder() would allow:

void so_evt_start() override
{
	introduce_child_coop(*this, so_this_agent_disp_binder(), [rec, this](so_5::coop_t& c) {		
		c.make_agent_with_binder<test>(...); 
	});
}

@eao197
Copy link
Member

eao197 commented Oct 17, 2023

Implemented in v.5.8.1.

@eao197 eao197 closed this as completed Oct 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants