On Mon, Jul 19, 2010 at 03:19:23PM -0700, I. E. Smith-Heisters wrote: > > I posted some code a while back that lets me pause my main thread > while the Ruote worker thread does work. The Ruote worker wakes the > main thread up when it's done. The point being that in certain very > important places I can simulate synchronicity with Ruote so human > users can be assured that they'll see the results of their (HTTP) > requests. > > The code I posted (below) relied on subclassing StorageParticipant and > overloading the #consume method. Now that we've added concurrency to > our process definition this approach has an unforeseen (but now > obvious) shortcoming. When we're in a concurrent branch, the > completion of one branch does not send the workitem to another > participant (since we're waiting on the other branch), and #consume is > never called. > > I have a couple possible fixes up my sleeve: overriding > Ruote::Exp::ParticipantExpression#reply to continue the waiting thread > (hacky), or not waiting in the first place if we're in a concurrent > branch (inconsistent behavior). However, I was wondering if someone > might have some suggestions that are less error-prone and better > supported by the existing interfaces (ie. no monkey-patching).
Hello, maybe you could have a look at Participant#on_reply. It was recently enhanced to work with "instantiated participants" (participants instantiated at registration time (I have the impression that it's what you use)). The test case is : http://github.com/jmettraux/ruote/blob/ruote2.1/test/functional/ft_43_participant_on_reply.rb Basically, it's a callback triggered when the workitem reaches back the participant. I'm not sure I fully understand your case. It seems that if there are multiple workitems in your engine, any of them will wake up the waiting thread when reaching a storage participant. Or, some speculation : what about a participant that explicitely wakes up your thread ? ---8<--- pdef = Ruote.process_definition do sequence do participant 'patient' do_the_work participant 'waker' end end module Bedroom @guests = {} def self.sleep (label) @guests[label] = Thread.current Thread.current.stop end def self.wakeup (label) t = @guests.delete(label) t.wakeup end end class PatientParticipant < Ruote::StorageParticipant def reply (workitem) label = workitem.fei.to_s workitem.fields['sleeper'] = label super(workitem) Bedroom.sleep(label) end end class WakerParticipant include Ruote::LocalParticipant def consume (workitem) Bedroom.wakeup(workitem.fields.delete('sleeper')) reply_to_engine(workitem) end end --->8--- (This assumes that the worker is running in the same ruby process as the web application). When the patient participant replies to the engine, the replying thread is put to sleep. It's woken up a bit later by a specific 'waker' participant. You could also rely on something inside "do_the_work" to wake up the thread. Sorry if I'm completely off. Best regards, -- John Mettraux - http://jmettraux.wordpress.com -- you received this message because you are subscribed to the "ruote users" group. to post : send email to [email protected] to unsubscribe : send email to [email protected] more options : http://groups.google.com/group/openwferu-users?hl=en
