From 4fff1338336e84185f1a62a03e78eead03538131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bon=C3=A9r?= Date: Thu, 17 Dec 2009 19:29:19 +0100 Subject: [PATCH] Removed MessageBodyWriter causing problems + added a Compression class with support for LZF compression and uncomression + added new flag to Actor defining if actor is currently dead --- akka-actors/src/main/scala/actor/Actor.scala | 57 ++++++++++-------- .../main/scala/remote/LzfCompression.scala | 29 --------- .../src/main/scala/remote/RemoteClient.scala | 5 +- .../src/main/scala/remote/RemoteServer.scala | 11 +++- .../scala/serialization/Compression.scala | 21 +++++++ .../main/scala/serialization/Serializer.scala | 2 +- ...> javax.ws.rs.ext.MessageBodyWriter_FIXME} | 0 .../org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar | Bin 5067 -> 16412 bytes .../org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.pom | 8 +++ 9 files changed, 72 insertions(+), 61 deletions(-) delete mode 100644 akka-actors/src/main/scala/remote/LzfCompression.scala create mode 100644 akka-actors/src/main/scala/serialization/Compression.scala rename akka-rest/src/main/resources/META-INF/services/{javax.ws.rs.ext.MessageBodyWriter => javax.ws.rs.ext.MessageBodyWriter_FIXME} (100%) create mode 100644 embedded-repo/org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.pom diff --git a/akka-actors/src/main/scala/actor/Actor.scala b/akka-actors/src/main/scala/actor/Actor.scala index 2ed1f26764..db80fa641b 100644 --- a/akka-actors/src/main/scala/actor/Actor.scala +++ b/akka-actors/src/main/scala/actor/Actor.scala @@ -219,7 +219,6 @@ trait Actor extends TransactionManagement { implicit protected val self: Actor = this - // FIXME http://www.assembla.com/spaces/akka/tickets/56-Change-UUID-generation-for-the-TransactionManagement-trait // Only mutable for RemoteServer in order to maintain identity across nodes private[akka] var _uuid = Uuid.newUuid.toString def uuid = _uuid @@ -228,10 +227,11 @@ trait Actor extends TransactionManagement { // private fields // ==================================== - @volatile private var _isRunning = false - @volatile private var _isSuspended = true - @volatile private var _isShutDown: Boolean = false - private var _isEventBased: Boolean = false + @volatile private[this] var _isRunning = false + @volatile private[this] var _isSuspended = true + @volatile private[this] var _isShutDown = false + @volatile private[this] var _isEventBased: Boolean = false + @volatile private[akka] var _isKilled = false private var _hotswap: Option[PartialFunction[Any, Unit]] = None private[akka] var _remoteAddress: Option[InetSocketAddress] = None private[akka] var _linkedActors: Option[HashSet[Actor]] = None @@ -253,14 +253,14 @@ trait Actor extends TransactionManagement { * message exchanges and which is in many ways better than using the '!!' method * which will make the sender wait for a reply using a *blocking* future. */ - protected[this] var sender: Option[Actor] = None + protected var sender: Option[Actor] = None /** * The 'senderFuture' field should normally not be touched by user code, which should instead use the 'reply' method. * But it can be used for advanced use-cases when one might want to store away the future and * resolve it later and/or somewhere else. */ - protected[this] var senderFuture: Option[CompletableFutureResult] = None + protected var senderFuture: Option[CompletableFutureResult] = None // ==================================== // ==== USER CALLBACKS TO OVERRIDE ==== @@ -317,7 +317,7 @@ trait Actor extends TransactionManagement { * trapExit = List(classOf[MyApplicationException], classOf[MyApplicationError]) * */ - protected[this] var trapExit: List[Class[_ <: Throwable]] = Nil + protected var trapExit: List[Class[_ <: Throwable]] = Nil /** * User overridable callback/setting. @@ -491,11 +491,13 @@ trait Actor extends TransactionManagement { /** * Same as the '!' method but does not take an implicit sender as second parameter. */ - def send(message: Any) = + def send(message: Any) = { + if (_isKilled) throw new ActorKilledException(this) if (_isRunning) postMessageToMailbox(message, None) else throw new IllegalStateException( "Actor has not been started, you need to invoke 'actor.start' before using it") - + } + /** * Sends a message asynchronously and waits on a future for a reply message. *

@@ -508,21 +510,24 @@ trait Actor extends TransactionManagement { * If you are sending messages using !! then you have to use reply(..) * to send a reply message to the original sender. If not then the sender will block until the timeout expires. */ - def !![T](message: Any, timeout: Long): Option[T] = if (_isRunning) { - val future = postMessageToMailboxAndCreateFutureResultWithTimeout(message, timeout) - val isActiveObject = message.isInstanceOf[Invocation] - if (isActiveObject && message.asInstanceOf[Invocation].isVoid) future.completeWithResult(None) - try { - future.await - } catch { - case e: FutureTimeoutException => - if (isActiveObject) throw e - else None - } - getResultOrThrowException(future) - } else throw new IllegalStateException( - "Actor has not been started, you need to invoke 'actor.start' before using it") - + def !![T](message: Any, timeout: Long): Option[T] = { + if (_isKilled) throw new ActorKilledException(this) + if (_isRunning) { + val future = postMessageToMailboxAndCreateFutureResultWithTimeout(message, timeout) + val isActiveObject = message.isInstanceOf[Invocation] + if (isActiveObject && message.asInstanceOf[Invocation].isVoid) future.completeWithResult(None) + try { + future.await + } catch { + case e: FutureTimeoutException => + if (isActiveObject) throw e + else None + } + getResultOrThrowException(future) + } else throw new IllegalStateException( + "Actor has not been started, you need to invoke 'actor.start' before using it") + } + /** * Sends a message asynchronously and waits on a future for a reply message. *

@@ -869,6 +874,7 @@ trait Actor extends TransactionManagement { else throw new IllegalArgumentException("No handler matching message [" + message + "] in " + toString) } catch { case e => + _isKilled = true Actor.log.error(e, "Could not invoke actor [%s]", this) // FIXME to fix supervisor restart of remote actor for oneway calls, inject a supervisor proxy that can send notification back to client if (_supervisor.isDefined) _supervisor.get ! Exit(this, e) @@ -970,6 +976,7 @@ trait Actor extends TransactionManagement { preRestart(reason) Actor.log.info("Restarting actor [%s] configured as PERMANENT.", id) postRestart(reason) + _isKilled = false } private[akka] def registerSupervisorAsRemoteActor: Option[String] = synchronized { diff --git a/akka-actors/src/main/scala/remote/LzfCompression.scala b/akka-actors/src/main/scala/remote/LzfCompression.scala deleted file mode 100644 index 04d2c615de..0000000000 --- a/akka-actors/src/main/scala/remote/LzfCompression.scala +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Copyright (C) 2009 Scalable Solutions. - */ - -package se.scalablesolutions.akka.remote - -import org.h2.compress.{LZFInputStream, LZFOutputStream} - -import org.jboss.netty.channel.{Channel, ChannelHandlerContext, ChannelPipelineCoverage} -import org.jboss.netty.buffer.{ChannelBufferOutputStream, ChannelBufferInputStream, ChannelBuffer} -import org.jboss.netty.handler.codec.oneone.{OneToOneEncoder, OneToOneDecoder}; - -@ChannelPipelineCoverage("all") -class LzfDecoder extends OneToOneDecoder { - override protected def decode(ctx: ChannelHandlerContext, channel: Channel, message: AnyRef) = { - if (!(message.isInstanceOf[ChannelBuffer])) message - else { - new LZFInputStream(new ChannelBufferInputStream(message.asInstanceOf[ChannelBuffer])) - } - } -} - -@ChannelPipelineCoverage("all") -class LzfEncoder extends OneToOneEncoder { - override protected def encode(ctx: ChannelHandlerContext, channel: Channel, message: AnyRef) = { - if (!(message.isInstanceOf[ChannelBuffer])) message - else new LZFOutputStream(new ChannelBufferOutputStream(message.asInstanceOf[ChannelBuffer])) - } -} diff --git a/akka-actors/src/main/scala/remote/RemoteClient.scala b/akka-actors/src/main/scala/remote/RemoteClient.scala index adb8a65ce3..cf9182646b 100644 --- a/akka-actors/src/main/scala/remote/RemoteClient.scala +++ b/akka-actors/src/main/scala/remote/RemoteClient.scala @@ -102,8 +102,7 @@ class RemoteClient(hostname: String, port: Int) extends Logging { connection.getChannel.getCloseFuture.awaitUninterruptibly channelFactory.releaseExternalResources } - - timer.stop + timer.stop } def send(request: RemoteRequest): Option[CompletableFutureResult] = if (isRunning) { @@ -169,7 +168,7 @@ class RemoteClientHandler(val name: String, val futures: ConcurrentMap[Long, CompletableFutureResult], val supervisors: ConcurrentMap[String, Actor], val bootstrap: ClientBootstrap, - val timer: HashedWheelTimer) + val timer: HashedWheelTimer) extends SimpleChannelUpstreamHandler with Logging { import Actor.Sender.Self diff --git a/akka-actors/src/main/scala/remote/RemoteServer.scala b/akka-actors/src/main/scala/remote/RemoteServer.scala index f297475ad4..1145689683 100755 --- a/akka-actors/src/main/scala/remote/RemoteServer.scala +++ b/akka-actors/src/main/scala/remote/RemoteServer.scala @@ -25,14 +25,19 @@ import org.jboss.netty.handler.codec.compression.{ZlibEncoder, ZlibDecoder} * Use this object if you need a single remote server on a specific node. * *

+ * // takes hostname and port from 'akka.conf'
  * RemoteNode.start
  * 
* + *
+ * RemoteNode.start(hostname, port)
+ * 
+ * * If you need to create more than one, then you can use the RemoteServer: * *
  * val server = new RemoteServer
- * server.start
+ * server.start(hostname, port)
  * 
* * @author Jonas Bonér @@ -201,8 +206,7 @@ class RemoteServerHandler(val name: String, openChannels: ChannelGroup, val appl private def dispatchToActor(request: RemoteRequest, channel: Channel) = { log.debug("Dispatching to remote actor [%s]", request.getTarget) val actor = createActor(request.getTarget, request.getUuid, request.getTimeout) - actor.start - + val message = RemoteProtocolBuilder.getMessage(request) if (request.getIsOneWay) { if (request.hasSourceHostname && request.hasSourcePort) { @@ -360,6 +364,7 @@ class RemoteServerHandler(val name: String, openChannels: ChannelGroup, val appl newInstance.timeout = timeout newInstance._remoteAddress = None actors.put(uuid, newInstance) + newInstance.start newInstance } catch { case e => diff --git a/akka-actors/src/main/scala/serialization/Compression.scala b/akka-actors/src/main/scala/serialization/Compression.scala new file mode 100644 index 0000000000..9cc2649742 --- /dev/null +++ b/akka-actors/src/main/scala/serialization/Compression.scala @@ -0,0 +1,21 @@ +/** + * Copyright (C) 2009 Scalable Solutions. + */ + +package se.scalablesolutions.akka.serialization + +/** + * @author Jonas Bonér + */ +object Compression { + + /** + * @author Jonas Bonér + */ + object LZF { + import voldemort.store.compress.lzf._ + def compress(bytes: Array[Byte]): Array[Byte] = LZFEncoder.encode(bytes) + def uncompress(bytes: Array[Byte]): Array[Byte] = LZFDecoder.decode(bytes) + } +} + diff --git a/akka-actors/src/main/scala/serialization/Serializer.scala b/akka-actors/src/main/scala/serialization/Serializer.scala index 643855a141..e6b791f168 100644 --- a/akka-actors/src/main/scala/serialization/Serializer.scala +++ b/akka-actors/src/main/scala/serialization/Serializer.scala @@ -10,7 +10,7 @@ import com.google.protobuf.Message import org.codehaus.jackson.map.ObjectMapper -import sjson.json.{Serializer =>SJSONSerializer} +import sjson.json.{Serializer => SJSONSerializer} /** * @author Jonas Bonér diff --git a/akka-rest/src/main/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter b/akka-rest/src/main/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter_FIXME similarity index 100% rename from akka-rest/src/main/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter rename to akka-rest/src/main/resources/META-INF/services/javax.ws.rs.ext.MessageBodyWriter_FIXME diff --git a/embedded-repo/org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar b/embedded-repo/org/h2/compress/h2-lzf/1.0/h2-lzf-1.0.jar index 620cfb1371e4510bf524bf16b3f6b172830f5cb5..5d74200e45a79e26548f90f189941caba3621327 100644 GIT binary patch literal 16412 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 literal 5067 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 u$21LFQyJYv + + 4.0.0 + org.h2.compress + h2-lzf + 1.0 + jar + \ No newline at end of file