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

Reply via email to