Heiko Braun Software Engineer

Flow Control for GWT

tl;dr

Within Ajax applications you need to manage a lot of interaction and RPC related asynchronous events. The control flow structures become hard to understand and yield unpredicatable results.

We created a re-usable GWT module that provides some higher order control structures that you can use to tame the asynchronous callback beast. It’s been inspired by Async.js, but aligns with the core GWT API’s more naturally.

Control Flow API

package org.jboss.gwt.flow.client;

import com.google.gwt.core.client.Scheduler;

/**
 * Flow control functions for GWT.
 * Integrates with the default GWT scheduling mechanism.
 *
 * @author Heiko Braun
 * @date 3/8/13
 */
public class Async<C>
{

    /**
     * Run an array of functions in series, each one running once the previous function has completed.
     * If any functions in the series pass an error to its callback,
     * no more functions are run and outcome for the series is immediately called with the value of the error.
     *
     * @param outcome
     * @param functions
     */
    public void series(final Outcome outcome, final Function... functions)
    {
       [...]
    }

    /**
     * Runs an array of functions in series, working on a shared context.
     * However, if any of the functions pass an error to the callback,
     * the next function is not executed and the outcome is immediately called with the error.
     *
     * @param context
     * @param outcome
     * @param functions
     */
    public void waterfall(final C context, final Outcome<C> outcome, final Function<C>... functions)
    {
        [...]
    }

    /**
     * Run an array of functions in parallel, without waiting until the previous function has completed.
     * If any of the functions pass an error to its callback, the outcome is immediately called with the value of the
     * error.
     *
     * @param outcome
     * @param functions
     */
    public void parallel(final Outcome outcome, final Function... functions)
    {
        [...]
    }

    /**
     * Repeatedly call function, while condition is met. Calls the callback when stopped, or an error occurs.
     *
     * @param condition
     * @param outcome
     * @param function
     */
    public void whilst(Precondition condition, final Outcome outcome, final Function function)
    {
        [...]
    }

}

/**
 * An execution delegate able to control the outcome.
 *
 * @author Heiko Braun
 * @date 3/8/13
 */
public interface Function<C> {
    void execute(Control<C> control);
}

/**
 * Execution control handle passed into functions
 *
 * @author Heiko Braun
 * @date 3/8/13
 */
public interface Control<C> {

    void proceed();
    void abort();
    C getContext();
}

/**
 * The final outcome of the controlled flow.
 *
 * @author Heiko Braun
 * @date 3/8/13
 */
public interface Outcome<C> {

    void onFailure(C context);

    void onSuccess(C context);

}

Example: Waterfall Execution

Runs an array of functions in series, working on a shared context. However, if any of the functions pass an error to the callback, the next function is not executed and the outcome is immediately called with the error.

private void runWaterfall()
    {

        final Function foo = new SpecificFunction("first");    (1)
        final Function bar = new SpecificFunction("second");   (2)

        final Outcome<StringBuffer> outcome = new Outcome<StringBuffer>() (3)
        {
            @Override
            public void onFailure(StringBuffer sb)
            {
                Window.alert("Outcome is failure");
            }

            @Override
            public void onSuccess(StringBuffer sb)
            {
                Window.alert("Outcome is success: " + sb);

            }
        };

        new Async<StringBuffer>().waterfall(new StringBuffer(), outcome, foo, bar); (4)

    }

Step by Step

  1. Create some executable command (aka Function)
  2. Create a command that should be run once the first one finishes
  3. The final callback to be invoked when the waterfall execution finishes. The StringBuffer acts as a shared context object
  4. Invoke the waterfall execution, providing a shared context (StringBuffer) and a number of function to be executed

Sources & Maven Coordinates

The sources for the control API can be found at github:

https://github.com/hal/core/tree/master/flow/core

The maven artefacts resides with the JBoss repositories:

<dependency>
  <groupId>org.jboss.as</groupId>
  <artifactId>jboss-as-console-flow</artifactId>
  <version>1.6.3.Final</version>
</dependency>

GWT Module Setup

<module rename-to="your_module">
    [...]
    <inherits name="org.jboss.gwt.flow.Flow"/>
</module>

The Great Java Application Server Debate

Here’s what zeroturnaround say’s about the Wildfly management console:

Enterprise quality administration, reload/restart information, need to configure users before use, extensive feature configuration, modern.

Read the full article here.

Cross origin server management

Retrieving the AS7 management console through an app store? Great idea, but what does it imply? Harald has written up a pretty good blog post, where he describes the challenges with this approach:

http://haraldpehl.blogspot.de/2013/03/independent-jboss-admin-console.html

Friday Picks – 01/03/2013

It’s been while, but here is this weeks reading list:

Stop Designing for “Users”

An advice on design for Activities opposed to individuals. A look at the limitations of personas.

Performance tips for working with Node.js

Performance takeaways from LinkedIn Engineering

Datomic for Five Year Olds

Do you grasp Datomic? I didn’t until I read this explanation.

Dart with Google Web Toolkit

Several ways how to use Dart with Google Web Toolkit.

Google Dart to “ultimately … replace JavaScript”

Some intersting obeservation on Google Dart. Raises the question if other vendors are going to adopt Dart .

JBoss AS7 Console 1.5.0 released

I am very happy to announce the 1.5.0 release of the AS7 web management interface. This release is intended to be used with AS 7.2 and EAP 6.1.

Among plenty of bug fixes here’s a quick overview of the most notable enhancements:

Domain Topology Overview
All hosts, servers and groups at a glance. You can start, stop single instances or complete groups from a single view.

topology

Deployment Browser
This has been one the highly requested features: Drill down into deployments and subsystem references.

deployment_browser

Unmanaged Deployments
Support for unmanaged deployments.

unmanaged_deployment

Improved Expression Support
The web interface now supports expressions on all attributes and provides a tool to resolve expression values from any view.

expression_resolver

Analytics Integration
To get a better idea, which tools matter most we’ve integrated analytics support.

tool_usage

Special thanks to Harald Pehl for his recent contributions. He did provide the topology overview and the deployments browser.

The full release notes can be found here: http://jbossas.github.com/console/releases.html

Merry Christmas,
Heiko