Migrate from GitHub to SourceForge with this tool. Check out all of SourceForge's recent improvements.
Close

Controllers

Why controllers

The controller is an object which can control a process. For example you can control a download process of a file or a solving process of a FEM-simulation.
Firstly controllers were developed to support decupled layered architecture to support the execution of long running processes. The API of the controller provides methods for start, cancel and monitor of implemented process. In the snippet below you can see how a controller can be started and its progress monitored.

Controller_1x3<Integer, String> c = ...
c.getOnProgressChanged().add(new ActionListener_1x0<ActionEventAfter_1x0<Integer>>() {
    @Override
    public void actionPerformedImpl(ActionEventAfter_1x0<Integer> event) {
        //extracted progress value from the received progress-event
        Integer progress = event.getData();
        System.out.println(progress);
    }
} );

c.start();//starts the controller
c.waitForFinish();//waits until finish

Implement custom controller

You can implement custom controller by extending of AbstractController. See below for an example with comments:

/**
 * fires events of type float and returns the String as the result
 * @author Andreas Hollmann
 *
 */
public class MyController extends AbstractController_1x3<Float, String> {

    @Override
    public Boolean start() {
        /*
         * implement here your logic, use a Thread to make your logic asynchronous, 
         * else you block on the start method.
         */

        //use setProgress(...) to fire progress events
        Float progress = 1F;
        this.setProgress(progress);

        //use setResult(..) to set the result
        String result = "my result";
        this.setResult(result );

        //use setState(..) to change state of your controller
        State_1x3 state = State_1x3.Finished;
        this.setState(state);

        return true;
    }

    @Override
    public String waitForFinish() {
        // implement here your code to wait until your logic in start() method has finished
        return this.getResult();
    }

    @Override
    public Boolean cancel() {
        //implement here your logic to cancel your controller
        //use setState(..) to change state of your controller
        State_1x3 state = State_1x3.Canceled;
        this.setState(state);

        return true;
    }

}

Protect controller in a multi-threaded code

A controller is usually used from different threads. For example if a controller represents a solving process for a FEM-simulation in a web application, then the controller can be started, monitored and canceled in different HTTP-requests, whereat every HTTP-request runs in its own thread and can access the controller concurrently. To protect the controller in a multi-thread application an synchronized controller decorator can be used. In the code snippet below you can see how a controller can be protected:

Controller_1x3<Integer, String> c = ...
SynchronizedController_1x3<Integer, String> synchController = 
                                    Controllers_1x3.synchronizedController(c);

//call methods in multi thread safe manner
synchController.start();
synchController.cancel();

Process fails and retries many times

Some time your process can fail and you want to retry to execute the process after a period of time. Such method is well known in distributed systems where a component can be restarted and a process execution fails on this component, but after a while the component is online and is ready to execute the process. Examples are file download, executing of a simulation on a grid node, calling a web service. In system engineering such retry strategy is also called as many retries method.
Controllers support this method and you can use it as shown in code snippet below:

int maxRetryNumber = 5;
long delayBeforeNextTry = 1000;//wait 1 sec
Factory_1x3<Controller_1x3<Integer, String>> factory = 
    new Factory_1x3<Controller_1x3<Integer, String>>() {
        @Override
        public Controller_1x3<Integer, String> create() {
            //create a new controller for your process
            Controller_1x3<Integer, String> c = ...;
            return c;
        }
    };
Controller_1x3<Integer, String> retryController =

Controllers_1x3.retryController(maxRetryNumber, delayBeforeNextTry, factory );

/*
 * if this controllers fails it waits for 1 sec and restarts again. 
 * This will be repeated in worst case 5 times, 
 * after that the controller fails with ManyRetriesException
 */
retryController.start();
retryController.waitForFinish();

Limit the process execution time

What to do if your process hangs on and doesn’t response, for example a call to a grid-node doesn’t respond for long time. For such situations the controller execution time can be limited. In Code snippet below you can see how the controller execution time can be limited:

//create a new controller for your process
Controller_1x3<Integer, String> c = ...
long maxExecutionTime = 1000*60*5;//5min
TimeLimiterController_1x3<Integer, String> tlc = 
        Controllers_1x3.timeLimiterController(c, maxExecutionTime );
tlc.start();
//waits max for 5 min then fails
tlc.waitForFinish();

It is a good idea to combine the time limited controller with many retries controller, take a look at the code snippet below:

int maxRetryNumber = 3;
long delayBeforeNextTry = 1000;//wait 1 sec
Factory_1x3<Controller_1x3<Integer, String>> factory = 
    new Factory_1x3<Controller_1x3<Integer, String>>() {
        @Override
        public Controller_1x3<Integer, String> create() {
            //create a new controller for your process
            Controller_1x3<Integer, String> c = ...

            //limit the controller execution time to 5 min
            long maxExecutionTime = 1000*60*5;//5min
            TimeLimiterController_1x3<Integer, String> tlc =
                        Controllers_1x3.timeLimiterController(c, maxExecutionTime );

            return c;
        }
    };
Controller_1x3<Integer, String> retryController = 
Controllers_1x3.retryController(maxRetryNumber, delayBeforeNextTry, factory );

/*
 * if this controllers fails, it waits for 1 sec and restarts again. 
 * This will be repeated in worst case 5 times, 
 * after that the controller fails with ManyRetriesException
 */
retryController.start();
retryController.waitForFinish();

For more examples see in example section.