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

ru.taskurotta.service.hz.server.PendingDecisionQueueProxy Maven / Gradle / Ivy

The newest version!
package ru.taskurotta.service.hz.server;

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.util.EmptyStatement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.taskurotta.hazelcast.queue.CachedQueue;
import ru.taskurotta.hazelcast.queue.config.CachedQueueServiceConfig;
import ru.taskurotta.service.hz.TaskKey;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 */
public class PendingDecisionQueueProxy {

    private static final Logger logger = LoggerFactory.getLogger(PendingDecisionQueueProxy.class);

    public static final long LOCK_TRY_TIME_MLS = 250;
    public static final String QUEUE_NAME = "PendingDecisions";

    private final HazelcastTaskServer taskServer;
    private final int maxPendingWorkers;
    private final int maxPendingLimit;
    private final long sleepOnOverloadMls;

    private final CachedQueue desTaskQueue;
    private final ExecutorService cachedExecutorService;

    private volatile int size;
    private final Lock lock = new ReentrantLock();

    public PendingDecisionQueueProxy(HazelcastInstance hzInstance, HazelcastTaskServer taskServer, int maxPendingWorkers,
                                     int maxPendingLimit, long sleepOnOverloadMls) {
        this.taskServer = taskServer;
        this.maxPendingWorkers = maxPendingWorkers;
        this.maxPendingLimit = maxPendingLimit;
        this.sleepOnOverloadMls = sleepOnOverloadMls;

        this.desTaskQueue = getQueue(hzInstance);
        this.cachedExecutorService = new ThreadPoolExecutor(3, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
                new SynchronousQueue());
    }


    public boolean stash(TaskKey taskKey) {

        final boolean result = desTaskQueue.offer(taskKey);
        addNewWorkerIfRequired();
        return result;
    }


    private void addNewWorkerIfRequired() {
        if (size < maxPendingWorkers) {
            try {
                if (lock.tryLock(LOCK_TRY_TIME_MLS, TimeUnit.MILLISECONDS)) {
                    try {
                        if (size < maxPendingWorkers && desTaskQueue.size() > 0) {
                            size++;
                            cachedExecutorService.execute(new Worker());
                        }
                    } finally {
                        lock.unlock();
                    }
                }
            } catch (InterruptedException ignored) {
                EmptyStatement.ignore(ignored);
            }
        }
    }

    private class Worker implements Runnable {

        @Override
        public void run() {
            try {

                TaskKey taskKey = null;
                do {
                    taskKey = desTaskQueue.poll();
                    if (taskKey == null) {
                        break;
                    }

                    if (taskServer.localExecutorStats.getPendingTaskCount() > maxPendingLimit) {
                        TimeUnit.MILLISECONDS.sleep(sleepOnOverloadMls);
                    }
                    taskServer.sendToClusterMember(taskKey);
                }
                while (true);

                // reduce addNewWorkerIfRequired() pressing
                TimeUnit.SECONDS.sleep(1);

            } catch (InterruptedException ignored) {
                EmptyStatement.ignore(ignored);
            } finally {
                exit();
            }
        }

        void exit() {
            lock.lock();
            try {
                size--;
                addNewWorkerIfRequired();
            } finally {
                lock.unlock();
            }
        }
    }

    private static CachedQueue getQueue(HazelcastInstance hzInstance) {

//        CachedQueueConfig cachedQueueConfig = CachedQueueServiceConfig.getQueueConfig(hzInstance.getConfig(),
//                QUEUE_NAME);
//        cachedQueueConfig.setCacheSize(Integer.MAX_VALUE);


        return CachedQueueServiceConfig.getCachedQueue(hzInstance, QUEUE_NAME);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy