com.webbfontaine.valuewebb.irms.worker.GParsWorkerPool.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.irms.worker.GParsWorkerPool.java

Source

/*
 * Copyrights 2002-2013 Webb Fontaine
 * Developer: Sargis Harutyunyan
 * Date: 29 juin 2013
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 */
package com.webbfontaine.valuewebb.irms.worker;

import com.google.common.collect.Lists;
import groovyx.gpars.actor.Actor;
import groovyx.gpars.actor.DynamicDispatchActor;
import groovyx.gpars.group.NonDaemonPGroup;
import groovyx.gpars.group.PGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

import static com.webbfontaine.twm.urmcore.utils.Preconditions.checkNotNull;

public class GParsWorkerPool implements WorkerPool {

    private static final Logger LOGGER = LoggerFactory.getLogger(GParsWorkerPool.class);

    private final WorkerFactory workerFactory;
    private final PGroup pGroup;

    private List<Actor> workers;

    public GParsWorkerPool(WorkerFactory workerFactory) {
        this(workerFactory, new NonDaemonPGroup());
    }

    public GParsWorkerPool(WorkerFactory workerFactory, int threadPoolSize) {
        this(workerFactory, new NonDaemonPGroup(threadPoolSize));
    }

    private GParsWorkerPool(WorkerFactory workerFactory, PGroup pGroup) {
        this.workerFactory = workerFactory;
        this.pGroup = pGroup;
    }

    /*
     Init 'Worker Pool', start() method is not thread safe and should be called only once and before trying submit works
     */
    @Override
    public void start() { // should be sync call, non thread safe
        if (workers == null) {
            workers = createWorkers(pGroup);
        }
    }

    @Override
    public void run(WorkUnit input) {
        checkWorkersNotNull();

        Actor worker = getWorker(input);
        worker.send(input);
    }

    @Override
    public <V> V runAndWait(WorkUnit input) throws InterruptedException {
        checkWorkersNotNull();

        Actor worker = getWorker(input);
        return worker.sendAndWait(input);
    }

    @Override
    public void shutdown() {
        stopWorkers();
        stopThreadPool();
    }

    private <T extends WorkUnit> Actor getWorker(T input) {
        return workers.get(workerId(input));
    }

    private <T extends WorkUnit> int workerId(T input) {
        return input.workerId() % workerFactory.getWorkersPoolSize();
    }

    private void checkWorkersNotNull() {
        checkNotNull(workers, "WorkerPool should by started before trying to submit work to it");
    }

    protected List<Actor> createWorkers(PGroup pGroup) {
        int workersPoolSize = workerFactory.getWorkersPoolSize();

        List<Actor> actors = Lists.newArrayListWithExpectedSize(workersPoolSize);
        for (int index = 0; index < workersPoolSize; index++) {
            DynamicDispatchActor actor = createDispatchActor(pGroup);
            actor.start();

            actors.add(actor);
        }
        return actors;
    }

    private DynamicDispatchActor createDispatchActor(PGroup pGroup) {
        DynamicDispatchActor dispatchActor = workerFactory.createDispatchActor();
        dispatchActor.setParallelGroup(pGroup);

        return dispatchActor;
    }

    private void stopWorkers() {
        for (Actor worker : workers) {
            worker.stop();
        }

        for (Actor worker : workers) {
            try {
                worker.join();
            } catch (InterruptedException e) {
                LOGGER.warn("", e);
            }
        }
    }

    private void stopThreadPool() {
        pGroup.shutdown();
    }

}