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

Add ability to execute notification on specific thread #6

Open
gelldur opened this issue Sep 9, 2018 · 12 comments
Open

Add ability to execute notification on specific thread #6

gelldur opened this issue Sep 9, 2018 · 12 comments
Assignees

Comments

@gelldur
Copy link
Owner

gelldur commented Sep 9, 2018

Eg. someone want to execute notification in background thread

@gelldur gelldur added the idea label Sep 9, 2018
@shenfumin
Copy link

shenfumin commented May 4, 2019

this feature is expected,espacially for AsyncEventBus.
the the consume() function is expected to be put into one background thread to process the event asynchronously.
the backgound thread may be like the following:
std::thread t( {
while (true)
{
getAsyncBus()->consume();
// using namespace std::chrono_literals;
// std::this_thread::sleep_for(1s);
}
});
t.detach();
but the consume() will lead the CPU load to 100% without some sleep. if you added some sleep, the event may not be consumed in time.
will you make the function consume() blocked if there is no event?

@gelldur
Copy link
Owner Author

gelldur commented May 4, 2019

Yes sure. It could be done.

@gelldur gelldur self-assigned this Jun 13, 2019
@gelldur
Copy link
Owner Author

gelldur commented Jun 15, 2019

@shenfumin I'm going to add: (brief example)

			if(bus.wait())
			{
				bus.consume();
			}

So it will wait until event come in. Also can be waitFor(10s) as timeout

@shenfumin
Copy link

thanks your information. it is good idea, i agree with you.

@Ristovski
Copy link

Ristovski commented Sep 28, 2020

Are there any updates to this? I noticed AsyncEventBus has been removed (but AsyncEventBusPerformance.cpp added in the same commit??), but I can not see an alternative mechanism for consuming events asynchronously (and calling the listeners on different threads).

@gelldur
Copy link
Owner Author

gelldur commented Sep 30, 2020

Hello
For now there is no possibility to handle event per thread. As EventBus 3.0 you may only handle events on specific thread calling EventBus::process() but you shouldn't call process from same bus on different threads, you should pick one and stick to it.

So you can add events from any thread as this is thread safe operation but processing events (calling listeners) is done on thread which is calling EventBus::process()

Currently I'm not planning to add such feature out of the box. Maybe you can add new "perk" to bus and decide on some tag that you pass on which thread process event.
Other solution may be to create MAIN EventBus which will pass event to other EventBus2 which will work on desired thread.

If you have any suggestions I'm happy to discuss.

@shenfumin
Copy link

shenfumin commented Oct 9, 2020

Are there any updates to this? I noticed AsyncEventBus has been removed (but AsyncEventBusPerformance.cpp added in the same commit??), but I can not see an alternative mechanism for consuming events asynchronously (and calling the listeners on different threads).

the most code had been changed, but the old version may be suite for you. you can checkout the old version for this issue

commit d51be92632576224f8976996dc02cfcae157fe61
Author: Dawid Drozd <[email protected]>
Date:   Mon Jun 24 19:10:01 2019 +0200

    Add AsyncEventBus::wait() function

then you can setup one thread to consume events asynchronously like the following

std::thread t( {
while (true)
{
getAsyncBus()->wait()
getAsyncBus()->consume();
}
});
t.detach();

@geiseri
Copy link
Contributor

geiseri commented Apr 26, 2021

In the absence of a proper event loop in c++ having a secondary listen-only event bus that is thread-specific. the main issue is that the execution of the event listener must run in the thread it was allocated. Maybe there can be a thread-aware listener that implicitly creates its own "listen-only" bus.

@geiseri
Copy link
Contributor

geiseri commented Apr 26, 2021

@gelldur actually isn't this was PassEverythingPerk would more or less do? You would create a bus on each thread, and then use the perk to forward everything to it? I guess the only issue there would be the removal of that when the thread exits. Or do I misunderstand what that does? Maybe it needs some more documentation ;)

@gelldur
Copy link
Owner Author

gelldur commented Apr 26, 2021

@geiseri yes you are right that was intention of PassEverythingPerk to have for example 2 event loops e.g. for logic and UI and pass events between those EventBus. I nned to prepare use case for such scenario. I'm also not so happy of such solution right now :) but we will see.

EventListener will be executed on thread which calls EventBus::process() it doesn't matter on which thread we create it. (It is thread safe)

@geiseri
Copy link
Contributor

geiseri commented Apr 26, 2021

I think I have a use case here, but it seems to be not working. I will try to put something in wandbox.

To be honest I think the best way is to have a thread-specific bus that is a subordinate of the main bus. Chances are that the thread might have a different scheduler or even event loop that would want to drive the bus. Since the bus itself is thread-safe everyone would publish back to the main one. I think the only issue you might run into is backpressure if a subordinate cant keep up. You wouldn't want to block the main bus, so you might need to introduce a TTL, or something.

My current case is that I have a main thread that needs to asynchronously communicate with an IO system that runs in a different thread. I need to be able to alert the main thread listeners when a message arrives, but I also need to send messages back. Since neither can block the other the bus seems the best option. Originally I was going to have a bus for rx and a bus for tx. The problem there is that the IO is in a thread pool, and coordination pretty much nullifies any decoupling the bus has to offer.
If each thread in the thread pool had its own subordinate bus that would solve this in a pretty slick way.

@geiseri
Copy link
Contributor

geiseri commented Apr 26, 2021

EventListener will be executed on thread which calls EventBus::process() it doesn't matter on which thread we create it. (It is thread safe)

The only reason I would want the thread-specific ownership would be to make it explicit it was tied to that thread. Since calling process from the wrong thread can cause interesting things to happen it would be nicer to the API consumer to make that hard to do =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants