You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

BeanFlow is a lightweight Java library for building flows using beans to orchestrate events. You can think of BeanFlow as a simple alternative to BPEL where the flows are all specified and implemented using Java code rather than declarative XML.

Motivation

When building highly concurrent or distributed applications it is very common for there to be many events happening; often asynchronously and in different threads and its very common to need to perform kinds of workflow or orchestration across these events.

Now you certainly can use things like BPEL to solve these kinds of problems. However often this is a bit heavy weight & complex and you just want to have a bean based flow using regular Java code to represent the flow.

Use cases

When working with concurrent or distributed applications there are many use cases for needing to orchestrate among multiple concurrent events. Here are a few examples from our use cases implementing ServiceMix and ActiveMQ

  • starting dependent services; where a parent component is dependent on the child components starting; where the start process may be asynchronous in different threads. e.g. there may be a recovery process on startup which you need to wait for.
  • implementing master-slave type protocols where you need to monitor the state of the master and slave to make decisions on what to do; together with dealing with transitions from Started to Recovering to Running then maybe to FailingOver etc.
  • implementing message orchestration. You may want to implement some simple orchestrations, waiting for either a response to arrive or a timeout to fire etc

Flow overview

A flow is just a POJO which implements the Flow interface. A flow has a simple lifecycle, you can start them and stop them and ask their status.

Once a flow has been started via the start() method it can take an arbitrarily long time to complete; you can see if the flow has completed via the isStopped() method. You can explicitly complete a flow using the stop() method whenever you like; typically when you are responding to state changes.

A flow could fail for some reason (such as it timed out or some error occurred) so there is a method isFailed() which can be used to easily inspect the flow. Rather like the stop() method, you can call fail(reason) if you wish to terminate a flow with the flow marked as the Failed rather than Stopped state.

Using timeouts

Its very common to add timeouts onto flows so that if the flow is not complete by a certain time then the flow is stopped & failed; often another parent flow may then do something differently if one of its child flows fails.

There is a useful base flow called TimeoutFlow which you can derive from to make your own flow which can be started/stopped/failed and which can be timed out.

You can explicitly register the flow with a timer and call the onTimedOut() method yourself or just call the startWithTimeout() method to start the flow registering the timeout.

Composing flows

One of the main reasons for using an object orientated language is to make composition and reuse possible; similarly BeanFlow allows you to compose flows together to make modular and reusable workflow constructs easily. So BeanFlow attempts to create a collection of reusable flows which you can then use to derive from or aggregate to make whatever flows you need.

Composition Flows

Description

JoinAll

Performs a join on all the given child flows. So the flow waits until all the child flows have completed, then it completes itself. You can add additional constraints to the flow using derivation. The default is to wait for all the child flows to complete; though you can enable fast-fail mode so that the flow fails as soon as a child flow fails

JoinQuorum

This flow is useful for implementing clustering style flows where you want a quorum of flows to complete. e.g. if you have 5 child flows you want to wait for at least 3 flows to complete succesfully before continuing

  • No labels