akka.actor.Status.Failure Scala Examples
The following examples show how to use akka.actor.Status.Failure.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: TAC.scala From akka-tools with MIT License | 5 votes |
package no.nextgentel.oss.akkatools.example2.trustaccountcreation import java.util.concurrent.TimeUnit import akka.actor.Status.Failure import akka.actor.{ActorSystem, Props, ActorPath} import no.nextgentel.oss.akkatools.aggregate._ import no.nextgentel.oss.akkatools.example2.other.{DoCreateTrustAccount, DoPerformESigning, DoSendEmailToCustomer} import scala.concurrent.duration.FiniteDuration class TACAggregate ( dmSelf:ActorPath, eSigningSystem:ActorPath, emailSystem:ActorPath, trustAccountSystem:ActorPath ) extends GeneralAggregateDMViaEvent[TACEvent, TACState](dmSelf) { override def persistenceIdBase() = TACAggregate.persistenceIdBase // Override this one to set different timeout override def idleTimeout() = FiniteDuration(60, TimeUnit.SECONDS) override var state = TACState.empty() // This is the state of our initial state (empty) // transform command to event override def cmdToEvent = { case c:CreateNewTACCmd => ResultingEvent( RegisteredEvent(c.info) ) .onSuccess{ sender() ! "ok" } .onError{ (e) => sender() ! Failure(new Exception(s"Failed: $e"))} case c:ESigningFailedCmd => ResultingEvent( ESigningFailedEvent() ) case c:ESigningCompletedCmd => ResultingEvent( ESigningCompletedEvent() ) case c:CompletedCmd => ResultingEvent( CreatedEvent(c.trustAccountId) ) case c:DeclinedCmd => ResultingEvent( DeclinedEvent(c.cause) ) } override def generateDMs = { case e:RegisteredEvent => // We must send message to eSigningSystem val msg = DoPerformESigning(dispatchId, e.info.customerNo) ResultingDMs( msg, eSigningSystem) case e:ESigningCompletedEvent => // ESigning is completed, so we should init creation of the TrustAccount val info = state.info.get val msg = DoCreateTrustAccount(dispatchId, info.customerNo, info.trustAccountType) ResultingDMs(msg, trustAccountSystem) case e:DeclinedEvent => // The TrustAccountCreation-process failed - must notify customer val msg = DoSendEmailToCustomer(state.info.get.customerNo, s"Sorry.. TAC-failed: ${e.cause}") ResultingDMs(msg, emailSystem) case e:CreatedEvent => // The TrustAccountCreation-process was success - must notify customer val msg = DoSendEmailToCustomer(state.info.get.customerNo, s"Your TrustAccount '${e.trustAccountId}' has been created!") ResultingDMs(msg, emailSystem) } } object TACAggregate { val persistenceIdBase = "TAC-" def props(dmSelf:ActorPath, eSigningSystem:ActorPath, emailSystem:ActorPath, trustAccountSystem:ActorPath) = Props(new TACAggregate(dmSelf, eSigningSystem, emailSystem ,trustAccountSystem)) } class TACStarter(system:ActorSystem) extends AggregateStarter("tac", system) with AggregateViewStarter { def config(eSigningSystem:ActorPath, emailSystem:ActorPath, trustAccountSystem:ActorPath):TACStarter = { setAggregatePropsCreator{ dmSelf => TACAggregate.props(dmSelf, eSigningSystem, emailSystem, trustAccountSystem) } this } override def createViewProps(aggregateId: String): Props = Props( new GeneralAggregateView[TACEvent, TACState](TACAggregate.persistenceIdBase, aggregateId, TACState.empty(), true)) }
Example 2
Source File: GeneralAggregateWithShardingTest.scala From akka-tools with MIT License | 5 votes |
package no.nextgentel.oss.akkatools.aggregate import java.util.{Arrays, UUID} import akka.actor.ActorSystem import akka.actor.Status.Failure import akka.testkit.{TestKit, TestProbe} import com.typesafe.config.ConfigFactory import no.nextgentel.oss.akkatools.aggregate.testAggregate.StateName._ import no.nextgentel.oss.akkatools.aggregate.testAggregate.{StateName, _} import no.nextgentel.oss.akkatools.testing.AggregateTesting import org.scalatest._ import org.slf4j.LoggerFactory import scala.util.Random object GeneralAggregateWithShardingTest { val port = 20000 + Random.nextInt(20000) } class GeneralAggregateWithShardingTest(_system:ActorSystem) extends TestKit(_system) with FunSuiteLike with Matchers with BeforeAndAfterAll with BeforeAndAfter { def this() = this(ActorSystem("test-actor-system", ConfigFactory.parseString( s"""akka.actor.provider = "akka.cluster.ClusterActorRefProvider" |akka.remote.enabled-transports = ["akka.remote.netty.tcp"] |akka.remote.netty.tcp.hostname="localhost" |akka.remote.netty.tcp.port=${GeneralAggregateWithShardingTest.port} |akka.cluster.seed-nodes = ["akka.tcp://test-actor-system@localhost:${GeneralAggregateWithShardingTest.port}"] """.stripMargin ).withFallback(ConfigFactory.load("application-test.conf")))) override def afterAll { TestKit.shutdownActorSystem(system) } val log = LoggerFactory.getLogger(getClass) private def generateId() = UUID.randomUUID().toString val seatIds = List("s1","id-used-in-Failed-in-onAfterValidationSuccess", "s2", "s3-This-id-is-going-to-be-discarded", "s4") trait TestEnv extends AggregateTesting[BookingState] { val id = generateId() val printShop = TestProbe() val cinema = TestProbe() val onSuccessDmForwardReceiver = TestProbe() val starter = new AggregateStarterSimple("booking", system).withAggregatePropsCreator { dmSelf => BookingAggregate.props(dmSelf, dmForwardAndConfirm(printShop.ref).path, dmForwardAndConfirm(cinema.ref).path, seatIds, dmForwardAndConfirm(onSuccessDmForwardReceiver.ref).path) } val main = starter.dispatcher starter.start() def assertState(correctState:BookingState): Unit = { assert(getState(id) == correctState) } } test("normal flow") { new TestEnv { // Make sure we start with empty state assertState(BookingState.empty()) val maxSeats = 2 val sender = TestProbe() // Open the booking println("1") sendDMBlocking(main, OpenBookingCmd(id, maxSeats), sender.ref) println("2") assertState(BookingState(OPEN, maxSeats, Set())) } } }
Example 3
Source File: LoadBalancerActor.scala From reactive-consul with MIT License | 5 votes |
package stormlantern.consul.client.loadbalancers import akka.actor.Status.Failure import akka.actor.{ Props, Actor, ActorLogging } import LoadBalancerActor._ import stormlantern.consul.client.discovery.{ ConnectionProvider, ConnectionHolder } import stormlantern.consul.client.ServiceUnavailableException import scala.concurrent.ExecutionContext.Implicits.global import scala.collection.mutable class LoadBalancerActor(loadBalancer: LoadBalancer, key: String) extends Actor with ActorLogging { import akka.pattern.pipe // Actor state val connectionProviders = mutable.Map.empty[String, ConnectionProvider] override def postStop(): Unit = { log.debug(s"LoadBalancerActor for $key stopped, destroying all connection providers") connectionProviders.values.foreach(_.destroy()) } def receive: PartialFunction[Any, Unit] = { case GetConnection ⇒ selectConnection match { case Some((id, connectionProvider)) ⇒ connectionProvider.getConnectionHolder(id, self) pipeTo sender case None ⇒ sender ! Failure(ServiceUnavailableException(key)) } case ReturnConnection(connection) ⇒ returnConnection(connection) case AddConnectionProvider(id, provider) ⇒ addConnectionProvider(id, provider) case RemoveConnectionProvider(id) ⇒ removeConnectionProvider(id) case HasAvailableConnectionProvider ⇒ sender ! connectionProviders.nonEmpty } def selectConnection: Option[(String, ConnectionProvider)] = loadBalancer.selectConnection.flatMap(id ⇒ connectionProviders.get(id).map(id → _)) def returnConnection(connection: ConnectionHolder): Unit = { connectionProviders.get(connection.id).foreach(_.returnConnection(connection)) loadBalancer.connectionReturned(connection.id) } def addConnectionProvider(id: String, provider: ConnectionProvider): Unit = { connectionProviders.put(id, provider) loadBalancer.connectionProviderAdded(id) } def removeConnectionProvider(id: String): Unit = { connectionProviders.remove(id).foreach(_.destroy()) loadBalancer.connectionProviderRemoved(id) } } object LoadBalancerActor { // Props def props(loadBalancer: LoadBalancer, key: String) = Props(new LoadBalancerActor(loadBalancer, key)) // Messsages case object GetConnection case class ReturnConnection(connection: ConnectionHolder) case class AddConnectionProvider(id: String, provider: ConnectionProvider) case class RemoveConnectionProvider(id: String) case object HasAvailableConnectionProvider }
Example 4
Source File: ServiceBrokerSpec.scala From reactive-consul with MIT License | 5 votes |
package stormlantern.consul.client import akka.actor.{ ActorRef, ActorSystem } import akka.actor.Status.Failure import akka.testkit.{ ImplicitSender, TestKit } import org.scalamock.scalatest.MockFactory import org.scalatest.concurrent.ScalaFutures import org.scalatest.{ BeforeAndAfterAll, FlatSpecLike, Matchers } import stormlantern.consul.client.dao.ConsulHttpClient import stormlantern.consul.client.discovery.ConnectionHolder import stormlantern.consul.client.helpers.CallingThreadExecutionContext import stormlantern.consul.client.loadbalancers.LoadBalancerActor import stormlantern.consul.client.util.Logging import scala.concurrent.Future class ServiceBrokerSpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with FlatSpecLike with Matchers with ScalaFutures with BeforeAndAfterAll with MockFactory with Logging { implicit val ec = CallingThreadExecutionContext() def this() = this(ActorSystem("ServiceBrokerSpec")) override def afterAll() { TestKit.shutdownActorSystem(system) } trait TestScope { val connectionHolder: ConnectionHolder = mock[ConnectionHolder] val httpClient: ConsulHttpClient = mock[ConsulHttpClient] val loadBalancer: ActorRef = self } "The ServiceBroker" should "return a service connection when requested" in new TestScope { (connectionHolder.connection _).expects().returns(Future.successful(true)) (connectionHolder.loadBalancer _).expects().returns(loadBalancer) val sut = new ServiceBroker(self, httpClient) val result: Future[Boolean] = sut.withService("service1") { service: Boolean ⇒ Future.successful(service) } expectMsgPF() { case ServiceBrokerActor.GetServiceConnection("service1") ⇒ lastSender ! connectionHolder result.map(_ shouldEqual true).futureValue } expectMsg(LoadBalancerActor.ReturnConnection(connectionHolder)) } it should "return the connection when an error occurs" in new TestScope { (connectionHolder.connection _).expects().returns(Future.successful(true)) (connectionHolder.loadBalancer _).expects().returns(loadBalancer) val sut = new ServiceBroker(self, httpClient) val result: Future[Boolean] = sut.withService[Boolean, Boolean]("service1") { service: Boolean ⇒ throw new RuntimeException() } expectMsgPF() { case ServiceBrokerActor.GetServiceConnection("service1") ⇒ lastSender ! connectionHolder an[RuntimeException] should be thrownBy result.futureValue } expectMsg(LoadBalancerActor.ReturnConnection(connectionHolder)) } it should "throw an error when an excpetion is returned" in new TestScope { val sut = new ServiceBroker(self, httpClient) val result: Future[Boolean] = sut.withService("service1") { service: Boolean ⇒ Future.successful(service) } expectMsgPF() { case ServiceBrokerActor.GetServiceConnection("service1") ⇒ lastSender ! Failure(new RuntimeException()) an[RuntimeException] should be thrownBy result.futureValue } } }
Example 5
Source File: Miner.scala From scalachain with MIT License | 5 votes |
package com.elleflorio.scalachain.actor import akka.actor.Status.{Failure, Success} import akka.actor.{Actor, ActorLogging, Props} import com.elleflorio.scalachain.actor.Miner._ import com.elleflorio.scalachain.exception.{InvalidProofException, MinerBusyException} import com.elleflorio.scalachain.proof.ProofOfWork import scala.concurrent.Future object Miner { sealed trait MinerMessage case class Validate(hash: String, proof: Long) extends MinerMessage case class Mine(hash: String) extends MinerMessage case object Ready extends MinerMessage val props: Props = Props(new Miner) } class Miner extends Actor with ActorLogging { import context._ def validate: Receive = { case Validate(hash, proof) => { log.info(s"Validating proof $proof") if (ProofOfWork.validProof(hash, proof)) { log.info("proof is valid!") sender() ! Success } else { log.info("proof is not valid") sender() ! Failure(new InvalidProofException(hash, proof)) } } } def ready: Receive = validate orElse { case Mine(hash) => { log.info(s"Mining hash $hash...") val proof = Future { ProofOfWork.proofOfWork(hash) } sender() ! proof become(busy) } case Ready => { log.info("I'm ready to mine!") sender() ! Success("OK") } } def busy: Receive = validate orElse { case Mine(_) => { log.info("I'm already mining") sender ! Failure(new MinerBusyException("Miner is busy")) } case Ready => { log.info("Ready to mine a new block") become(ready) } } override def receive: Receive = { case Ready => become(ready) } }
Example 6
Source File: PublishActor.scala From sns with Apache License 2.0 | 5 votes |
package me.snov.sns.actor import akka.actor.Status.{Failure, Success} import akka.actor.{Actor, ActorLogging, ActorRef, Props} import akka.pattern.ask import akka.pattern.pipe import akka.util.Timeout import me.snov.sns.actor.SubscribeActor.CmdFanOut import me.snov.sns.model.{Message, MessageAttribute} import scala.concurrent.ExecutionContext import scala.concurrent.duration._ object PublishActor { def props(actor: ActorRef) = Props(classOf[PublishActor], actor) case class CmdPublish(topicArn: String, bodies: Map[String, String], messageAttributes: Map[String, MessageAttribute]) } class PublishActor(subscribeActor: ActorRef) extends Actor with ActorLogging { import me.snov.sns.actor.PublishActor._ private implicit val timeout = Timeout(1.second) private implicit val ec = context.dispatcher private def publish(topicArn: String, bodies: Map[String, String], messageAttributes: Map[String, MessageAttribute])(implicit ec: ExecutionContext) = { val message = Message(bodies, messageAttributes = messageAttributes) (subscribeActor ? CmdFanOut(topicArn, message)).map { case Failure(e) => Failure(e) case Success => message } } override def receive = { case CmdPublish(topicArn, bodies, attributes) => publish(topicArn, bodies, attributes) pipeTo sender } }
Example 7
Source File: SubscribeApi.scala From sns with Apache License 2.0 | 5 votes |
package me.snov.sns.api import akka.actor.ActorRef import akka.actor.Status.{Success, Failure} import akka.http.scaladsl.model.HttpResponse import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.pattern.ask import akka.util.Timeout import me.snov.sns.actor.SubscribeActor.{CmdListSubscriptions, CmdListSubscriptionsByTopic, CmdSubscribe, CmdUnsubscribe,CmdSetSubscriptionAttributes,CmdGetSubscriptionAttributes} import me.snov.sns.model.Subscription import me.snov.sns.response.SubscribeResponse import scala.concurrent.ExecutionContext object SubscribeApi { private val arnPattern = """([\w+_:-]{1,512})""".r def route(actorRef: ActorRef)(implicit timeout: Timeout, ec: ExecutionContext): Route = { pathSingleSlash { formField('Action ! "Subscribe") { formFields('Endpoint, 'Protocol, 'TopicArn) { (endpoint, protocol, topicArn) => complete { (actorRef ? CmdSubscribe(topicArn, protocol, endpoint)).mapTo[Subscription] map { SubscribeResponse.subscribe } } } ~ complete(HttpResponse(400, entity = "Endpoint, Protocol, TopicArn are required")) } ~ formField('Action ! "ListSubscriptionsByTopic") { formField('TopicArn) { case arnPattern(topicArn) => complete { (actorRef ? CmdListSubscriptionsByTopic(topicArn)).mapTo[Iterable[Subscription]] map { SubscribeResponse.listByTopic } } case _ => complete(HttpResponse(400, entity = "Invalid topic ARN")) } ~ complete(HttpResponse(400, entity = "TopicArn is missing")) } ~ formField('Action ! "ListSubscriptions") { complete { (actorRef ? CmdListSubscriptions()).mapTo[Iterable[Subscription]] map { SubscribeResponse.list } } } ~ formField('Action ! "Unsubscribe") { formField('SubscriptionArn) { (arn) => complete { (actorRef ? CmdUnsubscribe(arn)).map { case Success => SubscribeResponse.unsubscribe case _ => HttpResponse(404, entity = "NotFound") } } } ~ complete(HttpResponse(400, entity = "SubscriptionArn is missing")) } ~ formField('Action ! "SetSubscriptionAttributes") { formField('SubscriptionArn, 'AttributeName, 'AttributeValue) { (arn, name, value) => complete { (actorRef ? CmdSetSubscriptionAttributes(arn, name, value)).map { case Success => SubscribeResponse.setSubscriptionAttributes case Failure(ex) => HttpResponse(404, entity = "NotFound") } } } ~ complete(HttpResponse(400, entity = "SubscriptionArn is missing")) } ~ formField('Action ! "GetSubscriptionAttributes") { formField('SubscriptionArn) { (arn) => complete { (actorRef ? CmdGetSubscriptionAttributes(arn)).mapTo[Option[Map[String,String]]] map { attributes => attributes .map(SubscribeResponse.getSubscriptionAttributes) .getOrElse { HttpResponse(404, entity = "Not Found") } } } } ~ complete(HttpResponse(400, entity = "SubscriptionArn is missing")) } } } }
Example 8
Source File: Register.scala From eclair with Apache License 2.0 | 5 votes |
package fr.acinq.eclair.channel import akka.actor.Status.Failure import akka.actor.{Actor, ActorLogging, ActorRef, Terminated} import fr.acinq.bitcoin.ByteVector32 import fr.acinq.bitcoin.Crypto.PublicKey import fr.acinq.eclair.ShortChannelId import fr.acinq.eclair.channel.Register._ class Register extends Actor with ActorLogging { context.system.eventStream.subscribe(self, classOf[ChannelCreated]) context.system.eventStream.subscribe(self, classOf[ChannelRestored]) context.system.eventStream.subscribe(self, classOf[ChannelIdAssigned]) context.system.eventStream.subscribe(self, classOf[ShortChannelIdAssigned]) override def receive: Receive = main(Map.empty, Map.empty, Map.empty) def main(channels: Map[ByteVector32, ActorRef], shortIds: Map[ShortChannelId, ByteVector32], channelsTo: Map[ByteVector32, PublicKey]): Receive = { case ChannelCreated(channel, _, remoteNodeId, _, temporaryChannelId, _, _) => context.watch(channel) context become main(channels + (temporaryChannelId -> channel), shortIds, channelsTo + (temporaryChannelId -> remoteNodeId)) case ChannelRestored(channel, _, remoteNodeId, _, channelId, _) => context.watch(channel) context become main(channels + (channelId -> channel), shortIds, channelsTo + (channelId -> remoteNodeId)) case ChannelIdAssigned(channel, remoteNodeId, temporaryChannelId, channelId) => context become main(channels + (channelId -> channel) - temporaryChannelId, shortIds, channelsTo + (channelId -> remoteNodeId) - temporaryChannelId) case ShortChannelIdAssigned(_, channelId, shortChannelId, _) => context become main(channels, shortIds + (shortChannelId -> channelId), channelsTo) case Terminated(actor) if channels.values.toSet.contains(actor) => val channelId = channels.find(_._2 == actor).get._1 val shortChannelId = shortIds.find(_._2 == channelId).map(_._1).getOrElse(ShortChannelId(0L)) context become main(channels - channelId, shortIds - shortChannelId, channelsTo - channelId) case Symbol("channels") => sender ! channels case Symbol("shortIds") => sender ! shortIds case Symbol("channelsTo") => sender ! channelsTo case fwd@Forward(channelId, msg) => channels.get(channelId) match { case Some(channel) => channel forward msg case None => sender ! Failure(ForwardFailure(fwd)) } case fwd@ForwardShortId(shortChannelId, msg) => shortIds.get(shortChannelId).flatMap(channels.get) match { case Some(channel) => channel forward msg case None => sender ! Failure(ForwardShortIdFailure(fwd)) } } } object Register { // @formatter:off case class Forward[T](channelId: ByteVector32, message: T) case class ForwardShortId[T](shortChannelId: ShortChannelId, message: T) case class ForwardFailure[T](fwd: Forward[T]) extends RuntimeException(s"channel ${fwd.channelId} not found") case class ForwardShortIdFailure[T](fwd: ForwardShortId[T]) extends RuntimeException(s"channel ${fwd.shortChannelId} not found") // @formatter:on }
Example 9
Source File: CheckpointTrackerActorSpec.scala From kinesis-stream with MIT License | 5 votes |
package px.kinesis.stream.consumer.checkpoint import akka.actor.Status.Failure import akka.actor.{ActorRef, ActorSystem} import akka.testkit.{ImplicitSender, TestKit} import org.scalamock.scalatest.MockFactory import org.scalatest.funspec.AnyFunSpecLike import org.scalatest.BeforeAndAfterAll import org.scalatest.matchers.must.Matchers import px.kinesis.stream.consumer.checkpoint.CheckpointTrackerActor._ import px.kinesis.stream.consumer.checkpoint.{ShardCheckpointTrackerActor => shard} import software.amazon.kinesis.retrieval.kpl.ExtendedSequenceNumber import scala.collection.immutable.Seq class CheckpointTrackerActorSpec extends TestKit(ActorSystem("CheckpointTrackerActorSpec")) with ImplicitSender with AnyFunSpecLike with Matchers with BeforeAndAfterAll with MockFactory { override def afterAll: Unit = { TestKit.shutdownActorSystem(system) } val workerId = "123" def toSequenceNum(i: Int): ExtendedSequenceNumber = new ExtendedSequenceNumber(i.toString) def createTracker(): ActorRef = system.actorOf( CheckpointTrackerActor .props(workerId, 10, 10)) describe("track") { it("should track successfully after creation of tracker") { val tracker = createTracker() val shardId = "01" tracker ! Command.Create(shardId) expectMsg(Response.Ack) tracker ! Command.Track(shardId, Seq(1).map(toSequenceNum)) expectMsg(shard.Response.Ack) } it("should fail if tracker is not active") { val tracker = createTracker() val shardId = "01" // shard tracker for 01 does not exist tracker ! Command.Track(shardId, Seq(1).map(toSequenceNum)) expectMsgPF() { case Failure(_) => true } } } describe("process") { it("should process successfully after creation of tracker") { val tracker = createTracker() val shardId = "01" tracker ! Command.Create(shardId) expectMsg(Response.Ack) tracker ! Command.Process(shardId, toSequenceNum(1)) expectMsg(shard.Response.Ack) } it("should process successfully even after shard tracker is shutdown") { val tracker = createTracker() val shardId = "01" tracker ! Command.Create(shardId) expectMsg(Response.Ack) tracker ! Command.Process(shardId, toSequenceNum(1)) expectMsg(shard.Response.Ack) tracker ! Command.ShutdownShard(shardId) expectMsg(Response.Ack) tracker ! Command.Process(shardId, toSequenceNum(2)) expectMsg(shard.Response.Ack) } } }
Example 10
Source File: ConsumerCommitter.scala From reactive-nakadi with MIT License | 5 votes |
package org.zalando.react.nakadi.commit import akka.actor._ import akka.actor.Status.Failure import org.zalando.react.nakadi.properties.ConsumerProperties import org.zalando.react.nakadi.NakadiActorPublisher.{CommitAck, CommitOffsets} import org.zalando.react.nakadi.NakadiMessages.ConsumerMessage object ConsumerCommitter { object Contract { object TheEnd object Flush } def props(consumerActor: ActorRef, consumerProperties: ConsumerProperties) = { Props(new ConsumerCommitter(consumerActor, consumerProperties)) } } class ConsumerCommitter(consumerActor: ActorRef, consumerProperties: ConsumerProperties) extends Actor with ActorLogging { import ConsumerCommitter.Contract._ val eventType = consumerProperties.eventType val commitInterval = consumerProperties.commitInterval var scheduledFlush: Option[Cancellable] = None var partitionOffsetMap = OffsetMap() var committedOffsetMap = OffsetMap() implicit val executionContext = context.dispatcher def scheduleFlush(): Unit = { if (scheduledFlush.isEmpty) { scheduledFlush = Option(context.system.scheduler.scheduleOnce(commitInterval, self, Flush)) } } override def preStart(): Unit = { context.watch(consumerActor) super.preStart() } override def postStop(): Unit = { scheduledFlush.foreach(_.cancel()) super.postStop() } override def receive: Receive = { case msg: ConsumerMessage => registerCommit(msg) case CommitAck(offsetMap) => handleAcknowledge(offsetMap) case Flush => commitGatheredOffsets() case TheEnd => log.debug("Closing Consumer connection") context.stop(self) case Failure => log.error("Closing offset committer due to a failure") context.stop(self) case Terminated(_) => log.warning("Terminating the consumer committer due to the death of the consumer actor.") context.stop(self) } def registerCommit(msg: ConsumerMessage): Unit = { log.debug(s"Received commit request for partition ${msg.cursor.partition} and offset ${msg.cursor.offset}") val eventTypePartition = EventTypePartition(msg.eventType, msg.cursor.partition) val last = partitionOffsetMap.lastOffset(eventTypePartition) updateOffsetIfLarger(msg, last) } def updateOffsetIfLarger(msg: ConsumerMessage, last: Long): Unit = { val msgOffset = msg.cursor.offset.toLong if (msgOffset > last) { log.debug(s"Registering commit for partition ${msg.cursor.partition} and offset ${msg.cursor.offset}, last registered = $last") val eventTypePartition = EventTypePartition(msg.eventType, msg.cursor.partition) partitionOffsetMap = partitionOffsetMap.plusOffset(eventTypePartition, msgOffset) scheduleFlush() } else { log.debug(s"Skipping commit for partition ${msg.cursor.partition} and offset ${msg.cursor.offset}, last registered is $last") } } def handleAcknowledge(offsetMap: OffsetMap) = committedOffsetMap = OffsetMap(offsetMap.map.mapValues(_ - 1)) def commitGatheredOffsets() = { log.debug("Flushing offsets to commit") scheduledFlush = None val offsetMapToFlush = partitionOffsetMap diff committedOffsetMap if (offsetMapToFlush.nonEmpty) { consumerActor ! CommitOffsets(offsetMapToFlush) } } }
Example 11
Source File: TransactionalProducer.scala From affinity with Apache License 2.0 | 5 votes |
package io.amient.affinity.kafka import java.util.Properties import akka.actor.Actor import akka.actor.Status.{Failure, Success} import akka.event.Logging import com.typesafe.config.Config import io.amient.affinity.Conf import io.amient.affinity.core.actor.{TransactionAbort, TransactionBegin, TransactionCommit, TransactionalRecord} import io.amient.affinity.core.config.CfgStruct import io.amient.affinity.core.storage.StorageConf import io.amient.affinity.kafka.KafkaStorage.{KafkaConsumerConf, KafkaProducerConf} import org.apache.kafka.clients.producer.{Callback, KafkaProducer, ProducerRecord, RecordMetadata} import org.apache.kafka.common.serialization.ByteArraySerializer import scala.collection.JavaConverters._ object KafkaConf extends KafkaConf { override def apply(config: Config): KafkaConf = new KafkaConf().apply(config) } class KafkaConf extends CfgStruct[KafkaConf](classOf[StorageConf]) { val BootstrapServers = string("kafka.bootstrap.servers", true).doc("kafka connection string used for consumer and/or producer") val Producer = struct("kafka.producer", new KafkaProducerConf, false).doc("any settings that the underlying version of kafka producer client supports") val Consumer = struct("kafka.consumer", new KafkaConsumerConf, false).doc("any settings that the underlying version of kafka consumer client supports") } class TransactionalProducer extends Actor { val logger = Logging.getLogger(context.system, this) private[this] var producer: KafkaProducer[Array[Byte], Array[Byte]] = null val kafkaConf = KafkaConf(Conf(context.system.settings.config).Affi.Storage) val producerConfig = new Properties() { if (kafkaConf.Producer.isDefined) { val producerConfig = kafkaConf.Producer.toMap() if (producerConfig.containsKey("bootstrap.servers")) throw new IllegalArgumentException("bootstrap.servers cannot be overriden for KafkaStroage producer") if (producerConfig.containsKey("key.serializer")) throw new IllegalArgumentException("Binary kafka stream cannot use custom key.serializer") if (producerConfig.containsKey("value.serializer")) throw new IllegalArgumentException("Binary kafka stream cannot use custom value.serializer") producerConfig.entrySet.asScala.filter(_.getValue.isDefined).foreach { case (entry) => put(entry.getKey, entry.getValue.apply.toString) } } put("bootstrap.servers", kafkaConf.BootstrapServers()) put("value.serializer", classOf[ByteArraySerializer].getName) put("key.serializer", classOf[ByteArraySerializer].getName) } override def receive: Receive = { case req@TransactionBegin(transactionalId) => req(sender) ! { if (producer == null) { producerConfig.put("transactional.id", transactionalId) producer = new KafkaProducer[Array[Byte], Array[Byte]](producerConfig) logger.debug(s"Transactions.Init(transactional.id = $transactionalId)") producer.initTransactions() } logger.debug("Transactions.Begin()") producer.beginTransaction() } case TransactionalRecord(topic, key, value, timestamp, partition) => val replyto = sender val producerRecord = new ProducerRecord( topic, partition.map(new Integer(_)).getOrElse(null), timestamp.map(new java.lang.Long(_)).getOrElse(null), key, value) logger.debug(s"Transactions.Append(topic=$topic)") producer.send(producerRecord, new Callback { override def onCompletion(metadata: RecordMetadata, exception: Exception): Unit = { if (exception != null) { replyto ! Failure(exception) } else { replyto ! Success(metadata.offset()) } } }) case req@TransactionCommit() => req(sender) ! { logger.debug("Transactions.Commit()") producer.commitTransaction() } case req@TransactionAbort() => req(sender) ! { logger.debug("Transactions.Abort()") producer.abortTransaction() } } }
Example 12
Source File: JobStatusActor.scala From asura with MIT License | 5 votes |
package asura.core.job.actor import akka.actor.Status.Failure import akka.actor.{ActorRef, Props} import asura.common.actor._ import asura.common.model.Pagination import asura.core.model.QueryJob import asura.core.es.service.JobService import asura.core.job.actor.JobStatusMonitorActor.JobStatusOperationMessage import asura.core.job.eventbus.JobStatusBus.JobStatusNotificationMessage import asura.core.job.{JobListItem, JobStates} import asura.core.redis.RedisJobState import asura.core.util.JacksonSupport import com.typesafe.scalalogging.Logger import scala.collection.mutable import scala.collection.mutable.ArrayBuffer class JobStatusActor() extends BaseActor { var query: QueryJob = null val watchIds = mutable.HashSet[String]() override def receive: Receive = { case SenderMessage(sender) => context.become(query(sender)) } def query(outSender: ActorRef): Receive = { case query: QueryJob => this.query = query JobService.queryJob(query).map(esResponse => if (esResponse.isSuccess) { val items = ArrayBuffer[JobListItem]() val jobsTable = mutable.HashMap[String, JobListItem]() val hits = esResponse.result.hits watchIds.clear() hits.hits.foreach(hit => { val jobId = hit.id watchIds.add(jobId) jobsTable += (jobId -> { val item = JacksonSupport.parse(hit.sourceAsString, classOf[JobListItem]) item.state = JobStates.UNKNOWN items += item item._id = jobId item }) }) if (watchIds.nonEmpty) { RedisJobState.getJobState(watchIds.toSet).onComplete { case util.Success(statesMap) => statesMap.forEach((jobKey, state) => jobsTable(jobKey).state = state) outSender ! ListActorEvent(Map("total" -> hits.total, "list" -> items)) case util.Failure(_) => outSender ! ListActorEvent(Map("total" -> hits.total, "list" -> items)) }(context.system.dispatcher) } else { outSender ! ListActorEvent(Map("total" -> 0, "list" -> Nil)) } } else { outSender ! ErrorActorEvent(esResponse.error.reason) })(context.system.dispatcher) case JobStatusNotificationMessage(_, operator, scheduler, group, name, data) => if (watchIds.contains(name)) { outSender ! ItemActorEvent(JobStatusOperationMessage(operator, scheduler, group, name, data)) } case eventMessage: ActorEvent => outSender ! eventMessage case Failure(t) => outSender ! ErrorActorEvent(t.getMessage) } override def postStop(): Unit = { import JobStatusActor.logger logger.debug(s"JobStatus for ${query} stopped") } } object JobStatusActor { val logger = Logger(classOf[JobStatusActor]) def props() = Props(new JobStatusActor()) case class JobQueryMessage(scheduler: String = null, group: String = null, text: String = null) extends Pagination }
Example 13
Source File: BankAccountTest.scala From reactive-programming with Apache License 2.0 | 5 votes |
package com.test.week5 import akka.actor.Status.Failure import akka.actor.{ Actor, ActorRef, Props } import akka.event.LoggingReceive import akka.pattern.ask import com.test.TestSpec class BankAccountTest extends TestSpec { "Actors" should "know itself" in { val ref: ActorRef = system.actorOf(Props(new Actor { override def receive: Receive = { case _ ⇒ sender() ! self } })) (ref ? "").futureValue shouldBe ref cleanup(ref) } it should "count" in { val ref: ActorRef = system.actorOf(Props(new Actor { def count(num: Int): Receive = LoggingReceive { case _ ⇒ context.become(count(num + 1)) sender() ! num } override def receive: Receive = LoggingReceive(count(0)) })) (ref ? "").futureValue shouldBe 0 (ref ? "").futureValue shouldBe 1 (ref ? "").futureValue shouldBe 2 (ref ? "").futureValue shouldBe 3 cleanup(ref) } it should "be a BankAccount" in { object BankAccount { case class Transfer(from: ActorRef, to: ActorRef, amount: BigInt) case class Deposit(amount: BigInt) case class Withdraw(amount: BigInt) case object Info case class Done(amount: BigInt) case object Failed } class BankAccount extends Actor { import BankAccount._ var balance: BigInt = BigInt(0) override def receive: Receive = LoggingReceive { case Deposit(amount) ⇒ balance += amount sender() ! Done(balance) case Withdraw(amount) ⇒ balance -= amount sender() ! Done(balance) case Info ⇒ sender() ! Done(balance) case _ ⇒ sender() ! Failure } } import BankAccount._ val account1 = system.actorOf(Props(new BankAccount)) (account1 ? Info).futureValue shouldBe Done(0) (account1 ? Deposit(100)).futureValue shouldBe Done(100) (account1 ? Deposit(100)).futureValue shouldBe Done(200) val account2 = system.actorOf(Props(new BankAccount)) val tom = system.actorOf(Props(new Actor { def awaitDeposit(client: ActorRef): Receive = LoggingReceive { case Done(amount) ⇒ client ! Done(amount) context.stop(self) } def awaitWithdraw(to: ActorRef, amount: BigInt, client: ActorRef): Receive = LoggingReceive { case Done(_) ⇒ to ! Deposit(amount) context.become(awaitDeposit(client)) case Failed ⇒ client ! Failed context.stop(self) } override def receive = { case Transfer(from, to, amount) ⇒ from ! Withdraw(amount) context.become(awaitWithdraw(to, amount, sender())) } })) (tom ? Transfer(account1, account2, 50)).futureValue shouldBe Done(50) (account1 ? Info).futureValue shouldBe Done(150) (account2 ? Info).futureValue shouldBe Done(50) cleanup(account1, account2, tom) } }