Package reactor.alloc.spec

Source Code of reactor.alloc.spec.RingBufferAllocatorSpec

/*
* Copyright (c) 2011-2014 Pivotal Software, Inc.
*
*  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 reactor.alloc.spec;

import reactor.alloc.Recyclable;
import reactor.alloc.Reference;
import reactor.alloc.RingBufferAllocator;
import reactor.function.Consumer;
import reactor.function.Supplier;
import reactor.jarjar.com.lmax.disruptor.BlockingWaitStrategy;
import reactor.jarjar.com.lmax.disruptor.EventHandler;
import reactor.jarjar.com.lmax.disruptor.ExceptionHandler;
import reactor.jarjar.com.lmax.disruptor.WaitStrategy;
import reactor.jarjar.com.lmax.disruptor.dsl.ProducerType;
import reactor.util.Assert;

import java.util.concurrent.ExecutorService;

/**
* Helper class for creating a {@link reactor.alloc.RingBufferAllocator}. Provides an easy way to specify the
* {@code EventFactory}, {@code EventHandler}, and {@code ExceptionHandler} via Reactor abstractions of {@link
* reactor.function.Supplier} and {@link Consumer}.
*
* @author Jon Brisbin
* @since 1.1
*/
public class RingBufferAllocatorSpec<T extends Recyclable> implements Supplier<RingBufferAllocator<T>> {

  private String name         = "ring-buffer-allocator";
  private int    ringSize     = 1024;
  private int    eventThreads = 1;

  private Supplier<T>            allocator;
  private Consumer<Reference<T>> eventHandler;
  private Consumer<Throwable>    errorHandler;
  private ProducerType           producerType;
  private WaitStrategy           waitStrategy;
  private ExecutorService        executor;

  /**
   * Name of the {@code RingBufferAllocator}.
   *
   * @param name
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> name(String name) {
    this.name = name;
    return this;
  }

  /**
   * Size of the {@code RingBuffer} ring.
   *
   * @param ringSize
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> ringSize(int ringSize) {
    Assert.isTrue(ringSize > 0, "Ring size must be greater than 0 (zero).");
    this.ringSize = ringSize;
    return this;
  }

  /**
   * Specify the number of threads the underlying {@link com.lmax.disruptor.RingBuffer} will use.
   *
   * @param eventThreads
   *     number of threads for event handlers
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> eventThreads(int eventThreads) {
    Assert.isTrue(eventThreads > 0, "Threads size must be 1 or greater.");
    this.eventThreads = eventThreads;
    return this;
  }

  /**
   * The {@link reactor.function.Supplier} to provide the {@code RingBuffer} with the reusable objects that are being
   * pooled.
   *
   * @param allocator
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> allocator(Supplier<T> allocator) {
    this.allocator = allocator;
    return this;
  }

  /**
   * The {@link reactor.function.Consumer} to be invoked with a sequence ID is published.
   *
   * @param eventHandler
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> eventHandler(Consumer<Reference<T>> eventHandler) {
    this.eventHandler = eventHandler;
    return this;
  }

  /**
   * The {@link reactor.function.Consumer} to be invoked when an error occurs.
   *
   * @param errorHandler
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> errorHandler(Consumer<Throwable> errorHandler) {
    this.errorHandler = errorHandler;
    return this;
  }

  /**
   * Specify single or multi-threaded producer.
   *
   * @param producerType
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> producerType(ProducerType producerType) {
    this.producerType = producerType;
    return this;
  }

  /**
   * Specify the {@link com.lmax.disruptor.WaitStrategy} to use (defaults to {@link
   * com.lmax.disruptor.BlockingWaitStrategy}).
   *
   * @param waitStrategy
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> waitStrategy(WaitStrategy waitStrategy) {
    this.waitStrategy = waitStrategy;
    return this;
  }

  /**
   * The {@link java.util.concurrent.ExecutorService} to use inside the {@link com.lmax.disruptor.RingBuffer}.
   *
   * @param executor
   *
   * @return {@code this}
   */
  public RingBufferAllocatorSpec<T> executor(ExecutorService executor) {
    this.executor = executor;
    return this;
  }

  @Override
  public RingBufferAllocator<T> get() {
    Assert.notNull(allocator, "Object Supplier (allocator) cannot be null.");

    if(null == producerType) {
      producerType = ProducerType.MULTI;
    }
    if(null == waitStrategy) {
      waitStrategy = new BlockingWaitStrategy();
    }

    RingBufferAllocator<T> alloc = new RingBufferAllocator<T>(
        name,
        ringSize,
        allocator,
        eventThreads,
        (null != eventHandler ? new EventHandler<Reference<T>>() {
          @Override
          public void onEvent(Reference<T> ref, long sequence, boolean endOfBatch) throws Exception {
            eventHandler.accept(ref);
            if(ref.getReferenceCount() > 0) {
              ref.release();
            }
          }
        } : null),
        (null != errorHandler ? new ExceptionHandler() {
          @Override
          public void handleEventException(Throwable ex, long sequence, Object event) {
            errorHandler.accept(ex);
          }

          @Override
          public void handleOnStartException(Throwable ex) {
            errorHandler.accept(ex);
          }

          @Override
          public void handleOnShutdownException(Throwable ex) {
            errorHandler.accept(ex);
          }
        } : null),
        producerType,
        waitStrategy,
        executor
    );
    // auto-start
    alloc.start();

    return alloc;
  }

}
TOP

Related Classes of reactor.alloc.spec.RingBufferAllocatorSpec

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.