Eventbus: ThreadMode.MAIN should cause events to queue

Created on 10 May 2016  ·  6Comments  ·  Source: greenrobot/EventBus

IMHO if a subscriber is configured as ThreadMode.MAIN, then events to it should always be queued for the next main Thread loop. Ie even if the caller is the main thread, the event would be added to the main thread queue instead of being delivered in the current thread of execution.

I say this because if you have caller1 (background thread) and caller2 (main thread) both posting EventA to a subscriber configured with ThreadMode.MAIN, then even though caller1 posts before caller2, caller1's event may get delivered last.

A classic example of this is where caller1 is notification of an event starting and caller2 is of event ending. Because caller2 is main thread, the order of the events gets reversed.

NB you may not always know what thread your callers will be invoked from, especially if the initiator is from another library.

If it is not palatable to enforce delivery to ThreadMode.MAIN subscribers in a separate main Thread loop, then ThreadMode.MAIN subscribers should be able to be configured to allow this to happen. Adding a new ThreadMode would suffice, eg ThreadMode.MAIN_DEFERRED.

Most helpful comment

I would expect that all events requested to be delivered via a certain delivery mode would be _processed_ in the order that they were posted. The actual order of delivery would depend on the semantics of the delivery mode.

Real life example was:

  • Network availability (background thread) initiates a connection to server and posts a start event. Subscriber is requesting event in MAIN thread as it needs to present UI on start of the connection.
  • Connection makes async call to a library and waits for connection success/fail callback. On success/fail a stop event is posted to a Subscriber configured for MAIN thread.
  • Library makes connection success callback in MAIN thread. Stop event is posted and appears immediately.
  • Start event is processed some time later.

I don't think performance is the right attribute to focus on here. Correctness is more relevant. The intent of an EventBus is to decouple event emitter from event consumer. By posting an event on the same thread as the emitter you are coupling the emitter to the consumer based on execution context. It is overriding the execution context explicitly defined by the subscriber.

All 6 comments

This would also be a solution to #318. Thanks for the PR!

@greenrobot This is worth a look.

-ut

Main reason for current behavior is performance. Also there is no strict event delivery order implied. Especially when using multiple threads. Do you have a real life example in more detail where this would help?

I would expect that all events requested to be delivered via a certain delivery mode would be _processed_ in the order that they were posted. The actual order of delivery would depend on the semantics of the delivery mode.

Real life example was:

  • Network availability (background thread) initiates a connection to server and posts a start event. Subscriber is requesting event in MAIN thread as it needs to present UI on start of the connection.
  • Connection makes async call to a library and waits for connection success/fail callback. On success/fail a stop event is posted to a Subscriber configured for MAIN thread.
  • Library makes connection success callback in MAIN thread. Stop event is posted and appears immediately.
  • Start event is processed some time later.

I don't think performance is the right attribute to focus on here. Correctness is more relevant. The intent of an EventBus is to decouple event emitter from event consumer. By posting an event on the same thread as the emitter you are coupling the emitter to the consumer based on execution context. It is overriding the execution context explicitly defined by the subscriber.

Makes sense. Thinking about doing it in two steps (e.g. version 3.1 and then 4.0): first allow a queued behavior, then make it the default. After all this might break stuff.

That makes sense to me. That was the intent behind #308 . Provide the capability and then make it default.
I have have come to believe that all events handled by the EventBus need to be handled async in order to completely decouple the poster from the subscriber. If in-thread execution is required then it is tantamount to an implicit method invocation. And implicit anything is a bad smell.

ThreadMode MAIN_ORDERED should be the default and pheraps other kind of behaviours can also be reworked. Pheraps a lot of code clean and optimizations can be done. Anyway i would wait for the first queued implementation before make some tests over it.
However thanks a lot for your work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

onomated picture onomated  ·  12Comments

timroes picture timroes  ·  9Comments

adhamenaya picture adhamenaya  ·  3Comments

liaohuyu picture liaohuyu  ·  4Comments

bdeneuter picture bdeneuter  ·  3Comments