From: Goldsack, P. <pat...@hp...> - 2004-06-23 08:17:03
|
Qinyi, This is a conflict between what I suggested for OnEvent's use, and what I did in its design. I proposed that you could use a parallel containing a set of OnEvent handlers, each in single event mode, sitting on a queue, each handling a different event (exactly as you do). Of course, I then proceed to design the OnEvent component to terminate in single event mode if it receives an event it doesn't understand - thereby ensuring that the first event received by the queue is sent to all OnEvents, and each terminates even if they don't handle it... This has been fixed - now if the OnEvent component receives an event it doesn't know how to handle, it ignores it and continues to wait - whether in single event mode or multi event mode. I should also look in to why the exception was so completely unhelpful in this case - the workflow has not been quite so well developed as the rest from this perspective. Now, debugging workflows is easier if you switch on tracing - as in these circumstances you can see the various parts come and go, and the reasons for this (termination records, for example). To switch on tracing, there are a couple of ways of doing this: 1) set it for the daemon in default.sf (uncommenting the last line is the easiest) 2) include the tracing component as part of your workflow so that it gets deployed on a node for the duration that you want it (note that although it is deployed as part of your application it will still trace everything that happens on that node, and only that node). As it terminates, the tracing will stop. Using the latter method means that you do not have to stop and restart daemons if you have not enabled tracing in default.sf. In the case of your example, with tracing on, you get the attached... The key aspect is the abnormal termination of the OnEvent components due to unknown event receipt. If you want to save a trace that has appeared on the daemon display (if you have it enabled), you can save its contents using the "file->save" as menu. (Note in testing the fix - out of about a dozen attempts I have had a single failure, a liveness error reported. I think that somewhere I must have left the opportunity for a race condition to exist between part of the workflow terminating and the switching off of the liveness monitoring of that part. If you see this, please let me know, but otherwise ignore... I have it on my todo list and if it becomes a serious problem I will up its priority.) Patrick -----Original Message----- From: qx...@cc... [mailto:qx...@cc...] Sent: 22 June 2004 21:03 To: pat...@hp... Cc: qx...@cc...; sma...@li... Subject: Question about EventQueue Hi, Patrick Thanks for you quick response to my question. I checked out your new version of OnEvent.java from CVS and did two tests on it. I got error message on one of the testing cases. Could you please take a look at them? ----------------------------Test Case 1--------------------------- #include "org/smartfrog/sfcore/workflow/components.sf" #include "org/smartfrog/components.sf" #include "org/smartfrog/examples/helloworld/printer.sf" #include "org/smartfrog/examples/helloworld/generator.sf" sfConfig extends Sequence{ actions extends LAZY{ eventQueue extends Run{ action extends LAZY Parallel{ sfProcessComponentName "eventQueue"; queue_1_2 extends EventQueue; queue_1_3 extends EventQueue; } } comp_1 extends Run{ action extends LAZY Sequence{ sfProcessComponentName "comp_1"; actions extends LAZY{ waitEvents extends Parallel{ actions extends LAZY{ waitEnv_comp_2_FS extends OnEvent{ registerWith:a LAZY HOST localhost:eventQueue:queue_1_2; comp_2_FS extends LAZY DoNothing{ time 1000; message "-- comp_2_FS --"; } } waitEnv_comp_3_FS extends OnEvent{ registerWith:a LAZY HOST localhost:eventQueue:queue_1_3; comp_3_FS extends LAZY DoNothing{ time 1000; message "-- comp_3_FS --"; } } } } aEvent extends DoNothing{ time 1000; message "--component 1 started"; } terminate_queue_1_2 extends Terminator{ kill LAZY HOST localhost:eventQueue:queue_1_2; } terminate_queue_1_3 extends Terminator{ kill LAZY HOST localhost:eventQueue:queue_1_3; } } } } comp_2 extends Run{ action extends LAZY Sequence{ sfProcessComponentName "comp_2"; actions extends LAZY{ aEvent extends DoNothing{ time 1000; message "--component 2 started"; } eventSend extends EventSend{ sendTo:a LAZY HOST localhost:eventQueue:queue_1_2; event "comp_2_FS"; } } } } comp_3 extends Run{ action extends LAZY Sequence{ sfProcessComponentName "comp_3"; actions extends LAZY{ aEvent extends DoNothing{ time 1000; message "--component 3 started"; } eventSend extends EventSend{ sendTo:a LAZY HOST localhost:eventQueue:queue_1_3; event "comp_3_FS"; } } } } } } This one ran successfully. Its output was: HOST athena.cc.gatech.edu:rootProcess:comp_2:aEvent: --component 2 started HOST athena.cc.gatech.edu:rootProcess:comp_3:aEvent: --component 3 started HOST athena.cc.gatech.edu:rootProcess:comp_2:eventSend sending comp_2_FS to org.smartfrog.sfcore.workflow.components.EventQueue_Stub[RemoteStub [ref: [endpoint:[130.207.5.222:48959](local),objID:[27]]]] HOST athena.cc.gatech.edu:rootProcess:comp_3:eventSend sending comp_3_FS to org.smartfrog.sfcore.workflow.components.EventQueue_Stub[RemoteStub [ref: [endpoint:[130.207.5.222:48959](local),objID:[28]]]] HOST athena.cc.gatech.edu:rootProcess:comp_1:waitEvents:waitEnv_comp_3_FS:comp_3_ FS0: -- comp_3_FS -- HOST athena.cc.gatech.edu:rootProcess:comp_1:waitEvents:waitEnv_comp_2_FS:comp_2_ FS0: -- comp_2_FS -- HOST athena.cc.gatech.edu:rootProcess:comp_1:aEvent: --component 1 started ----------------------------Test Case 2--------------------------- #include "org/smartfrog/sfcore/workflow/components.sf" #include "org/smartfrog/components.sf" #include "org/smartfrog/examples/helloworld/printer.sf" #include "org/smartfrog/examples/helloworld/generator.sf" sfConfig extends Sequence{ actions extends LAZY{ eventQueue extends Run{ action extends LAZY Parallel{ sfProcessComponentName "eventQueue"; queue_1 extends EventQueue; queue_2 extends EventQueue; queue_3 extends EventQueue; } } comp_1 extends Run{ action extends LAZY Sequence{ sfProcessComponentName "comp_1"; actions extends LAZY{ waitEvents extends Parallel{ actions extends LAZY{ waitEnv_comp_2_FS extends OnEvent{ registerWith:a LAZY HOST localhost:eventQueue:queue_1; comp_2_FS extends LAZY DoNothing{ time 1000; message "-- comp_2_FS --"; } } waitEnv_comp_3_FS extends OnEvent{ registerWith:a LAZY HOST localhost:eventQueue:queue_1; comp_3_FS extends LAZY DoNothing{ time 1000; message "-- comp_3_FS --"; } } } } aEvent extends DoNothing{ time 1000; message "--component 1 started--"; } terminateQueue extends Terminator{ kill LAZY HOST localhost:eventQueue:queue_1; } } } } comp_2 extends Run{ action extends LAZY Sequence{ sfProcessComponentName "comp_2"; actions extends LAZY{ aEvent extends DoNothing{ time 1000; message "--component 2 started--"; } eventSend extends EventSend{ sendTo:a LAZY HOST localhost:eventQueue:queue_1; event "comp_2_FS"; } terminateQueue extends Terminator{ kill LAZY HOST localhost:eventQueue:queue_2; } } } } comp_3 extends Run{ action extends LAZY Sequence{ sfProcessComponentName "comp_3"; actions extends LAZY{ aEvent extends DoNothing{ time 1000; message "--component 3 started--"; } eventSend extends EventSend{ sendTo:a LAZY HOST localhost:eventQueue:queue_1; event "comp_3_FS"; } terminateQueue extends Terminator{ kill LAZY HOST localhost:eventQueue:queue_3; } } } } } } This one failed. Its output was: SmartFrog ready... HOST athena.cc.gatech.edu:rootProcess:comp_2:aEvent: --component 2 started-- HOST athena.cc.gatech.edu:rootProcess:comp_3:aEvent: --component 3 started-- HOST athena.cc.gatech.edu:rootProcess:comp_2:eventSend sending comp_2_FS to org.smartfrog.sfcore.workflow.components.EventQueue_Stub[RemoteStub [ref: [endpoint:[130.207.5.222:48959](local),objID:[6]]]] HOST athena.cc.gatech.edu:rootProcess:comp_1:waitEvents:waitEnv_comp_3_FSignoring unknown event comp_2_FS HOST athena.cc.gatech.edu:rootProcess:comp_3:eventSend sending comp_3_FS to org.smartfrog.sfcore.workflow.components.EventQueue_Stub[RemoteStub [ref: [endpoint:[130.207.5.222:48959](local),objID:[6]]]] HOST athena.cc.gatech.edu:rootProcess:comp_1 - error in starting next component java.lang.NullPointerException You can see that in testing case 1, each OnEvent component within the Parallel workflow is listening on its onw EventQueue. But in testing case2, both OnEvent Components are registered with the same EventQueue. I thought the EventQueue should support event registration from different components. Is this a problem with the logic in the EventQueue component? Thanks Qinyi > Qinyi, > > I have yet to change this, I will do so at the earliest opportunity. > Hopefully tomorrow...but no guarantees. > > I think that I will do the "terminate after first event" and > "terminate when told to do so" options, the former handling exactly > one message, the other handling as many as it gets up to the point it > is told to terminate. The alternative model you propose (1) can be > done by having a number of OnEvent handlers that deal with one event > each, within a parallel, with each OnEvent registering with the > parallel for events, and eveyone else sending events to the parallel. > > Patrick |