Skip to content

Instantly share code, notes, and snippets.

@loganj
Last active December 23, 2015 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save loganj/6630117 to your computer and use it in GitHub Desktop.
Save loganj/6630117 to your computer and use it in GitHub Desktop.
This is probably a bad idea.
package com.squareup.otto;
/**
* A bus which supports detaching from its parent and attaching new children.
*
* THIS IS A THOUGHT EXPERIMENT. Don't freak out.
*/
public interface DetachableBus extends Bus {
/**
* Detach bus from its parent, making it a {@link Root}.
*
* Idempotent on roots.
*/
Root detach();
/**
* Make this bus the parent of the given bus.
*
* @throws IllegalArgumentException if child already has a parent (is not a root).
*/
void attach(Bus child);
/** @see com.squareup.otto.Bus#spawn() */
@Override DetachableBus spawn();
interface Root extends DetachableBus {
/**
* Turn on delivery of events to subscribers on the entire tree.
*/
void enableDelivery();
/**
* Turn off delivery of events to subscribers on the entire tree. Any attempted posts while
* delivery is disabled will result in a call to the dead event handler.
*/
void disableDelivery();
}
}
@loganj
Copy link
Author

loganj commented Sep 19, 2013

Immediate problems:

  • A root bus has no parent, but is also not detached. Does that suck?
  • You can't create a Bus in a detached state. Does that suck?

@pforhan
Copy link

pforhan commented Sep 20, 2013

So detaching also deactivates that bus? I would expect it to only break the link between busses.

@loganj
Copy link
Author

loganj commented Sep 20, 2013

@pforhan Correct. Essentially a bus can only be "live" if it has a path to its original root.

It might be easier to understand if it remains live, and we add an explicit enable/disable a la @piwai's proposal, with the key difference that enable/disable affects the entire bus tree.

@pforhan
Copy link

pforhan commented Sep 20, 2013

It'd be great if enable/disable weren't even present on non-root busses. Would it be worth lightly splitting Bus to allow that?

@pforhan
Copy link

pforhan commented Sep 20, 2013

Or, there could be a root() method or something that gives you a RootBus which is an interface with those two methods.

@loganj
Copy link
Author

loganj commented Sep 20, 2013

oh interesting.

@loganj
Copy link
Author

loganj commented Sep 20, 2013

@pforhan updated

@eburke
Copy link

eburke commented Sep 20, 2013

Curious how you know if it is safe to call enableDelivery() and disableDelivery(); this means the application code must know if the bus is or isn't a root.

Having either an isRoot() method or root() method might be useful. Otherwise we put burden of tracking which node is root onto the application code.

@loganj
Copy link
Author

loganj commented Sep 23, 2013

Thought this through a bit more. Has major problems with calls made during handler execution. I'm shelving the whole idea for now, more trouble than it's worth. Here are my notes:

  • what happens if there's an attach within a handler?
    • how are dispatch queues merged? what does the ordering guarantee mean here?
  • what happens if there's a detach within a handler?
    • what about enqueued events?
    • seems like we just proceed as normal, maybe. would that violate ordering guarantee?
  • what happens if the bus is disabled within a handler?
    • do we clear the queue, or just pause delivery?
  • can we just forbid detach/attach/enable/disable while handling an event?
    • would fit our only actual use case: onResume()/onPause()
    • does that mean we'd need to expose isDispatching() or something?
  • detach, reattach is going to thrash on queues.
    • could create queue lazily, only if needed.
      • good idea anyway?

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