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
