On Thu, Nov 01, 2012 at 02:14:27PM -0700, Karl Falconer wrote:
>
> I am working on a project refactoring that I believe will benefit from
> ruote + state_machine. At a high level this application is a message broker
> between two systems that are sending Order information between each other.
> Orders originate from a Store, and are destined for a
> Warehouse. Communications is usually via WebService calls.

Hello Karl,

welcome to the ruote mailing list.


> There are many Stores, and many Warehouses within the system, each having
> their own endpoint.
>
> Here is an overview of the Order lifecycle, annotated with the various
> states of the order.
>
> # 1. Cron job, pull orders from Store every 5 min, persist to db => 'New'
> # 2. Kick off workflow engine (send to Warehouse)
> #     Step 1: Process order (business logic, filterning/transformations) =>
> 'Processed'
> #     Step 2: Send order to Warehouse => 'Sent to Fulfillment'
> #     Step 3. Acknowledge (to Store) order sent => 'Open'
> # 3. Cron Job, pull order status from Warehouse every 15 minutes, presist
> tracking => 'Shipped'
> # 4. Kick off workflow engine (send to Store)
> #     Step 1. Send tracking information to Store => 'Notified Shipped'
> #     Step 2. Acknowledge (to Store) order closed => 'Closed'
>
> With the exception of the 'Process Order' step, there is no human
> interaction required, the system just runs in the background. The 'Process
> Order' step may require human interaction if there is a failure within this
> step.

> So, after reading through many of the docs there are a couple questions
> that I have.
>
> 0. Is the lifecycle I've described a good use case for Ruote? It seems to
> address some of the limitation I was seeing when trying a pure
> state_machine approach.

"Order Lifecycle", sounds like a job for a state machine. Especially if
there is only one business object affected.

It's also nicely described in a state_machine state of mind.

A workflow engine feels like overkill for that.

I wonder what limitations do you have with state machines.

OK, doing the workflow concept thing anyway...


> 1. Would this be considered a single Process definition or two distinct
> definitions?
> Who/What would be the Participants?

Here's what it could look like:

  https://gist.github.com/3998104

The process definition looks like

---8<---
pdef = Ruote.define do

  order_manager :task => 'create order'

  warehouse_worker :task => 'process order'
  order_manager :task => 'update_order'

  store_worker :task => 'ship order'
  order_manager :task => 'update_order'
end
--->8---

It could be shortened to

---8<---
pdef = Ruote.define do
  order_manager :task => 'create order'
  warehouse_worker :task => 'process order'
  store_worker :task => 'ship order'
end
--->8---

if the _worker participants were wrapping the code for updating orders.

Just an exploration, not fitting your requirements exaclty (store/warehouse
are modelled as humans). I hope it's OK.

The first step (cron job to pull orders from store) could be skipped if the
store would launch the workflow immediately.

A workflow engine gets really valuable when there are multiple different
processes sharing participants.


> It seems like Participants
> describe tasks/actions and not Players, since there can only be one action.

No, Participants describe "players" (if I get your terminology right). You are
not limited to one action. See OrderManager in gist above.


> 2. How can I handle error workflows.

Please read

  http://ruote.rubyforge.org/process_administration.html#errors

> Say that an order fails at a
> particular step, how can I send an e-mail alert?

You can set an on_error at the process or at an expression level:

  http://ruote.rubyforge.org/common_attributes.html#on_error

Or you can set a global on_error at the "engine" level:

  http://ruote.rubyforge.org/configuration.html#engine_on

Those "on_x" thinggies point to participant or subprocesses. An email
participant might then come in handy.


> 3. I am a bit confused about how threading works for the Workers. Say for
> example, I have 10 orders, that are at various points within the
> life-cycle. Is there any blocking happening? What I am concerned about is
> the throughput of completing a workflow given that there is minimal human
> interaction.

Workers pick work on their queue in the ruote storage. A worker has a single
thread of execution. By default when dispatching work to a participant, it
happens in a dedicated thread (but you can disable that).

The workflow execution happens in small steps handed to workers in messages,
execution is mixed, there isn't a workflow instance blocking all the other
instances until it terminates.

The throughput depends on your worker count, your storage choice, the
reliability of the [external] services, the complexity of the process
definition, ...


> 4. Would this be an acceptable implementation for a Participant to send an
> Order to a Warehouse?
>
> def on_workitem
>   
> Warehouse.find(workitem.fields['warehouse_id']).send_order(workitem.fields['order_id'])
> end

It sounds right. In the bigger picture, it's probably missing a "receiver" to
listen for events/messages/workitems coming back from the Warehouse.


> 5. Is it recommended that I run the ruote engine within a Rails
> application, or kick it out into its own process? How would that change the
> interaction of the participants since it still needs to access data which
> is in the rails application?

It depends.

I tend to have a shared codebase and different start mode: front-end or ruote
worker. When in front-end mode, the worker is not started, the dashboard is
directly linked to the storage. When in ruote worker mode, worker is present
and has access to the models.

For testing/speccing, the ruote inside rails is convenient.

After that, it all depends on your situation. For a monolithic rails 
application it might not be bad.


Best regards,

--
John Mettraux - http://lambda.io/jmettraux

-- 
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