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

com.hazelcast.durableexecutor.impl.DurableExecutorContainer Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Copyright (c) 2008-2020, 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.durableexecutor.impl;

import com.hazelcast.durableexecutor.impl.operations.PutResultOperation;
import com.hazelcast.logging.ILogger;
import com.hazelcast.spi.impl.NodeEngineImpl;
import com.hazelcast.spi.impl.executionservice.ExecutionService;
import com.hazelcast.spi.impl.operationservice.Operation;
import com.hazelcast.spi.impl.operationservice.OperationService;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

import static com.hazelcast.durableexecutor.impl.DistributedDurableExecutorService.SERVICE_NAME;

public class DurableExecutorContainer {

    private final String name;

    private final NodeEngineImpl nodeEngine;

    private final ExecutionService executionService;

    private final ILogger logger;

    private final int partitionId;

    private final int durability;

    private final TaskRingBuffer ringBuffer;

    public DurableExecutorContainer(NodeEngineImpl nodeEngine, String name, int partitionId,
                                    int durability, TaskRingBuffer ringBuffer) {
        this.name = name;
        this.nodeEngine = nodeEngine;
        this.executionService = nodeEngine.getExecutionService();
        this.partitionId = partitionId;
        this.logger = nodeEngine.getLogger(DurableExecutorContainer.class);
        this.durability = durability;
        this.ringBuffer = ringBuffer;
    }

    public int execute(Callable callable) {
        int sequence = ringBuffer.add(callable);
        TaskProcessor processor = new TaskProcessor(sequence, callable);
        executionService.executeDurable(name, processor);
        return sequence;
    }

    public void putBackup(int sequence, Callable callable) {
        ringBuffer.putBackup(sequence, callable);
    }

    public Object retrieveResult(int sequence) {
        return ringBuffer.retrieve(sequence);
    }

    public void disposeResult(int sequence) {
        ringBuffer.dispose(sequence);
    }

    public Object retrieveAndDisposeResult(int sequence) {
        return ringBuffer.retrieveAndDispose(sequence);
    }

    public void putResult(int sequence, Object result) {
        ringBuffer.replaceTaskWithResult(sequence, result);
    }

    public boolean shouldWait(int sequence) {
        return ringBuffer.isTask(sequence);
    }

    void executeAll() {
        TaskRingBuffer.DurableIterator iterator = ringBuffer.iterator();
        while (iterator.hasNext()) {
            Object item = iterator.next();
            boolean isCallable = iterator.isTask();
            if (!isCallable) {
                continue;
            }
            Callable callable = (Callable) item;
            int sequence = iterator.getSequence();
            TaskProcessor processor = new TaskProcessor(sequence, callable);
            executionService.executeDurable(name, processor);
        }
    }

    public TaskRingBuffer getRingBuffer() {
        return ringBuffer;
    }

    public int getDurability() {
        return durability;
    }

    public String getName() {
        return name;
    }

    public final class TaskProcessor extends FutureTask implements Runnable {
        private final String callableString;
        private final int sequence;

        private TaskProcessor(int sequence, Callable callable) {
            //noinspection unchecked
            super(callable);
            this.callableString = String.valueOf(callable);
            this.sequence = sequence;
        }

        @Override
        public void run() {
            Object response = null;
            try {
                super.run();
                if (!isCancelled()) {
                    response = get();
                }
            } catch (Exception e) {
                logger.warning("While executing callable: " + callableString, e);
                response = e;
            } finally {
                if (!isCancelled()) {
                    setResponse(response);
                }
            }
        }

        private void setResponse(Object response) {
            OperationService operationService = nodeEngine.getOperationService();
            Operation op = new PutResultOperation(name, sequence, response);
            operationService.createInvocationBuilder(SERVICE_NAME, op, partitionId)
                    .setCallTimeout(Long.MAX_VALUE)
                    .invoke();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy