akka.actor.Scheduler Scala Examples
The following examples show how to use akka.actor.Scheduler.
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: StatusCheckerModule.scala From CloudGenesis with Apache License 2.0 | 5 votes |
package com.lifeway.cloudops.cloudformation import akka.actor.{ActorSystem, Scheduler} import com.amazonaws.services.cloudformation.AmazonCloudFormation import scala.concurrent.{Await, ExecutionContext, Future} import scala.concurrent.duration._ import akka.pattern.after import com.amazonaws.AmazonServiceException import com.lifeway.cloudops.cloudformation.Types.StackName import org.scalactic._ import org.slf4j.Logger trait StatusCheckerModule { val logger: Logger def waitForStatus( actorSystem: ActorSystem, maxRetries: Int = 100, maxWaitTime: Duration = 5.minutes, retrySpeed: FiniteDuration = 3.seconds)(statusFetcher: (AmazonCloudFormation, String) => (String, String))( cfClient: AmazonCloudFormation, id: String, stackName: StackName, waitForStatus: Types.Status, failIfInStatus: Seq[Types.Status]): Unit Or AutomationError = { implicit val ec: ExecutionContext = actorSystem.dispatcher implicit val sch: Scheduler = actorSystem.scheduler sealed trait StatusException extends Exception case object PendingException extends StatusException case class FailedException(msg: String) extends StatusException def checkStatus: Unit = { val (status, reason) = statusFetcher(cfClient, id) if (status == waitForStatus) () else if (failIfInStatus.contains(status)) throw new FailedException(s"Unexpected stack status: $status. Reason: $reason") else throw PendingException } def retry(op: => Unit, delay: FiniteDuration, retries: Int): Future[Unit Or AutomationError] = Future(op).map(x => Good(x)) recoverWith { case PendingException if retries > 0 => after(delay, sch)(retry(op, delay, retries - 1)) case FailedException(err) => Future.successful( Bad(StackError(s"Failed to reach expected status of $waitForStatus for $stackName due to: $err"))) case t: AmazonServiceException if t.getStatusCode >= 500 => logger.error(s"AWS 500 Service Exception: Failed to reach expected status of $waitForStatus for $stackName", t) Future.successful( Bad(ServiceError( s"AWS 500 Service Exception: Failed to reach expected status of $waitForStatus for $stackName"))) case _ => Future.successful(Bad(StackError(s"Failed to reach expected status of $waitForStatus for $stackName"))) } //Retry to find final status for up to max time... try { Await.result(retry(checkStatus, retrySpeed, maxRetries), maxWaitTime) } catch { case _: Throwable => Bad( StackError( s"Failed to wait to reach expected status of $waitForStatus for $stackName due to process timeout")) } } }
Example 2
Source File: Api.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.{ ActorSystem, Scheduler } import akka.http.scaladsl.Http import akka.http.scaladsl.Http.ServerBinding import akka.http.scaladsl.model.StatusCodes.{ Conflict, Created, NoContent, NotFound } import akka.http.scaladsl.server.{ Directives, Route } import akka.stream.Materializer import akka.actor.typed.scaladsl.Actor import akka.actor.typed.scaladsl.AskPattern.Askable import akka.actor.typed.{ ActorRef, Behavior } import akka.util.Timeout import de.heikoseeberger.akkahttpcirce.ErrorAccumulatingCirceSupport import java.net.InetSocketAddress import org.apache.logging.log4j.scala.Logging import scala.concurrent.duration.FiniteDuration import scala.util.{ Failure, Success } object Api extends Logging { sealed trait Command private final case object HandleBindFailure extends Command private final case class HandleBound(address: InetSocketAddress) extends Command final val Name = "api" def apply(address: String, port: Int, userRepository: ActorRef[UserRepository.Command], userView: ActorRef[UserView.Command], askTimeout: FiniteDuration)(implicit mat: Materializer): Behavior[Command] = Actor.deferred { context => import akka.actor.typed.scaladsl.adapter._ import context.executionContext implicit val s: ActorSystem = context.system.toUntyped val self = context.self Http() .bindAndHandle(route(userRepository, userView)(askTimeout, context.system.scheduler), address, port) .onComplete { case Failure(_) => self ! HandleBindFailure case Success(ServerBinding(address)) => self ! HandleBound(address) } Actor.immutable { case (_, HandleBindFailure) => logger.error(s"Stopping, because cannot bind to $address:$port!") Actor.stopped case (_, HandleBound(address)) => logger.info(s"Bound to $address") Actor.ignore } } def route( userRepository: ActorRef[UserRepository.Command], userView: ActorRef[UserView.Command] )(implicit askTimeout: Timeout, scheduler: Scheduler): Route = { import Directives._ import ErrorAccumulatingCirceSupport._ import io.circe.generic.auto._ import io.circe.refined._ pathEndOrSingleSlash { get { complete { import UserView._ (userView ? GetUsers).mapTo[Users] } } ~ post { entity(as[User]) { user => import UserRepository._ onSuccess(userRepository ? addUser(user)) { case UsernameTaken(_) => complete(Conflict) case UserAdded(_) => complete(Created) } } } } ~ path(Segment) { username => delete { import UserRepository._ onSuccess(userRepository ? removeUser(username)) { case UsernameUnknown(_) => complete(NotFound) case UserRemoved(_) => complete(NoContent) } } } } }
Example 3
Source File: UserProjection.scala From whirlwind-tour-akka-typed with Apache License 2.0 | 5 votes |
package de.heikoseeberger.wtat import akka.actor.Scheduler import akka.actor.typed.{ ActorRef, Behavior } import akka.actor.typed.scaladsl.Actor import akka.actor.typed.scaladsl.AskPattern.Askable import akka.cluster.Cluster import akka.cluster.ddata.{ ORSet, ORSetKey } import akka.cluster.ddata.Replicator.WriteLocal import akka.cluster.ddata.typed.scaladsl.{ DistributedData, Replicator } import akka.persistence.query.EventEnvelope import akka.persistence.query.scaladsl.EventsByPersistenceIdQuery import akka.stream.Materializer import akka.stream.scaladsl.Sink import akka.util.Timeout import cats.instances.string._ import cats.syntax.eq._ import org.apache.logging.log4j.scala.Logging import scala.concurrent.duration.FiniteDuration object UserProjection extends Logging { import akka.actor.typed.scaladsl.adapter._ sealed trait Command final case object Stop extends Command private final case object HandleEventStreamComplete extends Command abstract class EventStreamCompleteException extends IllegalStateException("Event stream completed unexpectedly!") private final case object EventStreamCompleteException extends EventStreamCompleteException final val Name = "user-projection" final val usersKey: ORSetKey[User] = ORSetKey("users") def apply(readJournal: EventsByPersistenceIdQuery, userView: ActorRef[UserView.Command], askTimeout: FiniteDuration)(implicit mat: Materializer): Behavior[Command] = Actor.deferred { context => implicit val c: Cluster = Cluster(context.system.toUntyped) implicit val s: Scheduler = context.system.scheduler implicit val t: Timeout = askTimeout val replicator = DistributedData(context.system).replicator val self = context.self readJournal .eventsByPersistenceId(UserRepository.Name, 0, Long.MaxValue) .collect { case EventEnvelope(_, _, _, event: UserRepository.Event) => event } .mapAsync(1) { case UserRepository.UserAdded(user) => replicator ? Replicator.Update(usersKey, ORSet.empty[User], WriteLocal)(_ + user) case UserRepository.UserRemoved(username) => replicator ? Replicator.Update(usersKey, ORSet.empty[User], WriteLocal) { users => users.elements.find(_.username.value === username).fold(users)(users - _) } } .runWith(Sink.onComplete(_ => self ! HandleEventStreamComplete)) logger.debug("Running event stream") Actor.immutable { case (_, Stop) => Actor.stopped case (_, HandleEventStreamComplete) => throw EventStreamCompleteException } } }
Example 4
Source File: QueriesAkkaHttpResource.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.akka import akka.actor.Scheduler import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.AskPattern._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.util.Timeout import com.lightbend.modelserving.model.ModelToServeStats import de.heikoseeberger.akkahttpjackson.JacksonSupport import scala.concurrent.duration._ object QueriesAkkaHttpResource extends JacksonSupport { implicit val askTimeout = Timeout(30.seconds) def storeRoutes(modelserver: ActorRef[ModelServerManagerActor])(implicit scheduler: Scheduler) : Route = get { // Get list of models path("processors") { onSuccess(modelserver ? ((replyTo: ActorRef[GetModelsResult]) => GetModels(replyTo))) { case models: GetModelsResult => complete(models) } } ~ // Get statistics for a given data type path("state"/Segment) { dataType => onSuccess(modelserver ? ((replyTo: ActorRef[ModelToServeStats]) => GetState(replyTo, dataType))) { case stats : ModelToServeStats => complete(stats) } } } }
Example 5
Source File: TFQueriesAkkaHttpResource.scala From model-serving-tutorial with Apache License 2.0 | 5 votes |
package com.lightbend.modelserving.tensorflowserving import akka.actor.Scheduler import akka.actor.typed.ActorRef import akka.actor.typed.scaladsl.AskPattern._ import akka.http.scaladsl.server.Directives._ import akka.http.scaladsl.server.Route import akka.util.Timeout import com.lightbend.modelserving.model.ModelToServeStats import de.heikoseeberger.akkahttpjackson.JacksonSupport import scala.concurrent.duration._ object TFQueriesAkkaHttpResource extends JacksonSupport { implicit val askTimeout = Timeout(30.seconds) def storeRoutes(modelserver: ActorRef[TFModelServerActor])(implicit scheduler: Scheduler) : Route = get { // Get statistics path("state") { onSuccess(modelserver ? ((replyTo: ActorRef[ModelToServeStats]) => GetState(replyTo))) { case stats : ModelToServeStats => complete(stats) } } } }
Example 6
Source File: AkkaSuite.scala From streamee with Apache License 2.0 | 5 votes |
package io.moia.streamee import akka.actor.{ ActorSystem, Scheduler } import org.scalatest.{ BeforeAndAfterAll, Suite } import scala.concurrent.Await import scala.concurrent.duration.DurationInt trait AkkaSuite extends Suite with BeforeAndAfterAll { protected implicit val system: ActorSystem = ActorSystem() protected implicit val scheduler: Scheduler = system.scheduler override protected def afterAll(): Unit = { Await.ready(system.terminate(), 42.seconds) super.afterAll() } }
Example 7
Source File: Retriable.scala From vamp with Apache License 2.0 | 5 votes |
package io.vamp.container_driver.kubernetes import akka.actor.Scheduler import akka.pattern.after import scala.concurrent.{ ExecutionContext, Future } import scala.concurrent.duration.FiniteDuration trait Retriable { def retryIndefinitely[T](op: ⇒ T, delay: FiniteDuration)(implicit ec: ExecutionContext, s: Scheduler): Future[T] = Future(op) recoverWith { case _ ⇒ after(delay, s)(retryIndefinitely(op, delay)) } def retryWithLimit[T](op: ⇒ T, delay: FiniteDuration, iteration: Int, limit: Int)(implicit ec: ExecutionContext, s: Scheduler): Future[T] = Future(op) recoverWith { case _ ⇒ if (iteration < limit) after(delay * iteration, s)(retryWithLimit(op, delay, iteration + 1, limit)) else Future.failed(new Exception("Give up on retrial")) } }
Example 8
Source File: SimulatedScheduler.scala From metronome with Apache License 2.0 | 5 votes |
package dcos.metronome import akka.actor.{Cancellable, Scheduler} import java.util.concurrent.atomic.AtomicLong import scala.concurrent.ExecutionContext import scala.concurrent.duration.FiniteDuration class SimulatedScheduler(clock: SettableClock) extends Scheduler { override def maxFrequency = 0.0 private[this] val nextId = new AtomicLong private[this] val scheduledTasks = scala.collection.mutable.Map.empty[Long, ScheduledTask] private case class ScheduledTask(action: () => Unit, var time: Long) private class ScheduledTaskCancellable(id: Long) extends Cancellable { override def cancel() = { doCancel(id) true } override def isCancelled = scheduledTasks.contains(id) } clock.onChange { () => poll() } private[this] def doCancel(id: Long) = synchronized { scheduledTasks -= id } private[this] def poll(): Unit = synchronized { val now = clock.instant().toEpochMilli scheduledTasks.values.foreach { task => if (task.time <= now) task.action() } } override def scheduleOnce(delay: FiniteDuration, runnable: Runnable)(implicit executor: ExecutionContext ): Cancellable = synchronized { val id = nextId.getAndIncrement val cancellable = new ScheduledTaskCancellable(id) scheduledTasks(id) = ScheduledTask( time = clock.instant().plusMillis(delay.toMillis).toEpochMilli, action = () => { cancellable.cancel() executor.execute(runnable) } ) poll() cancellable } def schedule(initialDelay: FiniteDuration, interval: FiniteDuration, runnable: Runnable)(implicit executor: ExecutionContext ): Cancellable = synchronized { val id = nextId.getAndIncrement val cancellable = new ScheduledTaskCancellable(id) scheduledTasks(id) = ScheduledTask( time = clock.instant().toEpochMilli + initialDelay.toMillis, action = () => { scheduledTasks(id).time = clock.instant().toEpochMilli + interval.toMillis executor.execute(runnable) } ) poll() cancellable } def taskCount = synchronized { scheduledTasks.size } }
Example 9
Source File: FutureRetryUtilitySpec.scala From NSDb with Apache License 2.0 | 5 votes |
package io.radicalbit.nsdb.util import akka.actor.{ActorSystem, Scheduler, Status} import akka.event.{Logging, LoggingAdapter} import akka.testkit.{TestKit, TestProbe} import org.scalatest.{Matchers, WordSpecLike} import scala.collection.mutable import scala.concurrent.duration._ import scala.concurrent.{Await, Future} import scala.concurrent.ExecutionContext.Implicits.global class FutureRetryUtilitySpec extends TestKit(ActorSystem("MySpec")) with WordSpecLike with Matchers with FutureRetryUtility { implicit val schedule: Scheduler = system.scheduler implicit val logger: LoggingAdapter = Logging.getLogger(system, this) private final val delay: FiniteDuration = 2.seconds private final val retries: Int = 3 private def future(flag: Boolean) = if (flag) Future.successful(3) else Future.failed(new RuntimeException("Failure")) "retry function in FutureRetryUtility" must { "successfully returns whether, after retries, the future is eventually successful" in { Await.result(future(true).retry(delay, retries)(_ > 2), Duration.Inf) shouldBe 3 } "thrown an Exception whether, after retries, the future eventually returns an Exception" in { an[RuntimeException] shouldBe thrownBy(Await.result(future(false).retry(delay, retries)(_ => true), Duration.Inf)) } "consider the number of retries" in { val q = mutable.Queue(0) def future = { val nRetries = q.dequeue() if (nRetries < 2) { q.enqueue(nRetries + 1); Future.failed(new RuntimeException) } else { q.enqueue(nRetries + 1); Future.successful(nRetries) } } Await.result(future.retry(delay, retries)(_ > 2), Duration.Inf) shouldBe 3 } } "pipeTo function in FutureRetryUtility" must { "returns a successful future and send the content of it through pipe" in { val testProbe = TestProbe("actor-test") future(true).pipeTo(delay, retries, testProbe.testActor)() testProbe.expectMsg(3) } "return a failed future and send a status failure through pipe" in { val testProbe = TestProbe("actor-test") future(false).pipeTo(delay, retries, testProbe.testActor)() testProbe.expectMsgAllClassOf(classOf[Status.Failure]) } } }
Example 10
Source File: FutureRetryUtility.scala From NSDb with Apache License 2.0 | 5 votes |
package io.radicalbit.nsdb.util import akka.actor.{Actor, ActorRef, Scheduler, Status} import akka.event.LoggingAdapter import akka.pattern.after import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success} trait FutureRetryUtility { implicit class FutureRetry[T](f: => Future[T]) { def retry(delay: FiniteDuration, retries: Int)( wasSuccessful: T => Boolean)(implicit ec: ExecutionContext, s: Scheduler, log: LoggingAdapter): Future[T] = (for { a <- f result <- if (wasSuccessful(a) || retries < 1) Future(a) else { log.warning("{}. Retrying...", a); after(delay, s)(retry(delay, retries - 1)(wasSuccessful)) } } yield result) recoverWith { case t if retries > 0 => log.warning("{}. Retrying...", t); after(delay, s)(retry(delay, retries - 1)(wasSuccessful)) } } implicit class PipeToFutureRetry[T](f: => Future[T]) { def pipeTo(delay: FiniteDuration, retries: Int, recipient: ActorRef)(wasSuccessful: T => Boolean = _ => true)( implicit ec: ExecutionContext, s: Scheduler, log: LoggingAdapter, sender: ActorRef = Actor.noSender) = f.retry(delay, retries)(wasSuccessful) andThen { case Success(r) ⇒ recipient ! r case Failure(f) ⇒ recipient ! Status.Failure(f) } } }
Example 11
Source File: PingActorSpec.scala From akka-typed-persistence with Apache License 2.0 | 5 votes |
package com.example import scala.concurrent.duration._ import org.scalatest.{ FlatSpecLike, Matchers } import org.scalatest.concurrent.ScalaFutures import akka.actor.ActorSystem import akka.actor.Scheduler import akka.testkit.TestKit import akka.typed.ActorRef import akka.typed.scaladsl.AskPattern._ import akka.typed.scaladsl.adapter.actorRefAdapter import akka.util.Timeout class PingActorSpec extends TestKit(ActorSystem("pingSystem")) with FlatSpecLike with Matchers with ScalaFutures { import PingActor.MyMsg implicit val timeout: Timeout = Timeout(1.second) implicit val scheduler: Scheduler = this.system.scheduler implicit override def patienceConfig: PatienceConfig = PatienceConfig(timeout = super.patienceConfig.timeout * 5) val dummyRef: ActorRef[Any] = actorRefAdapter(this.testActor) "PingActor" should "reply with the number of pings it received so far" in { val ref: ActorRef[MyMsg] = PingActor.myBehavior.deployInto(this.system, "pingActor") ref.?[String](MyMsg("ping", _)).futureValue should be ("1 pings so far") ref ! MyMsg("foo", dummyRef) this.expectNoMsg() ref ! MyMsg("bar", dummyRef) this.expectNoMsg() ref.?[String](MyMsg("ping", _)).futureValue should be ("2 pings so far") ref.?[String](MyMsg("stop", _)).futureValue should be ("OK") val ref2: ActorRef[MyMsg] = PingActor.myBehavior.deployInto(this.system, "pingActor") ref2.?[String](MyMsg("ping", _)).futureValue should be ("3 pings so far") } }
Example 12
Source File: FutureRetries.scala From HAT2.0 with GNU Affero General Public License v3.0 | 5 votes |
package org.hatdex.hat.utils import akka.actor.Scheduler import akka.pattern.after import scala.concurrent.duration._ import scala.concurrent.{ ExecutionContext, Future } import scala.util.Random object FutureRetries { def retry[T](f: => Future[T], delays: List[FiniteDuration])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { f recoverWith { case _ if delays.nonEmpty => after(delays.head, s)(retry(f, delays.tail)) } } def withDefault(delays: List[FiniteDuration], retries: Int, default: FiniteDuration): List[FiniteDuration] = { if (delays.length > retries) { delays take retries } else { delays ++ List.fill(retries - delays.length)(default) } } def withJitter(delays: List[FiniteDuration], maxJitter: Double, minJitter: Double): List[FiniteDuration] = { delays.map { delay => val jitter = delay * (minJitter + (maxJitter - minJitter) * Random.nextDouble) jitter match { case d: FiniteDuration => d case _ => delay } } } val fibonacci: Stream[FiniteDuration] = 0.seconds #:: 1.seconds #:: (fibonacci zip fibonacci.tail).map { t => t._1 + t._2 } }
Example 13
Source File: MultiNodeExpect.scala From lagom with Apache License 2.0 | 5 votes |
package com.lightbend.lagom.internal.cluster import akka.Done import akka.actor.ActorRef import akka.actor.ActorSystem import akka.actor.Scheduler import akka.annotation.ApiMayChange import akka.cluster.ddata.DistributedData import akka.cluster.ddata.Flag import akka.cluster.ddata.FlagKey import akka.cluster.ddata.Replicator.Get import akka.cluster.ddata.Replicator.GetSuccess import akka.cluster.ddata.Replicator.ReadLocal import akka.cluster.ddata.Replicator.Update import akka.cluster.ddata.Replicator.UpdateSuccess import akka.cluster.ddata.Replicator.WriteAll import akka.cluster.ddata.Replicator.WriteConsistency import akka.cluster.ddata.SelfUniqueAddress import akka.event.LoggingAdapter import akka.testkit.TestProbe import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.concurrent.duration._ import scala.reflect.ClassTag import akka.pattern.after import akka.pattern.ask import akka.util.Timeout import scala.util.control.NonFatal @ApiMayChange class MultiNodeExpect(probe: TestProbe)(implicit system: ActorSystem) { private implicit val scheduler: Scheduler = system.scheduler private implicit val executionContext: ExecutionContext = system.dispatcher val replicator: ActorRef = DistributedData(system).replicator implicit val node: SelfUniqueAddress = DistributedData(system).selfUniqueAddress def expectMsgType[T](expectationKey: String, max: FiniteDuration)(implicit t: ClassTag[T]): Future[Done] = { val eventualT = () => Future(errorAsRuntime(probe.expectMsgType[T](max))) doExpect(eventualT)(expectationKey, max) } // prevents Errors from turning into BoxedError when using `Future(f)` (where f throws Error) private def errorAsRuntime[T](f: => T): T = { try { f } catch { case NonFatal(t) => throw t case x: Throwable => throw new RuntimeException(x) } } private def doExpect[T](eventualT: () => Future[T])(expectationKey: String, max: FiniteDuration): Future[Done] = { val DataKey: FlagKey = FlagKey(expectationKey) val writeAll: WriteConsistency = WriteAll(max) implicit val timeout: Timeout = Timeout(max) val retryDelay = 3.second val fTimeout = after(max, scheduler)(Future.failed(new RuntimeException(s"timeout $max expired"))) // If the local expectation wins, it must notify others. val fLocalExpect: Future[Done] = eventualT() .map { _ => (replicator ? Update(DataKey, Flag.empty, writeAll)( _.switchOn )).mapTo[UpdateSuccess[Flag]] } .map(_ => Done) // if a remote expectation wins, we can move on. val poll: () => Future[Done] = () => (replicator ? Get(DataKey, ReadLocal)).map { case g @ GetSuccess(DataKey, _) if g.get(DataKey).enabled => Done case _ => throw new RuntimeException("Flag unset") } val fRemoteExpect: Future[Done] = retry( poll, retryDelay, Int.MaxValue // keep retrying, there's a timeout later ) Future .firstCompletedOf( Seq( fLocalExpect, fRemoteExpect, fTimeout ) ) } // From vklang's https://gist.github.com/viktorklang/9414163 def retry[T](op: () => Future[T], delay: FiniteDuration, retries: Int): Future[T] = op().recoverWith { case _ if retries > 0 => after(delay, scheduler)(retry(op, delay, retries - 1)) } }
Example 14
Source File: Retry.scala From lagom with Apache License 2.0 | 5 votes |
package com.lightbend.lagom.internal.javadsl.persistence.jpa import java.util.concurrent.CompletionStage import java.util.function.Supplier import akka.actor.Scheduler import akka.pattern.after import scala.concurrent.duration.Duration.fromNanos import scala.concurrent.duration.FiniteDuration import scala.concurrent.ExecutionContext import scala.concurrent.Future import scala.util.control.NonFatal // With thanks to https://gist.github.com/viktorklang/9414163 private[lagom] class Retry(delay: FiniteDuration, delayFactor: Double, maxRetries: Int) { def apply[T](op: => T)(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { def iterate(nextDelay: FiniteDuration, remainingRetries: Int): Future[T] = Future(op).recoverWith { case NonFatal(throwable) if remainingRetries > 0 => { onRetry(throwable, nextDelay, remainingRetries) after(nextDelay, s)(iterate(finiteMultiply(nextDelay, delayFactor), remainingRetries - 1)) } } iterate(delay, maxRetries) } // For convenient use from Java 8 def retry[T](op: Supplier[T])(implicit ec: ExecutionContext, s: Scheduler): CompletionStage[T] = { import scala.compat.java8.FutureConverters._ apply(op.get()).toJava } protected def onRetry(throwable: Throwable, delay: FiniteDuration, remainingRetries: Int): Unit = () private def finiteMultiply(duration: FiniteDuration, factor: Double): FiniteDuration = fromNanos((duration.toNanos * factor).toLong) } private[lagom] object Retry { def apply[T](delay: FiniteDuration, delayFactor: Double, maxRetries: Int)( op: => T )(implicit ec: ExecutionContext, s: Scheduler): Future[T] = (new Retry(delay, delayFactor, maxRetries))(op) }
Example 15
Source File: QueriesService.scala From endpoints4s with MIT License | 5 votes |
package cqrs.queries import java.util.UUID import akka.actor.Scheduler import play.api.libs.ws.WSClient import scala.concurrent.ExecutionContext.Implicits.global import cqrs.commands.{CommandsEndpoints, MeterCreated, RecordAdded, StoredEvent} import scala.collection.immutable.SortedMap import scala.concurrent.duration.DurationInt import scala.concurrent.Future import scala.concurrent.stm.{Ref, atomic} private def applyEvent(state: State, storedEvent: StoredEvent): State = storedEvent match { case StoredEvent(t, MeterCreated(id, label)) => state.copy( lastEventTimestamp = Some(t), meters = state.meters + (id -> Meter(id, label, SortedMap.empty)) ) case StoredEvent(t, RecordAdded(id, date, value)) => val meter = state.meters(id) val updatedMeter = meter.copy(timeSeries = meter.timeSeries + (date -> value)) state.copy( lastEventTimestamp = Some(t), meters = state.meters + (id -> updatedMeter) ) } }
Example 16
Source File: AkkaTest.scala From daml with Apache License 2.0 | 5 votes |
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package com.daml.ledger.client.testing import java.util import java.util.concurrent.{Executors, ScheduledExecutorService} import akka.NotUsed import akka.actor.{ActorSystem, Scheduler} import akka.stream.scaladsl.{Sink, Source} import akka.stream.Materializer import akka.util.ByteString import com.daml.grpc.adapter.{ExecutionSequencerFactory, SingleThreadExecutionSequencerPool} import com.typesafe.config.{Config, ConfigFactory, ConfigValueFactory} import com.typesafe.scalalogging.LazyLogging import org.scalatest.{BeforeAndAfterAll, Suite} import scala.concurrent.duration._ import scala.concurrent.{Await, ExecutionContextExecutor, Future} import scala.util.control.NonFatal trait AkkaTest extends BeforeAndAfterAll with LazyLogging { self: Suite => // TestEventListener is needed for log testing private val loggers = util.Arrays.asList("akka.event.slf4j.Slf4jLogger", "akka.testkit.TestEventListener") protected implicit val sysConfig: Config = ConfigFactory .load() .withValue("akka.loggers", ConfigValueFactory.fromIterable(loggers)) .withValue("akka.logger-startup-timeout", ConfigValueFactory.fromAnyRef("30s")) .withValue("akka.stdout-loglevel", ConfigValueFactory.fromAnyRef("INFO")) protected implicit val system: ActorSystem = ActorSystem("test", sysConfig) protected implicit val ec: ExecutionContextExecutor = system.dispatchers.lookup("test-dispatcher") protected implicit val scheduler: Scheduler = system.scheduler protected implicit val schedulerService: ScheduledExecutorService = Executors.newSingleThreadScheduledExecutor() protected implicit val materializer: Materializer = Materializer(system) protected implicit val esf: ExecutionSequencerFactory = new SingleThreadExecutionSequencerPool("testSequencerPool") protected val timeout: FiniteDuration = 2.minutes protected val shortTimeout: FiniteDuration = 5.seconds protected def await[T](fun: => Future[T]): T = Await.result(fun, timeout) protected def awaitShort[T](fun: => Future[T]): T = Await.result(fun, shortTimeout) protected def drain(source: Source[ByteString, NotUsed]): ByteString = { val futureResult: Future[ByteString] = source.runFold(ByteString.empty) { (a, b) => a.concat(b) } awaitShort(futureResult) } protected def drain[A, B](source: Source[A, B]): Seq[A] = { val futureResult: Future[Seq[A]] = source.runWith(Sink.seq) awaitShort(futureResult) } override protected def afterAll(): Unit = { try { val _ = await(system.terminate()) } catch { case NonFatal(_) => () } schedulerService.shutdownNow() super.afterAll() } }
Example 17
Source File: ApiGwLauncher.scala From openwhisk with Apache License 2.0 | 5 votes |
package org.apache.openwhisk.standalone import akka.actor.{ActorSystem, Scheduler} import akka.http.scaladsl.model.Uri import akka.pattern.RetrySupport import org.apache.openwhisk.common.{Logging, TransactionId} import org.apache.openwhisk.standalone.StandaloneDockerSupport.{containerName, createRunCmd} import pureconfig._ import pureconfig.generic.auto._ import scala.concurrent.duration._ import scala.concurrent.{ExecutionContext, Future} class ApiGwLauncher(docker: StandaloneDockerClient, apiGwApiPort: Int, apiGwMgmtPort: Int, serverPort: Int)( implicit logging: Logging, ec: ExecutionContext, actorSystem: ActorSystem, tid: TransactionId) extends RetrySupport { private implicit val scd: Scheduler = actorSystem.scheduler case class RedisConfig(image: String) case class ApiGwConfig(image: String) private val redisConfig = loadConfigOrThrow[RedisConfig](StandaloneConfigKeys.redisConfigKey) private val apiGwConfig = loadConfigOrThrow[ApiGwConfig](StandaloneConfigKeys.apiGwConfigKey) def run(): Future[Seq[ServiceContainer]] = { for { (redis, redisSvcs) <- runRedis() _ <- waitForRedis(redis) (_, apiGwSvcs) <- runApiGateway(redis) _ <- waitForApiGw() } yield Seq(redisSvcs, apiGwSvcs).flatten } def runRedis(): Future[(StandaloneDockerContainer, Seq[ServiceContainer])] = { val defaultRedisPort = 6379 val redisPort = StandaloneDockerSupport.checkOrAllocatePort(defaultRedisPort) logging.info(this, s"Starting Redis at $redisPort") val params = Map("-p" -> Set(s"$redisPort:6379")) val name = containerName("redis") val args = createRunCmd(name, dockerRunParameters = params) val f = docker.runDetached(redisConfig.image, args, shouldPull = true) val sc = ServiceContainer(redisPort, s"http://localhost:$redisPort", name) f.map(c => (c, Seq(sc))) } def waitForRedis(c: StandaloneDockerContainer): Future[Unit] = { retry(() => isRedisUp(c), 12, 5.seconds) } private def isRedisUp(c: StandaloneDockerContainer) = { val args = Seq( "run", "--rm", "--name", containerName("redis-test"), redisConfig.image, "redis-cli", "-h", c.addr.host, "-p", "6379", "ping") docker.runCmd(args, docker.clientConfig.timeouts.run).map(out => require(out.toLowerCase == "pong")) } def runApiGateway(redis: StandaloneDockerContainer): Future[(StandaloneDockerContainer, Seq[ServiceContainer])] = { val hostIp = StandaloneDockerSupport.getLocalHostIp() val env = Map( "BACKEND_HOST" -> s"http://$hostIp:$serverPort", "REDIS_HOST" -> redis.addr.host, "REDIS_PORT" -> "6379", //This is the name used to render the final url. So should be localhost //as that would be used by end user outside of docker "PUBLIC_MANAGEDURL_HOST" -> StandaloneDockerSupport.getLocalHostName(), "PUBLIC_MANAGEDURL_PORT" -> apiGwMgmtPort.toString) logging.info(this, s"Starting Api Gateway at api port: $apiGwApiPort, management port: $apiGwMgmtPort") val name = containerName("apigw") val params = Map("-p" -> Set(s"$apiGwApiPort:9000", s"$apiGwMgmtPort:8080")) val args = createRunCmd(name, env, params) //TODO ExecManifest is scoped to core. Ideally we would like to do // ExecManifest.ImageName(apiGwConfig.image).prefix.contains("openwhisk") val pull = apiGwConfig.image.startsWith("openwhisk") val f = docker.runDetached(apiGwConfig.image, args, pull) val sc = Seq( ServiceContainer(apiGwApiPort, s"http://localhost:$apiGwApiPort", s"$name, Api Gateway - Api Service "), ServiceContainer(apiGwMgmtPort, s"http://localhost:$apiGwMgmtPort", s"$name, Api Gateway - Management Service")) f.map(c => (c, sc)) } def waitForApiGw(): Future[Unit] = { new ServerStartupCheck( Uri(s"http://${StandaloneDockerSupport.getLocalHostName()}:$apiGwApiPort/v1/apis"), "ApiGateway") .waitForServerToStart() Future.successful(()) } }
Example 18
Source File: RetryPolicy.scala From reactive-consul with MIT License | 5 votes |
package stormlantern.consul.client package util import scala.concurrent._ import scala.concurrent.duration._ import akka.actor.Scheduler import akka.pattern.after trait RetryPolicy { def maxRetries = 4 def retry[T]( delay: FiniteDuration = 500.milli, retries: Int = 4, backoff: Int = 2, predicate: T ⇒ Boolean = (r: T) ⇒ true )(f: ⇒ Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { f.map { case r if !predicate(r) ⇒ throw new IllegalStateException("Result does not satisfy the predicate specified") case r ⇒ r } recoverWith { case _ if retries > 0 ⇒ after(delay, s)(retry(delay * backoff, retries - 1, backoff, predicate)(f)) } } }
Example 19
Source File: CustomAutoDownBase.scala From akka-cluster-custom-downing with Apache License 2.0 | 5 votes |
package tanukki.akka.cluster.autodown import akka.actor.{Cancellable, Scheduler, Address, Actor} import akka.cluster.ClusterEvent._ import akka.cluster.MemberStatus.{Exiting, Down} import akka.cluster._ import scala.concurrent.duration.{Duration, FiniteDuration} object CustomDowning { case class UnreachableTimeout(member: Member) } abstract class CustomAutoDownBase(autoDownUnreachableAfter: FiniteDuration) extends Actor { import CustomDowning._ def selfAddress: Address def down(node: Address): Unit def downOrAddPending(member: Member): Unit def downOrAddPendingAll(members: Set[Member]): Unit def scheduler: Scheduler import context.dispatcher val skipMemberStatus = Set[MemberStatus](Down, Exiting) private var scheduledUnreachable: Map[Member, Cancellable] = Map.empty private var pendingUnreachable: Set[Member] = Set.empty private var unstableUnreachable: Set[Member] = Set.empty override def postStop(): Unit = { scheduledUnreachable.values foreach { _.cancel } super.postStop() } def receiveEvent: Receive def receive: Receive = receiveEvent orElse predefinedReceiveEvent def predefinedReceiveEvent: Receive = { case state: CurrentClusterState => initialize(state) state.unreachable foreach unreachableMember case UnreachableTimeout(member) => if (scheduledUnreachable contains member) { scheduledUnreachable -= member if (scheduledUnreachable.isEmpty) { unstableUnreachable += member downOrAddPendingAll(unstableUnreachable) unstableUnreachable = Set.empty } else { unstableUnreachable += member } } case _: ClusterDomainEvent => } def initialize(state: CurrentClusterState) = {} def unreachableMember(m: Member): Unit = if (!skipMemberStatus(m.status) && !scheduledUnreachable.contains(m)) scheduleUnreachable(m) def scheduleUnreachable(m: Member): Unit = { if (autoDownUnreachableAfter == Duration.Zero) { downOrAddPending(m) } else { val task = scheduler.scheduleOnce(autoDownUnreachableAfter, self, UnreachableTimeout(m)) scheduledUnreachable += (m -> task) } } def remove(member: Member): Unit = { scheduledUnreachable.get(member) foreach { _.cancel } scheduledUnreachable -= member pendingUnreachable -= member unstableUnreachable -= member } def scheduledUnreachableMembers: Map[Member, Cancellable] = scheduledUnreachable def pendingUnreachableMembers: Set[Member] = pendingUnreachable def pendingAsUnreachable(member: Member): Unit = pendingUnreachable += member def downPendingUnreachableMembers(): Unit = { pendingUnreachable.foreach(member => down(member.address)) pendingUnreachable = Set.empty } def unstableUnreachableMembers: Set[Member] = unstableUnreachable }
Example 20
Source File: ClusterCustomDowning.scala From akka-cluster-custom-downing with Apache License 2.0 | 5 votes |
package tanukki.akka.cluster.autodown import akka.actor.{Address, ActorLogging, Scheduler} import akka.cluster.Cluster import akka.cluster.ClusterEvent.ClusterDomainEvent import scala.concurrent.duration._ trait ClusterCustomDowning extends ActorLogging { base: CustomAutoDownBase => val cluster = Cluster(context.system) override def selfAddress: Address = cluster.selfAddress override def scheduler: Scheduler = { if (context.system.scheduler.maxFrequency < 1.second / cluster.settings.SchedulerTickDuration) { log.warning("CustomDowning does not use a cluster dedicated scheduler. Cluster will use a dedicated scheduler if configured " + "with 'akka.scheduler.tick-duration' [{} ms] > 'akka.cluster.scheduler.tick-duration' [{} ms].", (1000 / context.system.scheduler.maxFrequency).toInt, cluster.settings.SchedulerTickDuration.toMillis) } context.system.scheduler } override def preStart(): Unit = { cluster.subscribe(self, classOf[ClusterDomainEvent]) } override def postStop(): Unit = { cluster.unsubscribe(self) } }
Example 21
Source File: AkkaUnitTestLike.scala From reactive-kinesis with Apache License 2.0 | 5 votes |
package com.weightwatchers.reactive.kinesis.common import akka.actor.{ActorSystem, Scheduler} import akka.stream.{ActorMaterializer, Materializer} import akka.testkit.TestKitBase import com.typesafe.config.{Config, ConfigFactory} import org.scalatest.concurrent.ScalaFutures import org.scalatest.{BeforeAndAfterAll, Suite} import scala.concurrent.ExecutionContextExecutor trait AkkaUnitTestLike extends TestKitBase with ScalaFutures with BeforeAndAfterAll { self: Suite => implicit lazy val config: Config = ConfigFactory.load("sample.conf") implicit lazy val system: ActorSystem = ActorSystem(suiteName, config) implicit lazy val scheduler: Scheduler = system.scheduler implicit lazy val mat: Materializer = ActorMaterializer() implicit lazy val ctx: ExecutionContextExecutor = system.dispatcher abstract override def afterAll(): Unit = { super.afterAll() // intentionally shutdown the actor system last. system.terminate().futureValue } }
Example 22
Source File: FallbackPublisher.scala From reliable-http-client with Apache License 2.0 | 5 votes |
package rhttpc.transport.fallback import akka.actor.{ActorSystem, Scheduler} import akka.pattern.CircuitBreaker import org.slf4j.LoggerFactory import rhttpc.transport.{Message, Publisher} import scala.concurrent.Future import scala.concurrent.duration.FiniteDuration import scala.util.control.NonFatal private[fallback] class FallbackPublisher[Msg](main: Publisher[Msg], fallback: Publisher[Msg]) (maxFailures: Int, callTimeout: FiniteDuration, resetTimeout: FiniteDuration) (implicit system: ActorSystem) extends Publisher[Msg] { import system.dispatcher private val logger = LoggerFactory.getLogger(getClass) private val circuitBreaker = new CircuitBreaker(system.scheduler, maxFailures, callTimeout, resetTimeout) .onOpen(logger.debug("Circuit opened")) .onHalfOpen(logger.debug("Circuit half-opened")) .onClose(logger.debug("Circuit closed")) override def publish(msg: Message[Msg]): Future[Unit] = { circuitBreaker.withCircuitBreaker(main.publish(msg)).recoverWith { case NonFatal(ex) => logger.debug(s"Circuit is opened, sending message [${msg.getClass.getName}] to fallback transport") fallback.publish(msg) } } override def start(): Unit = { main.start() fallback.start() } override def stop(): Future[Unit] = { import rhttpc.utils.Recovered._ recoveredFuture("stopping main publisher", main.stop()) .flatMap(_ => recoveredFuture("stopping fallback publisher", fallback.stop())) } }
Example 23
Source File: AmqpJdbcScheduler.scala From reliable-http-client with Apache License 2.0 | 5 votes |
package rhttpc.transport.amqpjdbc import akka.actor.{Cancellable, Scheduler} import org.slf4j.LoggerFactory import rhttpc.transport.SerializingPublisher.SerializedMessage import rhttpc.transport._ import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} import scala.util.control.NonFatal import scala.util.{Failure, Success, Try} private[amqpjdbc] trait AmqpJdbcScheduler[PubMsg] { def schedule(msg: Message[PubMsg], delay: FiniteDuration): Future[Unit] def start(): Unit def stop(): Future[Unit] } private[amqpjdbc] class AmqpJdbcSchedulerImpl[PubMsg](scheduler: Scheduler, checkInterval: FiniteDuration, repo: ScheduledMessagesRepository, queueName: String, batchSize: Int, publisher: SerializingPublisher[PubMsg]) (implicit ec: ExecutionContext, serializer: Serializer[PubMsg]) extends AmqpJdbcScheduler[PubMsg] { private val logger = LoggerFactory.getLogger(getClass) private var ran: Boolean = false private var scheduledCheck: Option[Cancellable] = None private var currentPublishedFetchedFuture: Future[Int] = Future.successful(0) override def schedule(msg: Message[PubMsg], delay: FiniteDuration): Future[Unit] = { val serialized = serializer.serialize(msg.content) repo.save(MessageToSchedule(queueName, serialized, msg.properties, delay)) } override def start(): Unit = { synchronized { if (!ran) { ran = true publishFetchedMessagesThanReschedule() } } } private def publishFetchedMessagesThanReschedule(): Unit = { synchronized { if (ran) { val publishedFetchedFuture = repo.fetchMessagesShouldByRun(queueName, batchSize)(publish) currentPublishedFetchedFuture = publishedFetchedFuture publishedFetchedFuture onComplete handlePublicationResult } } } private def publish(messages: Seq[ScheduledMessage]): Future[Seq[Unit]] = { if (messages.nonEmpty) { logger.debug(s"Fetched ${messages.size}, publishing") } val handlingFutures = messages.map { message => publisher.publishSerialized(SerializedMessage(message.content.getBytes(), message.properties)) } Future.sequence(handlingFutures) } private def handlePublicationResult(tryResult: Try[Int]): Unit = { tryResult match { case Failure(ex) => logger.error("Exception while publishing fetched messages", ex) case _ => } synchronized { if (ran) { scheduledCheck = Some(scheduler.scheduleOnce(checkInterval)(publishFetchedMessagesThanReschedule())) } else { logger.debug(s"Scheduler is stopping, next check will be skipped") } } } override def stop(): Future[Unit] = { synchronized { scheduledCheck.foreach(_.cancel()) ran = false currentPublishedFetchedFuture.map(_ => Unit) } } }
Example 24
Source File: RandomDataProducer.scala From parquet4s with MIT License | 5 votes |
package com.github.mjakubowski84.parquet4s.indefinite import akka.actor.{Actor, ActorRef, Cancellable, Props, Scheduler} import akka.pattern.ask import akka.util.Timeout import scala.concurrent.duration._ import scala.concurrent.{Await, ExecutionContext} import scala.util.Random object RandomDataProducer { private val words = Seq("Example", "how", "to", "setup", "indefinite", "stream", "with", "Parquet", "writer") } trait RandomDataProducer { this: Akka with Logger with Kafka => import RandomDataProducer._ private def nextWord: String = words(Random.nextInt(words.size - 1)) private def action(): Unit = sendKafkaMessage(nextWord) private lazy val scheduler: ActorRef = system.actorOf(FluctuatingSchedulerActor.props(action)) implicit private val stopTimeout: Timeout = new Timeout(FluctuatingSchedulerActor.MaxDelay) def startDataProducer(): Unit = { logger.info("Starting scheduler that sends messages to Kafka...") scheduler ! FluctuatingSchedulerActor.Start } def stopDataProducer(): Unit = { logger.info("Stopping scheduler...") Await.ready(scheduler.ask(FluctuatingSchedulerActor.Stop), Duration.Inf) } } private object FluctuatingSchedulerActor { case object Start case object ScheduleNext case object Stop val MinDelay: FiniteDuration = 1.milli val MaxDelay: FiniteDuration = 500.millis val StartDelay: FiniteDuration = 100.millis trait Direction case object Up extends Direction case object Down extends Direction def props(action: () => Unit): Props = Props(new FluctuatingSchedulerActor(action)) } private class FluctuatingSchedulerActor(action: () => Unit) extends Actor { import FluctuatingSchedulerActor._ implicit def executionContext: ExecutionContext = context.system.dispatcher def scheduler: Scheduler = context.system.scheduler var scheduled: Option[Cancellable] = None override def receive: Receive = { case Start => self ! ScheduleNext context.become(scheduling(StartDelay, direction = Down), discardOld = true) } def scheduling(delay: FiniteDuration, direction: Direction): Receive = { case ScheduleNext => action() val rate = Random.nextFloat / 10.0f val step = (delay.toMillis * rate).millis val (newDirection, newDelay) = direction match { case Up if delay + step < MaxDelay => (Up, delay + step) case Up => (Down, delay - step) case Down if delay - step > MinDelay => (Down, delay - step) case Down => (Up, delay + step) } scheduled = Some(scheduler.scheduleOnce(delay, self, ScheduleNext)) context.become(scheduling(newDelay, newDirection), discardOld = true) case Stop => scheduled.foreach(_.cancel()) context.stop(self) } }
Example 25
Source File: WriteJournalDao.scala From akka-persistence-dynamodb with Apache License 2.0 | 5 votes |
package com.github.j5ik2o.akka.persistence.dynamodb.journal.dao import akka.NotUsed import akka.actor.Scheduler import akka.persistence.PersistentRepr import akka.stream.scaladsl.Source import com.github.j5ik2o.akka.persistence.dynamodb.journal.JournalRow import com.github.j5ik2o.akka.persistence.dynamodb.model.{ PersistenceId, SequenceNumber } import scala.concurrent.duration.FiniteDuration import scala.util.Try trait WriteJournalDao extends JournalDaoWithReadMessages { def deleteMessages( persistenceId: PersistenceId, toSequenceNr: SequenceNumber ): Source[Long, NotUsed] def highestSequenceNr(persistenceId: PersistenceId, fromSequenceNr: SequenceNumber): Source[Long, NotUsed] def putMessages(messages: Seq[JournalRow]): Source[Long, NotUsed] } trait JournalDaoWithUpdates extends WriteJournalDao { def updateMessage(journalRow: JournalRow): Source[Unit, NotUsed] } trait JournalDaoWithReadMessages { def getMessagesAsPersistentRepr( persistenceId: PersistenceId, fromSequenceNr: SequenceNumber, toSequenceNr: SequenceNumber, max: Long, deleted: Option[Boolean] = Some(false) ): Source[Try[PersistentRepr], NotUsed] def getMessagesAsPersistentReprWithBatch( persistenceId: String, fromSequenceNr: Long, toSequenceNr: Long, batchSize: Int, refreshInterval: Option[(FiniteDuration, Scheduler)] ): Source[Try[PersistentRepr], NotUsed] }
Example 26
Source File: PeerListSupport.scala From mantis with Apache License 2.0 | 5 votes |
package io.iohk.ethereum.blockchain.sync import akka.actor.{Actor, ActorLogging, ActorRef, Scheduler} import io.iohk.ethereum.network.{EtcPeerManagerActor, Peer, PeerId} import io.iohk.ethereum.network.EtcPeerManagerActor.PeerInfo import io.iohk.ethereum.network.PeerEventBusActor.PeerEvent.PeerDisconnected import io.iohk.ethereum.network.PeerEventBusActor.SubscriptionClassifier.PeerDisconnectedClassifier import io.iohk.ethereum.network.PeerEventBusActor.{PeerSelector, Subscribe, Unsubscribe} import io.iohk.ethereum.utils.Config.SyncConfig import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global trait PeerListSupport { self: Actor with ActorLogging with BlacklistSupport => def etcPeerManager: ActorRef def peerEventBus: ActorRef def syncConfig: SyncConfig def scheduler: Scheduler var handshakedPeers: Map[Peer, PeerInfo] = Map.empty scheduler.schedule(0.seconds, syncConfig.peersScanInterval, etcPeerManager, EtcPeerManagerActor.GetHandshakedPeers)(global, context.self) def removePeer(peerId: PeerId): Unit = { peerEventBus ! Unsubscribe(PeerDisconnectedClassifier(PeerSelector.WithId(peerId))) handshakedPeers.find(_._1.id == peerId).foreach { case (peer, _) => undoBlacklist(peer.id) } handshakedPeers = handshakedPeers.filterNot(_._1.id == peerId) } def peersToDownloadFrom: Map[Peer, PeerInfo] = handshakedPeers.filterNot { case (p, s) => isBlacklisted(p.id) } def handlePeerListMessages: Receive = { case EtcPeerManagerActor.HandshakedPeers(peers) => peers.keys.filterNot(handshakedPeers.contains).foreach { peer => peerEventBus ! Subscribe(PeerDisconnectedClassifier(PeerSelector.WithId(peer.id))) } handshakedPeers = peers case PeerDisconnected(peerId) if handshakedPeers.exists(_._1.id == peerId) => removePeer(peerId) } }
Example 27
Source File: BlacklistSupport.scala From mantis with Apache License 2.0 | 5 votes |
package io.iohk.ethereum.blockchain.sync import scala.concurrent.duration.FiniteDuration import akka.actor.{Actor, ActorLogging, Cancellable, Scheduler} import io.iohk.ethereum.network.PeerId import scala.concurrent.ExecutionContext.Implicits.global trait BlacklistSupport { selfActor: Actor with ActorLogging => import BlacklistSupport._ def scheduler: Scheduler var blacklistedPeers: Seq[(PeerId, Cancellable)] = Nil def blacklist(peerId: PeerId, duration: FiniteDuration, reason: String): Unit = { undoBlacklist(peerId) log.debug(s"Blacklisting peer ($peerId), $reason") val unblacklistCancellable = scheduler.scheduleOnce(duration, self, UnblacklistPeer(peerId)) blacklistedPeers :+= (peerId, unblacklistCancellable) } def undoBlacklist(peerId: PeerId): Unit = { blacklistedPeers.find(_._1 == peerId).foreach(_._2.cancel()) blacklistedPeers = blacklistedPeers.filterNot(_._1 == peerId) } def isBlacklisted(peerId: PeerId): Boolean = blacklistedPeers.exists(_._1 == peerId) def handleBlacklistMessages: Receive = { case UnblacklistPeer(ref) => undoBlacklist(ref) } } object BlacklistSupport { private case class UnblacklistPeer(peerId: PeerId) }
Example 28
Source File: KnownNodesManager.scala From mantis with Apache License 2.0 | 5 votes |
package io.iohk.ethereum.network import java.net.URI import akka.actor.{Actor, ActorLogging, Props, Scheduler} import io.iohk.ethereum.db.storage.KnownNodesStorage import io.iohk.ethereum.network.KnownNodesManager.KnownNodesManagerConfig import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global class KnownNodesManager( config: KnownNodesManagerConfig, knownNodesStorage: KnownNodesStorage, externalSchedulerOpt: Option[Scheduler] = None) extends Actor with ActorLogging { import KnownNodesManager._ private def scheduler = externalSchedulerOpt getOrElse context.system.scheduler var knownNodes: Set[URI] = knownNodesStorage.getKnownNodes() var toAdd: Set[URI] = Set.empty var toRemove: Set[URI] = Set.empty scheduler.schedule(config.persistInterval, config.persistInterval, self, PersistChanges) override def receive: Receive = { case AddKnownNode(uri) => if (!knownNodes.contains(uri)) { knownNodes += uri toAdd += uri toRemove -= uri } case RemoveKnownNode(uri) => if (knownNodes.contains(uri)) { knownNodes -= uri toAdd -= uri toRemove += uri } case GetKnownNodes => sender() ! KnownNodes(knownNodes) case PersistChanges => persistChanges() } private def persistChanges(): Unit = { log.debug(s"Persisting ${knownNodes.size} known nodes.") if (knownNodes.size > config.maxPersistedNodes) { val toAbandon = knownNodes.take(knownNodes.size - config.maxPersistedNodes) toRemove ++= toAbandon toAdd --= toAbandon } if (toAdd.nonEmpty || toRemove.nonEmpty) { knownNodesStorage.updateKnownNodes( toAdd = toAdd, toRemove = toRemove) toAdd = Set.empty toRemove = Set.empty } } } object KnownNodesManager { def props(config: KnownNodesManagerConfig, knownNodesStorage: KnownNodesStorage): Props = Props(new KnownNodesManager(config, knownNodesStorage)) case class AddKnownNode(uri: URI) case class RemoveKnownNode(uri: URI) case object GetKnownNodes case class KnownNodes(nodes: Set[URI]) private case object PersistChanges case class KnownNodesManagerConfig(persistInterval: FiniteDuration, maxPersistedNodes: Int) object KnownNodesManagerConfig { def apply(etcClientConfig: com.typesafe.config.Config): KnownNodesManagerConfig = { val knownNodesManagerConfig = etcClientConfig.getConfig("network.known-nodes") KnownNodesManagerConfig( persistInterval = knownNodesManagerConfig.getDuration("persist-interval").toMillis.millis, maxPersistedNodes = knownNodesManagerConfig.getInt("max-persisted-nodes")) } } }
Example 29
Source File: RetryHelper.scala From daml with Apache License 2.0 | 5 votes |
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package com.daml.navigator.util import java.lang.Math.floor import akka.actor.Scheduler import akka.pattern.after import com.daml.grpc.GrpcException import com.typesafe.scalalogging.LazyLogging import scala.concurrent.duration._ import scala.concurrent.{ExecutionContext, Future} import scala.util.control.NonFatal val always: RetryStrategy = { case NonFatal(_) => true } val failFastOnPermissionDenied: RetryStrategy = { case GrpcException.PERMISSION_DENIED() => false case NonFatal(_) => true } def retry[T](retryConfig: Option[(Scheduler, IRetryConfig)])(retryStrategy: RetryStrategy)( f: => Future[T])(implicit ec: ExecutionContext): Future[T] = { retryConfig match { case None => f case Some(rc) => implicit val scheduler: Scheduler = rc._1 retry(Option(rc._2))(retryStrategy)(f) } } def retry[T](retryConfig: Option[IRetryConfig])(retryStrategy: RetryStrategy)( f: => Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { retryConfig match { case None => f case Some(rc) => val maxAttempts = floor(rc.timeout / rc.interval).toInt retry(maxAttempts, rc.interval)(retryStrategy)(f) } } def retry[T](maxAttempts: Int, delay: FiniteDuration)(retryStrategy: RetryStrategy)( f: => Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { def shouldRetry(n: Int, e: Throwable): Boolean = n > 0 && retryStrategy.applyOrElse(e, (_: Throwable) => false) val remainingAttempts = maxAttempts - 1 // the next line will trigger a future evaluation f.recoverWith { case NonFatal(e) if shouldRetry(remainingAttempts, e) => logWarning(remainingAttempts, e) after(delay, s)(retry(remainingAttempts, delay)(retryStrategy)(f)) } } private def logWarning(remainingAttempts: Int, e: Throwable): Unit = { logger.warn( s"Retrying after failure. Attempts remaining: $remainingAttempts. Error: ${e.getMessage}") } }
Example 30
Source File: RetryHelper.scala From daml with Apache License 2.0 | 5 votes |
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. // SPDX-License-Identifier: Apache-2.0 package com.daml.ledger.client.binding.retrying import java.lang.Math.floor import akka.actor.Scheduler import akka.pattern.after import com.daml.ledger.client.binding.config.IRetryConfig import com.typesafe.scalalogging.LazyLogging import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} import scala.util.control.NonFatal object RetryHelper extends LazyLogging { val always: RetryStrategy = { case NonFatal(_) => true } def retry[T](retryConfig: Option[(Scheduler, IRetryConfig)])(retryStrategy: RetryStrategy)( f: => Future[T])(implicit ec: ExecutionContext): Future[T] = { retryConfig match { case None => f case Some(rc) => implicit val scheduler: Scheduler = rc._1 retry(Option(rc._2))(retryStrategy)(f) } } def retry[T](retryConfig: Option[IRetryConfig])(retryStrategy: RetryStrategy)( f: => Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { retryConfig match { case None => f case Some(rc) => val maxAttempts = floor(rc.timeout / rc.interval).toInt retry(maxAttempts, rc.interval)(retryStrategy)(f) } } def retry[T](maxAttempts: Int, delay: FiniteDuration)(retryStrategy: RetryStrategy)( f: => Future[T])(implicit ec: ExecutionContext, s: Scheduler): Future[T] = { def shouldRetry(n: Int, e: Throwable): Boolean = n > 0 && retryStrategy.applyOrElse(e, (_: Throwable) => false) val remainingAttempts = maxAttempts - 1 // the next line will trigger a future evaluation f.recoverWith { case NonFatal(e) if shouldRetry(remainingAttempts, e) => logWarning(remainingAttempts, e) after(delay, s)(retry(remainingAttempts, delay)(retryStrategy)(f)) } } private def logWarning(remainingAttempts: Int, e: Throwable): Unit = { logger.warn( s"Retrying after failure. Attempts remaining: $remainingAttempts. Error: ${e.getMessage}") } }