1. Added config option to enable/disable the remote client transaction log for resending failed messages.

2. Swallows exceptions on appending to transaction log and do not complete the Future matching the message.
This commit is contained in:
Jonas Bonér 2011-03-27 22:58:50 +02:00
parent e6c658f58d
commit cf80e6a33d
4 changed files with 34 additions and 27 deletions

View file

@ -6,18 +6,14 @@ package akka.actor
import akka.event.EventHandler
import akka.dispatch._
import akka.config.Config._
import akka.config.Supervision._
import akka.AkkaException
import akka.util._
import ReflectiveAccess._
import java.net.InetSocketAddress
import java.util.concurrent.atomic.{AtomicInteger, AtomicReference}
import java.util.concurrent.locks.ReentrantLock
import java.util.concurrent.atomic.AtomicReference
import java.util.concurrent.{ ScheduledFuture, ConcurrentHashMap, TimeUnit }
import java.util.{ Map => JMap }
import java.lang.reflect.Field
import scala.reflect.BeanProperty
import scala.collection.immutable.Stack

View file

@ -16,6 +16,7 @@ import akka.actor.{PoisonPill, Index, LocalActorRef, Actor, RemoteActorRef,
RemoteActorSystemMessage, uuidFrom, Uuid,
Exit, LifeCycleMessage, ActorType => AkkaActorType}
import akka.actor.Actor._
import akka.config.Config._
import akka.util._
import akka.event.EventHandler
@ -149,14 +150,16 @@ trait NettyRemoteClientModule extends RemoteClientModule { self: ListenerManagem
}
/**
* This is the abstract baseclass for netty remote clients,
* currently there's only an ActiveRemoteClient, but otehrs could be feasible, like a PassiveRemoteClient that
* This is the abstract baseclass for netty remote clients, currently there's only an
* ActiveRemoteClient, but otehrs could be feasible, like a PassiveRemoteClient that
* reuses an already established connection.
*/
abstract class RemoteClient private[akka] (
val module: NettyRemoteClientModule,
val remoteAddress: InetSocketAddress) {
val useTransactionLog = config.getBool("akka.remote.resend-on-failure", true)
val name = this.getClass.getSimpleName + "@" +
remoteAddress.getAddress.getHostAddress + "::" +
remoteAddress.getPort
@ -237,9 +240,10 @@ abstract class RemoteClient private[akka] (
}
} catch {
case e: Throwable =>
pendingRequests.add((true, null, request)) // add the request to the tx log after a failing send
// add the request to the tx log after a failing send
notifyListeners(RemoteClientError(e, module, remoteAddress))
throw e
if (useTransactionLog) pendingRequests.add((true, null, request))
else throw e
}
None
} else {
@ -249,10 +253,13 @@ abstract class RemoteClient private[akka] (
futures.put(futureUuid, futureResult) // Add future prematurely, remove it if write fails
def handleRequestReplyError(future: ChannelFuture) = {
notifyListeners(RemoteClientWriteFailed(request, future.getCause, module, remoteAddress))
if (useTransactionLog) {
pendingRequests.add((false, futureUuid, request)) // Add the request to the tx log after a failing send
} else {
val f = futures.remove(futureUuid) // Clean up future
if (f ne null) f.completeWithException(future.getCause)
notifyListeners(RemoteClientWriteFailed(request, future.getCause, module, remoteAddress))
}
}
var future: ChannelFuture = null
@ -509,7 +516,7 @@ class ActiveRemoteClientHandler(
override def channelConnected(ctx: ChannelHandlerContext, event: ChannelStateEvent) = {
try {
client.sendPendingRequests() // try to send pending requests (still there after client/server crash ard reconnect
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))
client.resetReconnectionTimeWindow
} catch {

View file

@ -65,10 +65,13 @@ trait NetworkFailureTest { self: WordSpec =>
import akka.actor.Actor._
import akka.util.Duration
// override is subclass if needed
val BYTES_PER_SECOND = "60KByte/s"
val DELAY_MILLIS = "350ms"
val PORT_RANGE = "1024-65535"
// FIXME add support for TCP FIN by hooking into Netty and do socket.close
def replyWithTcpResetFor(duration: Duration, dead: AtomicBoolean) = {
spawn {
try {

View file

@ -146,6 +146,7 @@ akka {
}
client {
resend-on-failure = true
reconnect-delay = 5
read-timeout = 10
message-frame-size = 1048576