Removing the AtomicReference from Dispatcher and restructured the code a bit
This commit is contained in:
parent
1a3329baa2
commit
4a2227fc95
2 changed files with 22 additions and 13 deletions
|
|
@ -33,11 +33,15 @@ class Dispatcher(
|
|||
val shutdownTimeout: Duration)
|
||||
extends MessageDispatcher(_prerequisites) {
|
||||
|
||||
protected val executorServiceFactory: ExecutorServiceFactory =
|
||||
executorServiceFactoryProvider.createExecutorServiceFactory(id, prerequisites.threadFactory)
|
||||
private class LazyExecutorServiceDelegate(factory: ExecutorServiceFactory) extends ExecutorServiceDelegate {
|
||||
lazy val executor: ExecutorService = factory.createExecutorService
|
||||
def copy(): LazyExecutorServiceDelegate = new LazyExecutorServiceDelegate(factory)
|
||||
}
|
||||
|
||||
protected val executorService = new AtomicReference[ExecutorServiceDelegate](
|
||||
new ExecutorServiceDelegate { lazy val executor = executorServiceFactory.createExecutorService })
|
||||
@volatile private var executorServiceDelegate: LazyExecutorServiceDelegate =
|
||||
new LazyExecutorServiceDelegate(executorServiceFactoryProvider.createExecutorServiceFactory(id, prerequisites.threadFactory))
|
||||
|
||||
protected final def executorService: ExecutorService = executorServiceDelegate
|
||||
|
||||
/**
|
||||
* INTERNAL USE ONLY
|
||||
|
|
@ -62,11 +66,11 @@ class Dispatcher(
|
|||
*/
|
||||
protected[akka] def executeTask(invocation: TaskInvocation) {
|
||||
try {
|
||||
executorService.get() execute invocation
|
||||
executorService execute invocation
|
||||
} catch {
|
||||
case e: RejectedExecutionException ⇒
|
||||
try {
|
||||
executorService.get() execute invocation
|
||||
executorService execute invocation
|
||||
} catch {
|
||||
case e2: RejectedExecutionException ⇒
|
||||
prerequisites.eventStream.publish(Error(e, getClass.getName, getClass, "executeTask was rejected twice!"))
|
||||
|
|
@ -83,10 +87,15 @@ class Dispatcher(
|
|||
/**
|
||||
* INTERNAL USE ONLY
|
||||
*/
|
||||
protected[akka] def shutdown: Unit =
|
||||
Option(executorService.getAndSet(new ExecutorServiceDelegate {
|
||||
lazy val executor = executorServiceFactory.createExecutorService
|
||||
})) foreach { _.shutdown() }
|
||||
protected[akka] def shutdown: Unit = {
|
||||
val newDelegate = executorServiceDelegate.copy() // Doesn't matter which one we copy
|
||||
val es = synchronized { // FIXME getAndSet using ARFU or Unsafe
|
||||
val service = executorServiceDelegate
|
||||
executorServiceDelegate = newDelegate // just a quick getAndSet
|
||||
service
|
||||
}
|
||||
es.shutdown()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if it was registered
|
||||
|
|
@ -97,12 +106,12 @@ class Dispatcher(
|
|||
if (mbox.canBeScheduledForExecution(hasMessageHint, hasSystemMessageHint)) { //This needs to be here to ensure thread safety and no races
|
||||
if (mbox.setAsScheduled()) {
|
||||
try {
|
||||
executorService.get() execute mbox
|
||||
executorService execute mbox
|
||||
true
|
||||
} catch {
|
||||
case e: RejectedExecutionException ⇒
|
||||
try {
|
||||
executorService.get() execute mbox
|
||||
executorService execute mbox
|
||||
true
|
||||
} catch { //Retry once
|
||||
case e: RejectedExecutionException ⇒
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue