package org.skywalking.apm.collector.actor;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import org.skywalking.apm.collector.queue.DaemonThreadFactory;
import org.skywalking.apm.collector.queue.MessageHolder;
import org.skywalking.apm.collector.queue.MessageHolderFactory;
/**
* @author pengys5
*/
public abstract class AbstractLocalAsyncWorkerProvider<T extends AbstractLocalAsyncWorker> extends AbstractLocalWorkerProvider<T> {
public abstract int queueSize();
@Override
final public WorkerRef onCreate(
LocalWorkerContext localContext) throws IllegalArgumentException, ProviderNotFoundException {
T localAsyncWorker = (T) workerInstance(getClusterContext());
localAsyncWorker.preStart();
// Specify the size of the ring buffer, must be power of 2.
int bufferSize = queueSize();
if (!((((bufferSize - 1) & bufferSize) == 0) && bufferSize != 0)) {
throw new IllegalArgumentException("queue size must be power of 2");
}
// Construct the Disruptor
Disruptor<MessageHolder> disruptor = new Disruptor<MessageHolder>(MessageHolderFactory.INSTANCE, bufferSize, DaemonThreadFactory.INSTANCE);
RingBuffer<MessageHolder> ringBuffer = disruptor.getRingBuffer();
T.WorkerWithDisruptor disruptorWorker = new T.WorkerWithDisruptor(ringBuffer, localAsyncWorker);
// Connect the handler
disruptor.handleEventsWith(disruptorWorker);
// Start the Disruptor, starts all threads running
disruptor.start();
LocalAsyncWorkerRef workerRef = new LocalAsyncWorkerRef(role(), disruptorWorker);
if (localContext != null) {
localContext.put(workerRef);
}
return workerRef;
}
}