Dataflow concurrency offers an alternative concurrency model, which is inherently safe and robust.

h2. Introduction

Check out the small example written in Groovy using GPars, which sums results of calculations performed by three concurrently run tasks:
{code}
import static groovyx.gpars.dataflow.Dataflow.task

final def x = new DataflowVariable()
final def y = new DataflowVariable()
final def z = new DataflowVariable()

task {
    z << x.val + y.val
}

task {
    x << 10
}

task {
    y << 5
}

println "Result: ${z.val}"
{code}

Or the same algorithm rewritten using the _Dataflows_ class.

{code}

import static groovyx.gpars.dataflow.Dataflow.task

final def df = new Dataflows()

task {
    df.z = df.x + df.y
}

task {
    df.x = 10
}

task {
    df.y = 5
}

println "Result: ${df.z}"

{code}

We start three logical tasks, which can run in parallel and perform their particular activities. The tasks need to exchange data and they do so using *Dataflow Variables*.
Think of Dataflow Variables as one-shot channels safely and reliably transferring data from producers to their consumers.

The Dataflow Variables have a pretty straightforward semantics. When a task needs to read a value from _DataflowVariable_ (through the val property), it will block until the value has been set by another task or thread (using the '<<' operator). Each _DataflowVariable_ can be set *only once* in its lifetime. Notice that you don't have to bother with ordering and synchronizing the tasks or threads and their access to shared variables. The values are magically transferred among tasks at the right time without your intervention.
The data flow seamlessly among tasks / threads without your intervention or care.

*Implementation detail:* The three tasks in the example *do not necessarily need to be mapped to three physical threads*. Tasks represent so-called "green" or "logical" threads and can be mapped under the covers to any number of physical threads. The actual mapping depends on the scheduler, but the outcome of dataflow algorithms doesn't depend on the actual scheduling.

{note}
The _bind_ operation of dataflow variables silently accepts re-binding to a value, which is equal to an already bound value. Call _bindUnique_ to reject equal values on already-bound variables.
{note}

h2. Benefits

Here's what you gain by using Dataflow Concurrency (by "Jonas Bonér":http://www.jonasboner.com ):

* No race-conditions
* No live-locks
* Deterministic deadlocks
* Completely deterministic programs
* BEAUTIFUL code.

This doesn't sound bad, does it?

h1. Concepts

h2. Dataflow programming

h4. Quoting Wikipedia

Operations (in Dataflow programs) consist of "black boxes" with inputs and outputs, all of which are always explicitly defined. They run as soon as all of their inputs become valid, as opposed to when the program encounters them. Whereas a traditional program essentially consists of a series of statements saying "do this, now do this", a dataflow program is more like a series of workers on an assembly line, who will do their assigned task as soon as the materials arrive. This is why dataflow languages are inherently parallel; the operations have no hidden state to keep track of, and the operations are all "ready" at the same time.

h2. Principles

With Dataflow Concurrency you can safely share variables across tasks. These variables (in Groovy instances of the _DataflowVariable_ class) can only be assigned (using the '<<' operator) a value once in their lifetime. The values of the variables, on the other hand, can be read multiple times (in Groovy through the val property), even before the value has been assigned. In such cases the reading task is suspended until the value is set by another task.
So you can simply write your code for each task sequentially using Dataflow Variables and the underlying mechanics will make sure you get all the values you need in a thread-safe manner.

In brief, you generally perform three operations with Dataflow variables:
* Create a dataflow variable
* Wait for the variable to be bound (read it)
* Bind the variable (write to it)

And these are the three essential rules your programs have to follow:
* When the program encounters an unbound variable it waits for a value.
* It is not possible to change the value of a dataflow variable once it is bound.
* Dataflow variables makes it easy to create concurrent stream agents.

h2. Dataflow Queues and Broadcasts

