All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.scheduledexecutor.impl.TaskRunner Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.scheduledexecutor.impl;

import com.hazelcast.scheduledexecutor.StatefulTask;
import com.hazelcast.scheduledexecutor.impl.operations.ResultReadyNotifyOperation;
import com.hazelcast.spi.Operation;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import static com.hazelcast.scheduledexecutor.impl.TaskDefinition.Type.SINGLE_RUN;
import static com.hazelcast.util.ExceptionUtil.rethrow;
import static java.util.logging.Level.FINEST;
import static java.util.logging.Level.WARNING;

class TaskRunner
        implements Callable, Runnable {

    private final ScheduledExecutorContainer container;

    private final String taskName;

    private final Callable original;

    private final ScheduledTaskDescriptor descriptor;

    private final ScheduledTaskStatisticsImpl statistics;

    private boolean initted;

    private ScheduledTaskResult resolution;

    TaskRunner(ScheduledExecutorContainer container, ScheduledTaskDescriptor descriptor) {
        this.container = container;
        this.descriptor = descriptor;
        this.original = descriptor.getDefinition().getCommand();
        this.taskName = descriptor.getDefinition().getName();
        this.statistics = descriptor.getStatsSnapshot();
        statistics.onInit();
    }

    @Override
    public V call()
            throws Exception {
        beforeRun();
        try {
            V result = original.call();
            if (SINGLE_RUN.equals(descriptor.getDefinition().getType())) {
                resolution = new ScheduledTaskResult(result);
            }
            return result;
        } catch (Throwable t) {
            container.log(WARNING, taskName, "Exception occurred during run", t);
            resolution = new ScheduledTaskResult(t);
            throw rethrow(t);
        } finally {
            afterRun();
        }
    }

    @Override
    public void run() {
        try {
            call();
        } catch (Exception e) {
            throw rethrow(e);
        }
    }

    private void initOnce() {
        if (initted) {
            return;
        }

        Map snapshot = descriptor.getState();
        if (original instanceof StatefulTask && !snapshot.isEmpty()) {
            ((StatefulTask) original).load(snapshot);
        }

        initted = true;
    }

    private void beforeRun() {
        container.log(FINEST, taskName, "Entering running mode");

        try {
            initOnce();
            statistics.onBeforeRun();
        } catch (Exception ex) {
            container.log(WARNING, taskName, "Unexpected exception during beforeRun occurred", ex);
        }
    }

    private void afterRun() {
        try {
            statistics.onAfterRun();

            Map state = new HashMap();
            if (original instanceof StatefulTask) {
                ((StatefulTask) original).save(state);
            }

            container.publishTaskState(taskName, state, statistics.snapshot(), resolution);
        } catch (Exception ex) {
            container.log(WARNING, taskName, "Unexpected exception during afterRun occurred", ex);
        } finally {
            notifyResultReady();
        }

        container.log(FINEST, taskName, "Exiting running mode");
    }

    private void notifyResultReady() {
        Operation op = new ResultReadyNotifyOperation(container.offprintHandler(taskName));
        container.createInvocationBuilder(op).setCallTimeout(Long.MAX_VALUE).invoke();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy