On Fri, Sep 18, 2009 at 11:08 AM, John Mettraux <[email protected]> wrote:
> On Thu, Sep 17, 2009 at 11:46 PM, krish <[email protected]> wrote:
>>
>> Say, I have a workflow that has a number of steps, a few of them being
>> concurrent. Some of these steps/participants talk to third party
>> products and the communication is asynchronous. They look at a
>> database field to check the status of those tasks as to whether or not
>> they finished and then move on.
>
> Hello Krish,
>
> I can than safely infer from the above paragraph that you wrote custom
> participants to perform those db-related tasks + communication with
> the third-party products.
>
>> I notice that each of these parallel
>> steps takes up 1 dedicated database connection. So, if I had 5
>> concurrent steps, it takes up 5 db connections per request. This seems
>> to be a bit ridiculous and more importantly, I am running into the
>> "ran out of connections" error. Any thoughts? Is this the expected
>> behavior?
>
> I don't know. YOU implemented it that way. Keep the "ridiculous"
> qualifier for your implementation.


OK, now let me try to help, it may be useful to someone.

I assume you're working with Ruby on Rails. You didn't tell but that
is my assumption.

With Rails 2.x, ActiveRecord's connection pool system has a dictionary
of connections, 1 connection per thread. The thread id is the key in
the dictionary.

Now ruote, in order not to block its execution loop, spins out a
thread per participant dispatch. It's a necessary thing. The engine
doesn't trust the participant implementation, it could take days and
before replying or simply die and never reply. Ruote has to protect
itself from that, hence the 1 thread per participant dispatch.

Now I can see two solutions to your issue.


A) add this method to your custom participant :

---8<---
def do_not_thread; true; end
--->8---

It will tell the ruote engine that your participant is "safe" and it
will thus not spawn a thread when dispatching to it.

The side effect will be that the dispatches to that participant will
share the same connection (since they will run in the single worker
thread of the engine.

It's now that you have to remember that while your participant is
working, the engine (and thus all process instances in it) will be
blocked waiting for it). You have to be extra-sure your participant
does reply, else you will have a stalled ruote engine.


B) modify the way your model gets its connection from ActiveRecord

ActiveRecord models have a class method named "connection" you could
override it this way :

---8<---
def self.connection
  @connection ||= ActiveRecord::Base.connection_pool.checkout
  @connection.reconnect! unless @connection.active?
  @connection
end
--->8---

This piece of code stores a single connection for its class.

I'm not sure this will work out of the box, but I'm sure that with a
bit of googling you'll find better examples and suggestions.


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