Merge with Peter's work (i.e. merging master into tame-globals)
This commit is contained in:
commit
44b94643e5
60 changed files with 2078 additions and 1700 deletions
|
|
@ -51,7 +51,6 @@ trait NettyRemoteClientModule extends RemoteClientModule {
|
|||
self: RemoteSupport ⇒
|
||||
|
||||
private val remoteClients = new HashMap[RemoteAddress, RemoteClient]
|
||||
private val remoteActors = new Index[RemoteAddress, Uuid]
|
||||
private val lock = new ReadWriteGuard
|
||||
|
||||
def app: AkkaApplication
|
||||
|
|
@ -143,22 +142,13 @@ abstract class RemoteClient private[akka] (
|
|||
val module: NettyRemoteClientModule,
|
||||
val remoteAddress: InetSocketAddress) {
|
||||
|
||||
import app.config
|
||||
implicit def _app = app
|
||||
val serialization = new RemoteActorSerialization(app)
|
||||
|
||||
val useTransactionLog = config.getBool("akka.remote.client.buffering.retry-message-send-on-failure", false)
|
||||
val transactionLogCapacity = config.getInt("akka.remote.client.buffering.capacity", -1)
|
||||
|
||||
val name = this.getClass.getSimpleName + "@" +
|
||||
remoteAddress.getAddress.getHostAddress + "::" +
|
||||
remoteAddress.getPort
|
||||
|
||||
val serialization = new RemoteActorSerialization(app)
|
||||
|
||||
protected val futures = new ConcurrentHashMap[Uuid, Promise[_]]
|
||||
protected val pendingRequests = {
|
||||
if (transactionLogCapacity < 0) new ConcurrentLinkedQueue[(Boolean, Uuid, RemoteMessageProtocol)]
|
||||
new LinkedBlockingQueue[(Boolean, Uuid, RemoteMessageProtocol)](transactionLogCapacity)
|
||||
}
|
||||
|
||||
private[remote] val runSwitch = new Switch()
|
||||
|
||||
|
|
@ -172,19 +162,6 @@ abstract class RemoteClient private[akka] (
|
|||
|
||||
def shutdown(): Boolean
|
||||
|
||||
/**
|
||||
* Returns an array with the current pending messages not yet delivered.
|
||||
*/
|
||||
def pendingMessages: Array[Any] = {
|
||||
var messages = Vector[Any]()
|
||||
val iter = pendingRequests.iterator
|
||||
while (iter.hasNext) {
|
||||
val (_, _, message) = iter.next
|
||||
messages = messages :+ MessageSerializer.deserialize(app, message.getMessage)
|
||||
}
|
||||
messages.toArray
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the message to the wireprotocol and sends the message across the wire
|
||||
*/
|
||||
|
|
@ -219,13 +196,7 @@ abstract class RemoteClient private[akka] (
|
|||
notifyListeners(RemoteClientWriteFailed(request, future.getCause, module, remoteAddress))
|
||||
}
|
||||
} catch {
|
||||
case e: Exception ⇒
|
||||
notifyListeners(RemoteClientError(e, module, remoteAddress))
|
||||
|
||||
if (useTransactionLog && !pendingRequests.offer((true, null, request))) { // Add the request to the tx log after a failing send
|
||||
pendingRequests.clear()
|
||||
throw new RemoteClientMessageBufferException("Buffer limit [" + transactionLogCapacity + "] reached")
|
||||
}
|
||||
case e: Exception ⇒ notifyListeners(RemoteClientError(e, module, remoteAddress))
|
||||
}
|
||||
None
|
||||
|
||||
|
|
@ -233,20 +204,14 @@ abstract class RemoteClient private[akka] (
|
|||
} else {
|
||||
val futureResult =
|
||||
if (senderFuture.isDefined) senderFuture.get
|
||||
else new DefaultPromise[T](request.getActorInfo.getTimeout)
|
||||
else new DefaultPromise[T](request.getActorInfo.getTimeout)(app.dispatcher)
|
||||
|
||||
val futureUuid = uuidFrom(request.getUuid.getHigh, request.getUuid.getLow)
|
||||
futures.put(futureUuid, futureResult) // Add future prematurely, remove it if write fails
|
||||
|
||||
def handleRequestReplyError(future: ChannelFuture) = {
|
||||
if (useTransactionLog && !pendingRequests.offer((false, futureUuid, request))) { // Add the request to the tx log after a failing send
|
||||
pendingRequests.clear()
|
||||
throw new RemoteClientMessageBufferException("Buffer limit [" + transactionLogCapacity + "] reached")
|
||||
|
||||
} else {
|
||||
val f = futures.remove(futureUuid) // Clean up future
|
||||
if (f ne null) f.completeWithException(future.getCause)
|
||||
}
|
||||
val f = futures.remove(futureUuid) // Clean up future
|
||||
if (f ne null) f.completeWithException(future.getCause)
|
||||
}
|
||||
|
||||
var future: ChannelFuture = null
|
||||
|
|
@ -274,41 +239,6 @@ abstract class RemoteClient private[akka] (
|
|||
throw exception
|
||||
}
|
||||
}
|
||||
|
||||
private[remote] def sendPendingRequests() = pendingRequests synchronized {
|
||||
// ensure only one thread at a time can flush the log
|
||||
val nrOfMessages = pendingRequests.size
|
||||
if (nrOfMessages > 0) app.eventHandler.info(this, "Resending [%s] previously failed messages after remote client reconnect" format nrOfMessages)
|
||||
var pendingRequest = pendingRequests.peek
|
||||
|
||||
while (pendingRequest ne null) {
|
||||
val (isOneWay, futureUuid, message) = pendingRequest
|
||||
|
||||
if (isOneWay) {
|
||||
// tell
|
||||
val future = currentChannel.write(RemoteEncoder.encode(message))
|
||||
future.awaitUninterruptibly()
|
||||
|
||||
if (future.isCancelled && !future.isSuccess) {
|
||||
notifyListeners(RemoteClientWriteFailed(message, future.getCause, module, remoteAddress))
|
||||
}
|
||||
|
||||
} else {
|
||||
// ask
|
||||
val future = currentChannel.write(RemoteEncoder.encode(message))
|
||||
future.awaitUninterruptibly()
|
||||
|
||||
if (future.isCancelled || !future.isSuccess) {
|
||||
val f = futures.remove(futureUuid) // Clean up future
|
||||
if (f ne null) f.completeWithException(future.getCause)
|
||||
notifyListeners(RemoteClientWriteFailed(message, future.getCause, module, remoteAddress))
|
||||
}
|
||||
}
|
||||
|
||||
pendingRequests.remove(pendingRequest)
|
||||
pendingRequest = pendingRequests.peek // try to grab next message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -441,7 +371,6 @@ class ActiveRemoteClient private[akka] (
|
|||
bootstrap.releaseExternalResources()
|
||||
bootstrap = null
|
||||
connection = null
|
||||
pendingRequests.clear()
|
||||
|
||||
app.eventHandler.info(this, "[%s] has been shut down".format(name))
|
||||
}
|
||||
|
|
@ -564,7 +493,6 @@ class ActiveRemoteClientHandler(
|
|||
|
||||
override def channelConnected(ctx: ChannelHandlerContext, event: ChannelStateEvent) = {
|
||||
try {
|
||||
if (client.useTransactionLog) client.sendPendingRequests() // try to send pending requests (still there after client/server crash ard reconnect
|
||||
client.notifyListeners(RemoteClientConnected(client.module, client.remoteAddress))
|
||||
app.eventHandler.debug(this, "Remote client connected to [%s]".format(ctx.getChannel.getRemoteAddress))
|
||||
client.resetReconnectionTimeWindow
|
||||
|
|
@ -648,7 +576,7 @@ class NettyRemoteSupport(_app: AkkaApplication) extends RemoteSupport(_app) with
|
|||
app.eventHandler.debug(this,
|
||||
"Creating RemoteActorRef with address [%s] connected to [%s]"
|
||||
.format(actorAddress, remoteInetSocketAddress))
|
||||
RemoteActorRef(app, app.remote, remoteInetSocketAddress, actorAddress, loader)
|
||||
RemoteActorRef(app.remote, remoteInetSocketAddress, actorAddress, loader)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -971,7 +899,7 @@ class RemoteServerHandler(
|
|||
override def messageReceived(ctx: ChannelHandlerContext, event: MessageEvent) = {
|
||||
event.getMessage match {
|
||||
case null ⇒
|
||||
throw new IllegalActorStateException("Message in remote MessageEvent is null: " + event)
|
||||
throw new IllegalActorStateException("Message in remote MessageEvent is null [" + event + "]")
|
||||
|
||||
case remote: AkkaRemoteProtocol if remote.hasMessage ⇒
|
||||
handleRemoteMessageProtocol(remote.getMessage, event.getChannel)
|
||||
|
|
@ -1070,12 +998,6 @@ class RemoteServerHandler(
|
|||
private def createActor(actorInfo: ActorInfoProtocol, channel: Channel): ActorRef = {
|
||||
val uuid = actorInfo.getUuid
|
||||
val address = actorInfo.getAddress
|
||||
// val address = {
|
||||
// // strip off clusterActorRefPrefix if needed
|
||||
// val addr = actorInfo.getAddress
|
||||
// if (addr.startsWith(Address.clusterActorRefPrefix)) addr.substring(addr.indexOf('.') + 1, addr.length)
|
||||
// else addr
|
||||
// }
|
||||
|
||||
app.eventHandler.debug(this,
|
||||
"Looking up a remotely available actor for address [%s] on node [%s]"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue