easyWorker icon indicating copy to clipboard operation
easyWorker copied to clipboard

How can reuse a thred

Open varadig opened this issue 9 years ago • 4 comments

I have to create worker and use it in a SQLConnection. So the multiple worker solution is not good for me. How can I use again a thread, when it's result event is dispatched? If I trace the state of the thread in the event handler method, the result is: started

varadig avatar Feb 03 '16 06:02 varadig

... in a SQLConnection ? can you please detailed for use case, thanks.

doublefx avatar Feb 03 '16 09:02 doublefx

DatabaseControllerWorker.as

/**
 * Created by varadig on 1/30/16.
 */
package controller.database {
import com.doublefx.as3.thread.Thread;
import com.doublefx.as3.thread.api.IThread;
import com.doublefx.as3.thread.event.ThreadFaultEvent;
import com.doublefx.as3.thread.event.ThreadResultEvent;

import controller.database.base.BaseDatabaseController;
import controller.database.interfaces.IDatabaseController;
import controller.database.workers.DatabaseWorker;

import flash.filesystem.File;

import model.database.DatabaseFile;
import model.geolocation.route.CyclingRoute;
import model.geolocation.route.WalkingRoute;
import model.geolocation.route.base.BaseRoute;
import model.geolocation.route.interfaces.IRoute;

import starling.core.Starling;

public class DatabaseControllerWorker extends BaseDatabaseController implements IDatabaseController {

    private var thread:IThread;

    public function DatabaseControllerWorker() {
        super();
        this.initThreads();
    }

    private function initThreads():void {
        Thread.DEFAULT_LOADER_INFO = Starling.current.nativeStage.loaderInfo;
        this.thread = new Thread(DatabaseWorker, "databaseWorker", true, DatabaseWorker.DEPENDENCIES);
        this.thread.addEventListener(ThreadResultEvent.RESULT, thread_resultHandler);
        this.thread.addEventListener(ThreadFaultEvent.FAULT, thread_faultHandler);
    }

    private function thread_resultHandler(event:ThreadResultEvent):void {
        log('thread result: ' + event.result);
    }

    private function thread_faultHandler(event:ThreadFaultEvent):void {
        log('thread fault');
    }

    public function open(file:DatabaseFile):void {
        this.thread.start('open', DatabaseFile(file));
    }

    public function read():void {
        thread.start('read');
    }

    public function updateRoute(route:IRoute):void {
        if (!this.isOppened)
            return;

        var walkingDistance = (route is WalkingRoute) ? int(BaseRoute(route).distanceInMeter) : 0;
        var cyclingDistance = (route is CyclingRoute) ? int(BaseRoute(route).distanceInMeter) : 0;
        this.commitData(walkingDistance, cyclingDistance);

    }

    public function updateRoutes(routes:Vector.<IRoute>):void {
        if (!this.isOppened)
            return;

        var walkingDistance = 0;
        var cyclingDistance = 0;

        for each(var route:IRoute in routes) {
            if (route is WalkingRoute)
                walkingDistance += int(BaseRoute(route).distanceInMeter);
            if (route is CyclingRoute)
                cyclingDistance += int(BaseRoute(route).distanceInMeter);

        }
        this.commitData(walkingDistance, cyclingDistance);
    }

    public function commitData(walking:int, cycling:int):void {
        this.thread.start('update', walking, cycling, this.currentDay);
    }

    public function close():void {
        this.thread.start('close');
    }

    public function save(file:File):void {
    }
}
}

DatabaseWorker.as

/**
 * Created by varadig on 1/29/16.
 */
package controller.database.workers {
import com.doublefx.as3.thread.api.CrossThreadDispatcher;
import com.doublefx.as3.thread.api.Runnable;
import com.doublefx.as3.thread.event.ThreadActionRequestEvent;
import com.doublefx.as3.thread.event.ThreadActionResponseEvent;

import core.base.CoreBaseClass;

import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.SQLEvent;

import model.database.DatabaseFile;
import model.database.SQL;

public class DatabaseWorker extends CoreBaseClass implements Runnable {

    /**
     * Mandatory declaration if you want your Worker be able to communicate.
     * This CrossThreadDispatcher is injected at runtime.
     */
    private var _dispatcher:CrossThreadDispatcher;

    private var connection:SQLConnection;
    public static const READ:String = 'database.worker.read';

    public static const UPDATE:String = 'database.worker.update';
    public static const DEPENDENCIES:Vector.<String> = Vector.<String>([
        "controller.database.*",
        'core.notification::CoreNotification',
        'core.base::CoreBaseClassFactory',
        'model.database.*',
        'model.settings.*',
        'model.geolocation.*',
        'flash.data.SQLResult',
        'com.probertson.*']);

    public function DatabaseWorker():void {
        super();
    }

    public function run(args:Array):void {

        var message:String = args[0];
        switch (message) {
            case 'open':
                this.open(args[1]);
                break;
            case 'read':
                this.read();
                break;
        }
        return;
    }

    private function open(file:DatabaseFile):void {
        this.connection = new SQLConnection();
        this.connection.open(file);
        dispatcher.dispatchResult('opened');
    }

    private function read():void {
        var readStatement:SQLStatement = new SQLStatement();
        readStatement.sqlConnection = this.connection;
        readStatement.text = SQL.getInstance().SELECT_ALL_DISTANCE;
        readStatement.addEventListener(SQLEvent.RESULT, function (event:SQLEvent) {
            dispatcher.dispatchResult('read');
        });
        readStatement.execute();

    }

    public function get dispatcher():CrossThreadDispatcher {
        return _dispatcher;
    }

    public function set dispatcher(value:CrossThreadDispatcher):void {
        _dispatcher = value;

        if (_dispatcher) {
            _dispatcher.addEventListener(ThreadActionRequestEvent.PAUSE_REQUESTED, dispatcher_pauseRequestedHandler);
            _dispatcher.addEventListener(ThreadActionRequestEvent.RESUME_REQUESTED, dispatcher_resumeRequestedHandler);
            _dispatcher.addEventListener(ThreadActionRequestEvent.TERMINATE_REQUESTED, dispatcher_terminateRequestedHandler);
        }
    }

    // Won't be call if IThread.pause() has been called before start();
    private function dispatcher_pauseRequestedHandler(event:ThreadActionRequestEvent):void {
        trace("Pause requested, I do the eventual job to before Paused...");
        _dispatcher.dispatchEvent(new ThreadActionResponseEvent(ThreadActionResponseEvent.PAUSED));
    }

    // Won't be call if IThread.resume() has been called before start();
    private function dispatcher_resumeRequestedHandler(event:ThreadActionRequestEvent):void {
        trace("Resume requested, I do the eventual job to before Resumed...");
        _dispatcher.dispatchEvent(new ThreadActionResponseEvent(ThreadActionResponseEvent.RESUMED));
    }

    // Won't be call if IThread.terminate() has been called before start();
    private function dispatcher_terminateRequestedHandler(event:ThreadActionRequestEvent):void {
        trace("Terminate requested, I do the eventual job to before Terminated...");
        _dispatcher.dispatchEvent(new ThreadActionResponseEvent(ThreadActionResponseEvent.TERMINATED));
    }
}
}

If call method open in the DatabaseControllerWorker class, the thread is dispatch the result: open But after if I wanted to read the database (or call/start anything in the thread) nothing happend. No result no fault.

varadig avatar Feb 03 '16 10:02 varadig

Yeah, workers have been designed to have 1 entry point and once it has executed its supposed "long CPU consuming task", it terminates itself, I did not change the original design but I guess I could add a wait() method accessible from the Runnable as it can be already achieve with Mutex and Condition.

doublefx avatar Feb 03 '16 12:02 doublefx

Thanks doublefx, It would be very nice

varadig avatar Feb 03 '16 12:02 varadig