Package com.sos.scheduler.engine.kernel.main

Source Code of com.sos.scheduler.engine.kernel.main.SchedulerThread$MyMainContext

/********************************************************* begin of preamble
**
** Copyright (C) 2003-2010 Software- und Organisations-Service GmbH.
** All rights reserved.
**
** This file may be used under the terms of either the
**
**   GNU General Public License version 2.0 (GPL)
**
**   as published by the Free Software Foundation
**   http://www.gnu.org/licenses/gpl-2.0.txt and appearing in the file
**   LICENSE.GPL included in the packaging of this file.
**
** or the
** 
**   Agreement for Purchase and Licensing
**
**   as offered by Software- und Organisations-Service GmbH
**   in the respective terms of supply that ship with this file.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
********************************************************** end of preamble*/
package com.sos.scheduler.engine.kernel.main;

import com.sos.scheduler.engine.kernel.Scheduler;
import com.sos.scheduler.engine.kernel.SchedulerException;
import com.sos.scheduler.engine.kernel.SchedulerCloseEvent;
import com.sos.scheduler.engine.kernel.event.Event;
import com.sos.scheduler.engine.kernel.event.EventSubscriber;
import com.sos.scheduler.engine.kernel.main.event.TerminatedEvent;
import com.sos.scheduler.engine.kernel.main.event.SchedulerReadyEvent;
import com.sos.scheduler.engine.kernel.util.Time;
import com.sos.scheduler.engine.kernel.util.sync.ThrowableMailbox;
import java.util.concurrent.atomic.AtomicReference;


/** Der Scheduler in einem eigenen Thread. */
public class SchedulerThread extends Thread implements SchedulerController {
    //TODO Thread auslagern, um nicht zwei Interfaces zu haben. Dann kann getSchedulerState() wieder getState() heißen.
    private final CppScheduler cppScheduler = new CppScheduler();
    private final CoOp coOp = new CoOp();
    private final AtomicReference<Integer> exitCodeAtom = new AtomicReference<Integer>();
    private final ThrowableMailbox<Throwable> throwableMailbox = new ThrowableMailbox<Throwable>();
    private EventSubscriber eventSubscriber = EventSubscriber.empty;
    private String[] arguments = {};
   

    public SchedulerThread() {
        setName("Scheduler");
    }


    @Override public final void loadModule() {
        cppScheduler.loadModule();
    }


    @Override public final void subscribeEvents(EventSubscriber s) {
        assert s != null;
        eventSubscriber = s;
    }


    @Override public final void runScheduler(String... arguments) {
        startScheduler(arguments);
        waitForTermination(terminationTimeout);
    }


    @Override public final void startScheduler(String... args) {
        this.arguments = args;
        start()// Thread läuft in run()
    }


    @Override public final Scheduler waitUntilSchedulerIsRunning() {
        try {
            Scheduler result = coOp.waitWhileSchedulerIsStarting();
            throwableMailbox.throwUncheckedIfSet();
            if (result == null) {
                throw new SchedulerException("Scheduler aborted before startup");
            }
            return result;
        }
        catch (InterruptedException x) { throw new RuntimeException(x); }
    }


    @Override public final void terminateAndWait() {
        terminateScheduler();
        waitForTermination(Time.eternal);
    }


    @Override public final void waitForTermination(Time timeout) {
        try {
            if (timeout == Time.eternaljoin();
            else timeout.unit.timedJoin(this, timeout.value);
            throwableMailbox.throwUncheckedIfSet();
        }
        catch (InterruptedException x) { throw new RuntimeException(x); }
    }


    @Override public final void terminateAfterException(Throwable x) {
        throwableMailbox.setIfFirst(x);
        terminateScheduler();
    }


    @Override public final void terminateScheduler() {
        coOp.terminate();
    }


//    @Override public final Scheduler getScheduler() {
//        Scheduler result = coOp.getScheduler();
//        if (result == null)  throw new NullPointerException(getClass() + " scheduler is not yet running");
//        return result;
//    }


    @Override public final int getExitCode() {
        assert !isAlive();
        return exitCodeAtom.get();
    }


    @Override public final SchedulerState getSchedulerState() {
        return coOp.getState();
    }


    @Override public final void run() {
        int exitCode = -1;
        Throwable t = null;
        try {
            exitCode = cppScheduler.run(arguments, "", new MyMainContext());
            synchronized (exitCodeAtom) { exitCodeAtom.set(exitCode); }
            if (exitCode != 0throw new SchedulerException("Scheduler terminated with exit code " + exitCode);
        }
        catch (Exception x) {
            throwableMailbox.setIfFirst(x);
            t = x;
        }
        catch (Error x) {
            throwableMailbox.setIfFirst(x);
            t = x;
            throw x;
        }
        finally {
            coOp.onTerminated();
            strictReportEvent(new TerminatedEvent(exitCode, t));
        }
    }


    private class MyMainContext implements MainContext {
        private MyEventSubscriber myEventSubscriber = new MyEventSubscriber();
        private Scheduler scheduler = null;

        @Override public final void setScheduler(Scheduler scheduler) {
            coOp.onSchedulerStarted(scheduler);
            this.scheduler = scheduler;
            strictReportEvent(new SchedulerReadyEvent(SchedulerThread.this));
        }

        @Override public final void onSchedulerActivated() {
            scheduler.getEventSubsystem().subscribe(myEventSubscriber);
        }
       
        class MyEventSubscriber implements EventSubscriber {
            @Override public final void onEvent(Event e) throws Exception {
                if (e instanceof SchedulerCloseEvent)
                    coOp.onSchedulerClosed();
                eventSubscriber.onEvent(e);
            }
        }
    }

   
    private void strictReportEvent(Event e) {
        try {
            eventSubscriber.onEvent(e);
        }
        catch (Throwable x) {
            //boolean debugOnly = e instanceof TerminatedEvent  &&  x instanceof UnexpectedTerminatedEventException;
            throwableMailbox.setIfFirst(x); //, debugOnly? Level.DEBUG : Level.ERROR);
        }
    }
}
TOP

Related Classes of com.sos.scheduler.engine.kernel.main.SchedulerThread$MyMainContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.