Rewrote the dispatcher APIs and internals, now event-based dispatchers are 10x faster and much faster than Scala Actors. Added Executor and ForkJoin based dispatchers. Added a bunch of dispatcher tests. Added performance test
This commit is contained in:
parent
de5735a4e2
commit
e35e9581bc
27 changed files with 937 additions and 501 deletions
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Copyright (C) 2009 Scalable Solutions.
|
||||
*/
|
||||
|
||||
package se.scalablesolutions.akka.dispatch
|
||||
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
/**
|
||||
* Default settings are:
|
||||
* <pre/>
|
||||
* - withNewThreadPoolWithLinkedBlockingQueueWithUnboundedCapacity
|
||||
* - NR_START_THREADS = 16
|
||||
* - NR_MAX_THREADS = 128
|
||||
* - KEEP_ALIVE_TIME = 60000L // one minute
|
||||
* </pre>
|
||||
* <p/>
|
||||
*
|
||||
* The dispatcher has a fluent builder interface to build up a thread pool to suite your use-case.
|
||||
* There is a default thread pool defined but make use of the builder if you need it. Here are some examples.
|
||||
* <p/>
|
||||
*
|
||||
* Scala API.
|
||||
* <p/>
|
||||
* Example usage:
|
||||
* <pre/>
|
||||
* val dispatcher = new ExecutorBasedEventDrivenDispatcher("name")
|
||||
* dispatcher
|
||||
* .withNewThreadPoolWithBoundedBlockingQueue(100)
|
||||
* .setCorePoolSize(16)
|
||||
* .setMaxPoolSize(128)
|
||||
* .setKeepAliveTimeInMillis(60000)
|
||||
* .setRejectionPolicy(new CallerRunsPolicy)
|
||||
* .buildThreadPool
|
||||
* </pre>
|
||||
* <p/>
|
||||
*
|
||||
* Java API.
|
||||
* <p/>
|
||||
* Example usage:
|
||||
* <pre/>
|
||||
* ExecutorBasedEventDrivenDispatcher dispatcher = new ExecutorBasedEventDrivenDispatcher("name");
|
||||
* dispatcher
|
||||
* .withNewThreadPoolWithBoundedBlockingQueue(100)
|
||||
* .setCorePoolSize(16)
|
||||
* .setMaxPoolSize(128)
|
||||
* .setKeepAliveTimeInMillis(60000)
|
||||
* .setRejectionPolicy(new CallerRunsPolicy())
|
||||
* .buildThreadPool();
|
||||
* </pre>
|
||||
* <p/>
|
||||
*
|
||||
* But the preferred way of creating dispatchers is to use
|
||||
* the {@link se.scalablesolutions.akka.dispatch.Dispatchers} factory object.
|
||||
*
|
||||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
class ExecutorBasedEventDrivenDispatcher(_name: String) extends MessageDispatcher with ThreadPoolBuilder {
|
||||
@volatile private var active: Boolean = false
|
||||
|
||||
val name = "event-driven:executor:dispatcher:" + _name
|
||||
|
||||
withNewThreadPoolWithLinkedBlockingQueueWithUnboundedCapacity.buildThreadPool
|
||||
|
||||
//private val _executor = Executors.newFixedThreadPool(4)
|
||||
|
||||
def dispatch(invocation: MessageInvocation) = if (active) {
|
||||
executor.execute(new Runnable() {
|
||||
def run = invocation.invoke
|
||||
})
|
||||
} else throw new IllegalStateException("Can't submit invocations to dispatcher since it's not started")
|
||||
|
||||
def start = if (!active) {
|
||||
active = true
|
||||
}
|
||||
|
||||
def canBeShutDown = true
|
||||
|
||||
def shutdown = if (active) {
|
||||
executor.shutdownNow
|
||||
active = false
|
||||
}
|
||||
|
||||
def registerHandler(key: AnyRef, handler: MessageInvoker) = {}
|
||||
def unregisterHandler(key: AnyRef) = {}
|
||||
|
||||
def ensureNotActive: Unit = if (active) throw new IllegalStateException(
|
||||
"Can't build a new thread pool for a dispatcher that is already up and running")
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue