The Artima Developer Community
Sponsored Link

Legacy Design Forum
Event Generator Idiom



This page contains an archived post to the Design Forum (formerly called the Flexible Java Forum) made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.


....making more intelligent EventGenerator

Posted by akireddy on January 16, 2001 at 9:38 PM

> > > > The only problem that seems to plague the observer idiom in Java is
> > > > the throwing of errors in the listeners. What is your recommendation
> > > > for the cases where the listeners fail to catch errors and it
> > > > ends up blowing up the event generator? Would you typically
> > > > catch and ignore or let the listener blow you up.

> > > This is a good point. I'll have to think about this one, and
> > > would welcome other people's thoughts in the mean time. It
> > > seems to me on first glance that all my fireXXX() method is
> > > supposed to be responsible for is to deliver the event
> > > message to each listener. If a listener has a bug or some
> > > problem which results in an exception, my first inclination
> > > is to catch and ignore the Exception and then continue
> > > passing the event to the other listeners. I wouldn't catch
> > > Errors, but I think I might just be inclined to catch all
> > > Exceptions.

> > > The trouble with ignoring an exception is that then when the
> > > fireXXX method is done passing along the message, should it
> > > report back to its caller with some kind of exception? And
> > > what exception?

> > > I think what I lack here is clarity of the fireXXX's contract
> > > and the listener method's contract. I'll think about this
> > > one and post again later.

> > If you take a look at the TelephoneListener interface, you'll see
> > that the notification methods, telephoneRang() and
> > telephoneAnswered() don't have throws clauses. This means that
> > objects that implement this interface can't throw any exceptions
> > from those methods except RuntimeExceptions, which aren't
> > checked, and Errors.

> > My opinion is that Errors shouldn't be caught anyway, and
> > should usually result in the death of the thread. Errors
> > indicate a catastrophic problem, such as OutOfMemory or
> > StackOverflow.

> > RuntimeErrors, on the other hand, usually indicate a software
> > bug. Since listeners can't throw checked exceptions because
> > of the signature of the notification methods in the
> > TelephoneListener interface, the "contract" between the event
> > source object and the listener is that the notification methods
> > should not throw any exceptions. (The other part of the contract
> > is that the notification methods should return "quickly.")

> > So if the event source surrounds its invocation of the
> > notification methods with a try block, and catches all
> > RuntimeExceptions so that it can make sure it notifies all
> > listeners, it is basically trying to be robust in the face
> > of software bugs in the listener objects.

> > Given that the Event Generator idiom enables the event source
> > to know know anything about the listner objects other than they
> > implement the listener interface, it make sense to me that
> > event generators would implement this level of robustness against
> > software bugs in the listeners.

> > As far as what the fire() method should return when it has
> > caught and ignored one or more runtime exceptions, I can see
> > two possibilities. One is it can just bury them and return
> > normally. This makes some sense to me because I have no idea
> > what the caller is going to want to do in the case of a buggy
> > listener. (Perhaps the fire() method could print out a message
> > to an error log.)

> > Alternatively, the fire() method could collect the runtime
> > exceptions it catches and ignores and throw an exception that
> > is a "bucket" of the caught runtime exceptions, along with
> > some other information about the listener(s) that failed.

> > The question this issue brings to my mind is to what extent
> > should I program defensively against classes that are "breaking
> > their contract". It seems my program will be more robust if
> > I have some strategy for dealing with software bugs in listeners,
> > but how do I know that the whole program isn't going to be
> > broken if a listner has a bug in it. Any thoughts?

> Hi all,

> would this situation be a real-life example here for
> a listener not being able to process the request in a timely
> manner.. ?

> example : telephone rings, 3 other devices have registered
> their interested in listening, but one of them is
> way to busy or isn't equipped to handle the info
> between certain times. (9pm to 6am..)

> The listeners should in that case inform someway or the other
> about this to Event Generator. If we have the event listeners
> just receive the event and the event generator from which
> it is originating from, these methods can return immediately,
> making the event generator not to wait for them. Once the
> event generator receives a notification back from these
> listeners that all of them have succeeded, (here, the event
> generator itself behaves as an listener to ACK/FAILURE/SUCCESS
> messages from the other listeners ) it could get rid
> of the main event (telephone ring) or just archive back
> what happened to these listeners and go ahead. basically
> make the whole system work in a asynchrous event passing
> one..

> a small snippet below...

> public class TelephoneHandler implements TelephoneListener {

> void telephoneRang(EventGenerator eg,TelephoneEvent e)
> {
> //In this case, the EventGenerator is a Telephone object
> Thread ringHandlerThread = new RingHandlerThread(eg,e);
> ringHandlerThread.start();
> // method returns here.. the RingHandlerThread should
> // take care of intimating the EventGenerator abt. the
> // success/failure events..
> }

> void anyothermethodininterface()
> {
> }
> }

> but hey, this is first time writing back in a discussion
> group and to an author as good as bv. pretty nervous
> and curious about what I am going to hear back..;-)

> cheers,
> gopinath

Perfect...and this is what guru 'bv' has mentioned in Implementation guidelines (#5 of the article). Now the question is what if the subsequent logic of EventGenerator is dependent on the message outcome of the Handler thread(s)?.
How about this..
1) set/add the ringHandlerThread ref on EventGenerator
Thread ringHandlerThread = new RingHandlerThread(eg,e);
eg.addEventHandlerThread(ringHandlerThread); // new line
2) In EventGenerator class after raising the event, join() on the list of eventhandler threads added to it and continue --OR -- 'wait(..)' for a configurable period of time and check for the death of all threads (isAlive() on each thread) and if still any of the threads is alive possible because of the reason you have mentioned, then judge the consequences of it's result not being evaluated and proceed.

I believe developers working on multi-threaded env have solved this in many other ways.
Curious on 'bv's solution for this. May be this is not the right pattern for this situation



Sponsored Links

Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us