Before you go to check the samples of using *Dataflow Variables*, *Tasks* and *Operators*, you should know a bit about streams and queues to have a full picture of Dataflow Concurrency.
Except for dataflow variables there are also the concepts of _DataflowQueues_ and _DataflowBroadcast_ that you can leverage in your code.
You may think of them as thread-safe buffers or queues for message transfer among concurrent tasks or threads. Check out a typical producer-consumer demo:

{code}import static groovyx.gpars.dataflow.Dataflow.task

def words = ['Groovy', 'fantastic', 'concurrency', 'fun', 'enjoy', 'safe', 'GPars', 'data', 'flow']
final def buffer = new DataflowQueue()

task {
    for (word in words) {
        buffer << word.toUpperCase()  //add to the buffer
    }
}

task {
    while(true) println buffer.val  //read from the buffer in a loop
}
{code}

Both _DataflowBroadcasts_ and _DataflowQueues_ , just like _DataflowVariables_ , implement the _DataflowChannel_ interface with common methods allowing users
to write to them and read values from them. The ability to treat both types identically through the _DataflowChannel_ interface comes in handy
once you start using them to wire _tasks_ , _operators_ or _selectors_ together.

{note}
The _DataflowChannel_ interface combines two interfaces, each serving its purpose:
* DataflowReadChannel holding all the methods necessary for reading values from a channel - getVal(), getValAsync(), whenBound(), etc.
* DataflowWriteChannel holding all the methods necessary for writing values into a channel - bind(), <<
You may prefer using these dedicated interfaces instead of the general _DataflowChannel_ interface, to better express the intended usage.
{note}

Please refer to the "API doc":http://gpars.codehaus.org/API+doc for more details on the channel interfaces.

h3. Point-to-point communication

The _DataflowQueue_ class can be viewed as a point-to-point (1 to 1, many to 1) communication channel. It allows one or more producers send messages to one reader.
If multiple readers read from the same _DataflowQueue_ , they will each consume different messages. Or to put it a different way, each message is consumed by exactly one reader.
You can easily imagine a simple load-balancing scheme built around a shared _DataflowQueue_ with readers being added dynamically when the consumer part of your algorithm needs to scale up.
This is also a useful default choice when connecting tasks or operators.

h3. Publish-subscribe communication

The _DataflowBroadcast_ class offers a publish-subscribe (1 to many, many to many) communication model. One or more producers write messages,
while all registered readers will receive all the messages. Each message is thus consumed by all readers with a valid subscription at the moment when the message is being written to the channel.
The readers subscribe by calling the _createReadChannel()_ method.

{code}
DataflowWriteChannel broadcastStream = new DataflowBroadcast()
DataflowReadChannel stream1 = broadcastStream.createReadChannel()
DataflowReadChannel stream2 = broadcastStream.createReadChannel()
broadcastStream << 'Message1'
broadcastStream << 'Message2'
broadcastStream << 'Message3'
assert stream1.val == stream2.val
assert stream1.val == stream2.val
assert stream1.val == stream2.val
{code}

Under the hood _DataflowBroadcast_ uses the _DataflowStream_ class to implement the message delivery.

h2. DataflowStream

The _DataflowStream_ class represents a deterministic dataflow channel. It is build around the concept of a functional queue and so provides a lock-free thread-safe implementation for message passing.
Essentially, you may think of _DataflowStream_ as a 1 to many communication channel, since when a reader consumes a messages,
other readers will still be able to read the message. Also, all messages arrive to all readers in the same order.
Since _DataflowStream_ is implemented as a functional queue, its API requires that users traverse the values in the stream themselves.
On the other hand _DataflowStream_ offers handy methods for value filtering or transformation together with interesting performance characteristics.

{note}
The _DataflowStream_ class, unlike the other communication elements, does not implement the _DataflowChannel_ interface, since the semantics of its use is different.
Use _DataflowStreamReadAdapter_ and _DataflowStreamWriteAdapter_ classes to wrap instances of the _DataflowChannel_ class
in _DataflowReadChannel_ or _DataflowWriteChannel_ implementations.
{note}

