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; } }