On Thursday, November 1, 2012 10:22:37 PM UTC-4, John Mettraux wrote:
>
>
> 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... 
>
>
I found the state machine very useful for defining state, and explicitly 
stating valid transitions. But I found I would rather have a separation 
between that various states of the object, and the process which changes 
the states. While this example is fairly simplistic, I would hope I could 
continue to use Ruote as the business rules became more complex. 
 

>
> > 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--- 
>
>
Thank you for the gist code sample, I was a bit confused as to why I kept 
seeing tasks defined as strings. Now I understand what is going on under 
the hood, and Participants are not limited to one task.
 

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

Can you expand on this a bit more? Are you saying have a second process def 
with a single task to get new orders, and have it run/re-try indefinitely? 
Would I need to launch a process def for each store at application start? 

Currently the cron job is polling a web service for new orders. I imagined 
that after orders were found, the Store would launch the workflow for each 
order that was saved. A single store could import as many as 100 orders at 
a single time. 
 

>
> A workflow engine gets really valuable when there are multiple different 
> processes sharing participants. 
>
>
There is also a separate process for syncing inventory between the two 
systems, and there would probably be a third process for importing products 
from one system to the other. 
 

>
> > 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, ... 
>
>
So I could create 3 worker instances all pointed to the same storage. This 
would enable the proces def's to run in parallel. And I am assuming, the 
workers would cycle through all of the items on the queue until each item 
was complete. In reality, I shouldn't need to have more than one worker if 
the web service calls are executed quickly enough. 


> > 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. 
>
>
Again, here I am polling with a cron job to update the order status for all 
the orders at each warehouse, after which I intended to invoke the process 
def to continue working on the order. Are you suggesting a better 
alternative is to use a receiver. Looking at the Beanstalk sample, I am not 
sure how a receiver would work in my case, can you expand a bit? 


> > 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. 
>
> It seems like ruote-kit inside my rails application could be an option 
then?
 
Thank you for your response, it was very helpful

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