{code}
import groovyx.gpars.dataflow.stream.DataflowStream
import groovyx.gpars.group.DefaultPGroup
import groovyx.gpars.scheduler.ResizeablePool

/**
 * Demonstrates concurrent implementation of the Sieve of Eratosthenes using dataflow tasks
 *
 * In principle, the algorithm consists of a concurrently run chained filters,
 * each of which detects whether the current number can be divided by a single prime number.
 * (generate nums 1, 2, 3, 4, 5, ...) -> (filter by mod 2) -> (filter by mod 3) -> (filter by mod 5) -> (filter by mod 7) -> (filter by mod 11) -> (caution! Primes falling out here)
 * The chain is built (grows) on the fly, whenever a new prime is found
 */

/**
 * We need a resizeable thread pool, since tasks consume threads while waiting blocked for values at DataflowQueue.val
 */
group = new DefaultPGroup(new ResizeablePool(true))

final int requestedPrimeNumberCount = 100

/**
 * Generating candidate numbers
 */
final DataflowStream candidates = new DataflowStream()
group.task {
    candidates.generate(2, {it + 1}, {it < 1000})
}

/**
 * Chain a new filter for a particular prime number to the end of the Sieve
 * @param inChannel The current end channel to consume
 * @param prime The prime number to divide future prime candidates with
 * @return A new channel ending the whole chain
 */
def filter(DataflowStream inChannel, int prime) {
    inChannel.filter { number ->
        group.task {
            number % prime != 0
        }
    }
}

/**
 * Consume Sieve output and add additional filters for all found primes
 */
def currentOutput = candidates
requestedPrimeNumberCount.times {
    int prime = currentOutput.first
    println "Found: $prime"
    currentOutput = filter(currentOutput, prime)
}
{code}

For convenience and for the ability to use _DataflowStream_ with other dataflow constructs, like e.g. operators,
you can wrap it with _DataflowReadAdapter_ for read access or _DataflowWriteAdapter_ for write access.
The _DataflowStream_ class is designed for single-threaded producers and consumers. If multiple threads are supposed to read or write values
to the stream, their access to the stream must be serialized externally or the adapters should be used.

h3. DataflowStream Adapters

Since the _DataflowStream_ API as well as the semantics of its use are very different from the one defined by _Dataflow(Read/Write)Channel_ , adapters have to be used in order to allow _DataflowStreams_
to be used with other dataflow elements.
The _DataflowStreamReadAdapter_ class will wrap a _DataflowStream_ with necessary methods to read values, while the _DataflowStreamWriteAdapter_ class
will provide write methods around the wrapped _DataflowStream_ .

{note}
It is important to mention that the _DataflowStreamWriteAdapter_ is thread safe allowing multiple threads to add values to the wrapped _DataflowStream_ through the adapter.
On the other hand, _DataflowStreamReadAdapter_ is designed to be used by a single thread.

To minimize the overhead and stay in-line with the _DataflowStream_ semantics, the _DataflowStreamReadAdapter_ class is not thread-safe
and should only be used from within a single thread.
If multiple threads need to read from a DataflowStream, they should each create their own wrapping _DataflowStreamReadAdapter_ .
{note}

Thanks to the adapters _DataflowStream_ can be used for communication between operators or selectors, which expect _Dataflow(Read/Write)Channels_ .

{code}
import groovyx.gpars.dataflow.DataflowQueue
import groovyx.gpars.dataflow.stream.DataflowStream
import groovyx.gpars.dataflow.stream.DataflowStreamReadAdapter
import groovyx.gpars.dataflow.stream.DataflowStreamWriteAdapter
import static groovyx.gpars.dataflow.Dataflow.selector
import static groovyx.gpars.dataflow.Dataflow.operator

/**
 * Demonstrates the use of DataflowStreamAdapters to allow dataflow operators to use DataflowStreams
 */

final DataflowStream a = new DataflowStream()
final DataflowStream b = new DataflowStream()
def aw = new DataflowStreamWriteAdapter(a)
def bw = new DataflowStreamWriteAdapter(b)
def ar = new DataflowStreamReadAdapter(a)
def br = new DataflowStreamReadAdapter(b)

def result = new DataflowQueue()

def op1 = operator(ar, bw) {
    bindOutput it
}
def op2 = selector([br], [result]) {
    result << it
}

aw << 1
aw << 2
aw << 3
assert([1, 2, 3] == [result.val, result.val, result.val])
op1.stop()
op2.stop()
op1.join()
op2.join()

{code}

Also the ability to select a value from multiple _DataflowChannels_ can only be used through an adapter around a _DataflowStream_ :

{code}
import groovyx.gpars.dataflow.Select
import groovyx.gpars.dataflow.stream.DataflowStream
import groovyx.gpars.dataflow.stream.DataflowStreamReadAdapter
import groovyx.gpars.dataflow.stream.DataflowStreamWriteAdapter
import static groovyx.gpars.dataflow.Dataflow.select
import static groovyx.gpars.dataflow.Dataflow.task

/**
 * Demonstrates the use of DataflowStreamAdapters to allow dataflow select to select on DataflowStreams
 */

final DataflowStream a = new DataflowStream()
final DataflowStream b = new DataflowStream()
def aw = new DataflowStreamWriteAdapter(a)
def bw = new DataflowStreamWriteAdapter(b)
def ar = new DataflowStreamReadAdapter(a)
def br = new DataflowStreamReadAdapter(b)

final Select<?> select = select(ar, br)
task {
    aw << 1
    aw << 2
    aw << 3
}
assert 1 == select().value
assert 2 == select().value
assert 3 == select().value
task {
    bw << 4
    aw << 5
    bw << 6
}
def result = (1..3).collect{select()}.sort{it.value}
assert result*.value == [4, 5, 6]
assert result*.index == [1, 0, 1]
{code}

{note}
If you don't need any of the functional queue _DataflowStream-special_ functionality, like generation, filtering or mapping,
you may consider using the _DataflowBroadcast_ class instead, which offers the _publish-subscribe_ communication model through the _DataflowChannel_ interface.
{note}

h2. Bind handlers

{code}
def a = new DataflowVariable()
a >> {println "The variable has just been bound to $it"}
a.whenBound {println "Just to confirm that the variable has been really set to $it"}
...
{code}

Bind handlers can be registered on all dataflow channels (variables, queues or broadcasts) either using the >> operator and the _then()_ or the _whenBound()_ methods. They will be run once a value is bound to the variable.

Dataflow queues and broadcasts also support a _wheneverBound_ method to register a closure or a message handler to run each time a value is bound to them.

{code}
def queue = new DataflowQueue()
queue.wheneverBound {println "A value $it arrived to the queue"}
{code}

Obviously nothing prevents you from having more of such handlers for a single promise: They will all trigger in parallel once the promise has a concrete value:

{code}
Promise bookingPromise = task {
    final data = collectData()
    return broker.makeBooking(data)
}
…
bookingPromise.whenBound {booking -> printAgenda booking}
bookingPromise.whenBound {booking -> sendMeAnEmailTo booking}
bookingPromise.whenBound {booking -> updateTheCalendar booking}
{code}

{note}
Dataflow variables and broadcasts are one of several possible ways to implement _Parallel Speculations_ . For details, please check out _Parallel Speculations_ in the _Parallel Collections_ section
of the User Guide.
{note}

h2. Bind handlers grouping

When you need to wait for multiple DataflowVariables/Promises to be bound, you can benefit from calling the _whenAllBound()_ function,
which is available on the _Dataflow_ class as well as on _PGroup_ instances.

{code}
    final group = new NonDaemonPGroup()

    //Calling asynchronous services and receiving back promises for the reservations
    Promise flightReservation = flightBookingService('PRG <-> BRU')
    Promise hotelReservation = hotelBookingService('BRU:Feb 24 2009 - Feb 29 2009')
    Promise taxiReservation = taxiBookingService('BRU:Feb 24 2009 10:31')

    //when all reservations have been made we need to build an agenda for our trip
    Promise agenda = group.whenAllBound(flightReservation, hotelReservation, taxiReservation) {flight, hotel, taxi ->
        "Agenda: $flight | $hotel | $taxi"
    }

    //since this is a demo, we will only print the agenda and block till it is ready
    println agenda.val
{code}

If you cannot specify up-front the number of parameters the _whenAllBound()_ handler takes, use a closure with one argument of type _List_:
{code}
Promise module1 = task {
    compile(module1Sources)
}
Promise module2 = task {
    compile(module2Sources)
}
//We don't know the number of modules that will be jarred together, so use a List
final jarCompiledModules = {List modules -> ...}

whenAllBound([module1, module2], jarCompiledModules)
{code}

h2. Bind handlers chaining

All dataflow channels also support the _then()_ method to register a handler (a callback) that should be invoked when a value becomes available. Unlike _whenBound()_ the _then()_ method allows for chaining,
giving you the option to pass result values between functions asynchronously.
{note}
Notice that Groovy allows us to leave out some of the _dots_ in the _then()_ method chains.
{note}

{code}
final DataflowVariable variable = new DataflowVariable()
final DataflowVariable result = new DataflowVariable()

variable.then {it * 2} then {it + 1} then {result << it}
variable << 4
assert 9 == result.val
{code}

This could be nicely combined with _Asynchronous functions_

{code}
final DataflowVariable variable = new DataflowVariable()
final DataflowVariable result = new DataflowVariable()

final doubler = {it * 2}
final adder = {it + 1}

variable.then doubler then adder then {result << it}

Thread.start {variable << 4}
assert 9 == result.val
{code}

or _ActiveObjects_

{code}
@ActiveObject
class ActiveDemoCalculator {
    @ActiveMethod
    def doubler(int value) {
        value * 2
    }

    @ActiveMethod
    def adder(int value) {
        value + 1
    }
}

final DataflowVariable result = new DataflowVariable()
final calculator = new ActiveDemoCalculator();
calculator.doubler(4).then {calculator.adder it}.then {result << it}
assert 9 == result.val
{code}

{note:Title=Motivation for chaining Promises}
Chaining can save quite some code when calling other asynchronous services from within _whenBound()_ handlers. Asynchronous services,
such as _Asynchronous Functions_ or _Active Methods_, return _Promises_ for their results. To obtain the actual results
your handlers would either have to block to wait for the value to be bound, which would lock the current thread in an unproductive state,
{code}
variable.whenBound {value ->
    Promise promise = asyncFunction(value)
    println promise.get()
}
{code}
or, alternatively, it would register another (nested) _whenBound()_ handler, which would result in unnecessarily complex code.
{code}
variable.whenBound {value ->
    asyncFunction(value).whenBound {
        println it
    }
}
{code}
For illustration compare the two following code snippets, one using _whenBound()_ and one using _then()_ chaining. They ate both equivalent in terms of functionality and behavior.

{code}
final DataflowVariable variable = new DataflowVariable()

final doubler = {it * 2}
final inc = {it + 1}

//Using whenBound()
variable.whenBound {value ->
    task {
        doubler(value)
    }.whenBound {doubledValue ->
        task {
            inc(doubledValue)
        }.whenBound {incrementedValue ->
            println incrementedValue
        }
    }
}

//Using then() chaining
variable.then doubler then inc then this.&println

Thread.start {variable << 4}
{code}
Chaining Promises solves both of these issues elegantly:
{code}
variable >> asyncFunction >> {println it}
{code}
{note}

The _RightShift_ (_>>_) operator has been overloaded to call _then()_ and so can be chained the same way:

{code}
final DataflowVariable variable = new DataflowVariable()
final DataflowVariable result = new DataflowVariable()

final doubler = {it * 2}
final adder = {it + 1}

variable >> doubler >> adder >> {result << it}

Thread.start {variable << 4}

assert 9 == result.val
{code}

h3. Error handling for Promise chaining

Asynchronous operations may obviously throw exceptions. It is important to be able to handle them easily and with little effort.
GPars promises can implicitly propagate exceptions from asynchronous calculations across promise chains.

# Promises propagate result values as well as exceptions. The blocking _get()_ method re-throws the exception that was bound to the Promise and so the caller can handle it.
# For asynchronous notifications, the _whenBound()_ handler closure gets the exception passed in as an argument.
# The _then()_ method accepts two arguments - a *value handler* and an optional *error handler*. These will be invoked depending on whether the result is a regular value or an exception. If no errorHandler is specified, the exception is re-thrown to the Promise returned by _then()_ .
# Exactly the same behavior as for _then()_ holds true for the _whenAllBound()_ method, which listens on multiple Promises to get bound

{code}
    Promise<Integer> initial = new DataflowVariable<Integer>()
    Promise<String> result = initial.then {it * 2} then {100 / it}                  //Will throw exception for 0
            .then {println "Logging the value $it as it passes by"; return it}      //Since no error handler is defined, exceptions will be ignored
                                                                                    //and silently re-thrown to the next handler in the chain
            .then({"The result for $num is $it"}, {"Error detected for $num: $it"}) //Here the exception is caught
    initial << 0
    println result.get()
{code}

ErrorHandler is a closure that accepts instances of _Throwable_ as its only (optional) argument and returns a value that should be bound to
the result of the _then()_ method call (the returned Promise). If an exception is thrown from within an error handler, it is bound
as an error to the resulting Promise.

{code}
promise.then({it+1})                                                         //Implicitly re-throws potential exceptions bound to promise
promise.then({it+1}, {e -> throw e})                                         //Explicitly re-throws potential exceptions bound to promise
promise.then({it+1}, {e -> throw new RuntimeException('Error occurred', e})  //Explicitly re-throws a new exception wrapping a potential exception bound to promise
{code}

Just like with regular exception handling in Java with try-catch statements, this behavior of GPars promises gives asynchronous invocations the freedom to handle exceptions
at the place where it is most convenient. You may freely ignore exceptions in your code and assume things just work, yet exceptions
will not get accidentally swallowed.

 {code}
task {
    'gpars.codehaus.org'.toURL().text  //should throw MalformedURLException
}
.then {page -> page.toUpperCase()}
.then {page -> page.contains('GROOVY')}
.then({mentionsGroovy -> println "Groovy found: $mentionsGroovy"}, {error -> println "Error: $error"}).join()
 {code}

h4. Handling concrete exception type

You may be also more specific about the handled exception type:

{code}
url.then(download)
    .then(calculateHash, {MalformedURLException e -> return 0})
    .then(formatResult)
    .then(printResult, printError)
    .then(sendNotificationEmail);
{code}`

h4. Customer-site exception handling

You may also leave the exception completely un-handled and let the clients (consumers) handle it:

{code}`
Promise<Object> result = url.then(download).then(calculateHash).then(formatResult).then(printResult);
try {
    result.get()
} catch (Exception e) {
    //handle exceptions here
}
{code}`


h3. Putting it together

By combining _whenAllBound()_ and _then_ (or >>) you can easily create large asynchronous scenarios in a convenient way:

{code}
withPool {
    Closure download = {String url ->
        sleep 3000  //Simulate a web read
        'web content'
    }.asyncFun()

    Closure loadFile = {String fileName ->
        'file content'  //simulate a local file read
    }.asyncFun()

    Closure hash = {s -> s.hashCode()}

    Closure compare = {int first, int second ->
        first == second
    }

    Closure errorHandler = {println "Error detected: $it"}

    def all = whenAllBound([
                  download('http://www.gpars.org') >> hash,
                  loadFile('/coolStuff/gpars/website/index.html') >> hash
              ], compare).then({println it}, errorHandler)
    all.join()  //optionally block until the calculation is all done
{code}

{note}
Notice that only the initial action (function) needs to be asynchronous. The functions further down the pipe will be invoked
asynchronously by the promise even if the are synchronous.
{note}

h3. Implementing the fork/join pattern with Promises

Promises are very flexible and can be used as an implementation vehicle for a lot of different scenarios:.
Here's one additional handy capability od Promises. The _thenForkAndJoin() method triggers multiple activities once the current promise is bound
and returns a promise that get bound only after all the activities finish. Let's see how it fits into the picture:

* _then()_ - allows for chaining of activities, so that one is performed after another
* _whenAllBound()_ - allows for joining multiple activities, so that a new activity is started only after they all finish
* _task()_ - allows to create (fork) multiple asynchronous activities
* _thenForkAndJoin()_ - a short-hand for forking several activities and joining on them

So with _thenForkAndJoin()_ you simply create multiple activities that should be triggered by a shared (triggering) promise.
{code}
promise.thenForkAndJoin(task1, task2, task3).then{...}
{code}

Once all the activities return a result, they get collected into a list and bound into the promise returned by _thenForkAndJoin()_ .

{code}
task {
    2
}.thenForkAndJoin({ it ** 2 }, { it**3 }, { it**4 }, { it**5 }).then({ println it}).join()
{code}

h2. Lazy dataflow tasks and variables

Sometimes you may like to combine the qualities of dataflow variables with their lazy initialization.
{code}
Closure<String> download = {url ->
    println "Downloading"
    url.toURL().text
}

def pageContent = new LazyDataflowVariable(download.curry("http://gpars.codehaus.org"))
{code}

Instances of _LazyDataflowVariable_ have an initializer specified at construction time, which only gets triggered
when someone asks for its value, either through the blocking _get()_ method or using any of the non-blocking callback
methods, such as _then()_ .
Since _LazyDataflowVariables_ preserve all the goodies of ordinary _DataflowVariables_ , you can again chain them easily
 with other _lazy_ or _ordinary_ dataflow variables.

h4. Example

This deserves a more practical example. Taking inspiration from http://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/
the following piece of code demonstrates use of _LazyDataflowVariables_ to lazily and asynchronously load mutually dependent components into memory.
The components (modules) will be loaded in the order of their dependencies and concurrently, if possible.
Each module will only be loaded once, irrespective of the number of modules that depend on it.
Thanks to laziness only the modules that are transitively needed will be loaded.
Our example uses a simple "diamond" dependency scheme:

* D depends on B and C
* C depends on A
* B depends on A

When loading D, A will get loaded first. B and C will be loaded concurrently once A has been loaded. D will start loading
once both B and C have been loaded.

{code}
def moduleA = new LazyDataflowVariable({->
    println "Loading moduleA into memory"
    sleep 3000
    println "Loaded moduleA into memory"
    return "moduleA"
})

def moduleB = new LazyDataflowVariable({->
    moduleA.then {
        println "->Loading moduleB into memory, since moduleA is ready"
        sleep 3000
        println "  Loaded moduleB into memory"
        return "moduleB"
    }
})

def moduleC = new LazyDataflowVariable({->
    moduleA.then {
        println "->Loading moduleC into memory, since moduleA is ready"
        sleep 3000
        println "  Loaded moduleC into memory"
        return "moduleC"
    }
})

def moduleD = new LazyDataflowVariable({->
    whenAllBound(moduleB, moduleC) { b, c ->
        println "-->Loading moduleD into memory, since moduleB and moduleC are ready"
        sleep 3000
        println "   Loaded moduleD into memory"
        return "moduleD"
    }
})

println "Nothing loaded so far"
println "==================================================================="
println "Load module: " + moduleD.get()
println "==================================================================="
println "All requested modules loaded"
{code}

h3. Making tasks lazy

The _lazyTask()_ method is available alongside the _task()_ method to give the users a task-oriented abstraction for delayed activities.
A *Lazy Task* returns an instance of _LazyDataflowVariable_ (a _Promise_ ) with the initializer set to the provided closure.
As soon as someone asks for the value, the task will start asynchronously and eventually deliver a value into the _LazyDataflowVariable_ .

{code}
import groovyx.gpars.dataflow.Dataflow

def pageContent = Dataflow.lazyTask {
        println "Downloading"
        "http://gpars.codehaus.org".toURL().text
    }

println "No-one has asked for the value just yet. Bound = ${pageContent.bound}"
sleep 1000
println "Now going to ask for a value"
println pageContent.get().size()
println "Repetitive requests will receive the already calculated value. No additional downloading."
println pageContent.get().size()
{code}

h2. Dataflow Expressions

Look at the magic below:

{code}
def initialDistance = new DataflowVariable()
def acceleration = new DataflowVariable()
def time = new DataflowVariable()

task {
    initialDistance << 100
    acceleration << 2
    time << 10
}

def result = initialDistance + acceleration*0.5*time**2
println 'Total distance ' + result.val
{code}

We use DataflowVariables that represent several parameters to a mathematical equation calculating total distance of an accelerating object.
In the equation itself, however, we use the DataflowVariables directly. We do not refer to the values they represent
and yet we are able to do the math correctly. This shows that DataflowVariables can be very flexible.

For example, you can call methods on them and these methods will get dispatched to the bound values:

{code}
def name = new DataflowVariable()
task {
    name << '  adam   '
}
println name.toUpperCase().trim().val
{code}

You can pass other DataflowVariables as arguments to such methods and the real values will be passed automatically instead:

{code}
def title = new DataflowVariable()
def searchPhrase = new DataflowVariable()
task {
    title << ' Groovy in Action 2nd edition   '
}

task {
    searchPhrase << '2nd'
}

println title.trim().contains(searchPhrase).val
{code}

And you can also query properties of the bound value using directly the DataflowVariable:

{code}
def book = new DataflowVariable()
def searchPhrase = new DataflowVariable()
task {
    book << [
             title:'Groovy in Action 2nd edition   ',
             author:'Dierk Koenig',
             publisher:'Manning']
}

task {
    searchPhrase << '2nd'
}

book.title.trim().contains(searchPhrase).whenBound {println it}  //Asynchronous waiting

println book.title.trim().contains(searchPhrase).val  //Synchronous waiting
{code}

Please note that the result is still a DataflowVariable (DataflowExpression to be precise), which you can get the real value from both synchronously and asynchronously.

h2. Bind error notification

_DataflowVariables_ offer the ability to send notifications to the registered listeners whenever a bind operation fails. The _getBindErrorManager()_ method allows for listener to be added and removed.
The listeners get notified in case of a failed attempt to bind a value (through bind(), bindSafely(), bindUnique() or leftShift()) or an error (through bindError()).

{code}
        final DataflowVariable variable = new DataflowVariable()

        variable.getBindErrorManager().addBindErrorListener(new BindErrorListener() {
            @Override
            void onBindError(final Object oldValue, final Object failedValue, final boolean uniqueBind) {
                println "Bind failed!"
            }

            @Override
            void onBindError(final Object oldValue, final Throwable failedError) {
                println "Binding an error failed!"
            }

            @Override
            public void onBindError(final Throwable oldError, final Object failedValue, final boolean uniqueBind) {
                println "Bind failed!"
            }

            @Override
            public void onBindError(final Throwable oldError, final Throwable failedError) {
                println "Binding an error failed!"
            }

        })
{code}

This allows you to customize reactions to attempts to binding of already bound dataflow variables. For example, using _bindSafely()_ you do not get bind exceptions fired to the caller,
but instead a registered _BindErrorListener_ gets notified.

h2. Further reading

"Scala Dataflow library":http://github.com/jboner/scala-dataflow/tree/f9a38992f5abed4df0b12f6a5293f703aa04dc33/src by Jonas Bonér

"JVM concurrency presentation slides":http://jonasboner.com/talks/state_youre_doing_it_wrong/html/all.html by Jonas Bonér

"Dataflow Concurrency library for Ruby":http://github.com/larrytheliquid/dataflow/tree/master
