1 /*
2  *  Make.org Core API
3  *  Copyright (C) 2018 Make.org
4  *
5  * This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  *
18  */
19 
20 package org.make.api.sequence
21 
22 import akka.actor.typed.receptionist.ServiceKey
23 import akka.actor.typed.{ActorRef, Behavior}
24 import akka.actor.typed.scaladsl.Behaviors
25 import org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol
26 import org.make.core.question.QuestionId
27 import org.make.core.sequence.SequenceConfiguration
28 
29 import scala.concurrent.duration.DurationInt
30 import scala.util.{Failure, Success}
31 
32 object SequenceConfigurationActor {
33   def apply(
34     persistentSequenceConfigurationService: PersistentSequenceConfigurationService
35   ): Behavior[SequenceConfigurationActorProtocol] = {
36     Behaviors.withTimers { timers =>
37       timers.startTimerWithFixedDelay(ReloadSequenceConfiguration, 5.minutes)
38       handleMessages(Map.empty)(persistentSequenceConfigurationService)
39     }
40   }
41 
42   @SuppressWarnings(Array("org.wartremover.warts.Recursion"))
43   private def handleMessages(configCache: Map[QuestionId, SequenceConfiguration])(
44     implicit persistentSequenceConfigurationService: PersistentSequenceConfigurationService
45   ): Behavior[SequenceConfigurationActorProtocol] = {
46     Behaviors.setup { context =>
47       Behaviors.receiveMessage {
48         case ReloadSequenceConfiguration =>
49           context.pipeToSelf(persistentSequenceConfigurationService.findAll()) {
50             case Success(configurations) => UpdateSequenceConfiguration(configurations)
51             case Failure(e)              => UpdateSequenceConfigurationsFailed(e)
52           }
53           Behaviors.same
54         case UpdateSequenceConfiguration(configurations) =>
55           val configCache = configurations.map { configuration =>
56             configuration.questionId -> configuration
57           }.toMap
58           handleMessages(configCache)
59         case UpdateSequenceConfigurationsFailed(e) =>
60           context.log.error("Unable to reload sequence configurations:", e)
61           Behaviors.same
62         case GetSequenceConfiguration(questionId, replyTo) =>
63           replyTo ! CachedSequenceConfiguration(configCache.getOrElse(questionId, SequenceConfiguration.default))
64           Behaviors.same
65       }
66     }
67   }
68 
69   sealed trait SequenceConfigurationActorProtocol
70   case object ReloadSequenceConfiguration extends SequenceConfigurationActorProtocol
71   private final case class UpdateSequenceConfiguration(configurations: Seq[SequenceConfiguration])
72       extends SequenceConfigurationActorProtocol
73   private final case class UpdateSequenceConfigurationsFailed(e: Throwable) extends SequenceConfigurationActorProtocol
74 
75   final case class GetSequenceConfiguration(questionId: QuestionId, replyTo: ActorRef[CachedSequenceConfiguration])
76       extends SequenceConfigurationActorProtocol
77 
78   final case class CachedSequenceConfiguration(sequenceConfiguration: SequenceConfiguration)
79   val name: String = "sequence-configuration-cache"
80   val SequenceConfigurationCacheActorKey: ServiceKey[SequenceConfigurationActorProtocol] = ServiceKey(name)
81 
82 }
83 
84 trait SequenceConfigurationActorComponent {
85   def sequenceConfigurationActor: ActorRef[SequenceConfigurationActorProtocol]
86 }
Line Stmt Id Pos Tree Symbol Tests Code
36 28624 1370 - 1558 Apply akka.actor.typed.scaladsl.Behaviors.withTimers akka.actor.typed.scaladsl.Behaviors.withTimers[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol](((timers: akka.actor.typed.scaladsl.TimerScheduler[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol]) => { timers.startTimerWithFixedDelay(SequenceConfigurationActor.this.ReloadSequenceConfiguration, scala.concurrent.duration.`package`.DurationInt(5).minutes); SequenceConfigurationActor.this.handleMessages(scala.Predef.Map.empty[org.make.core.question.QuestionId, Nothing])(persistentSequenceConfigurationService) }))
37 30234 1409 - 1480 Apply akka.actor.typed.scaladsl.TimerScheduler.startTimerWithFixedDelay timers.startTimerWithFixedDelay(SequenceConfigurationActor.this.ReloadSequenceConfiguration, scala.concurrent.duration.`package`.DurationInt(5).minutes)
37 28424 1470 - 1479 Select scala.concurrent.duration.DurationConversions.minutes scala.concurrent.duration.`package`.DurationInt(5).minutes
37 30089 1441 - 1468 Select org.make.api.sequence.SequenceConfigurationActor.ReloadSequenceConfiguration SequenceConfigurationActor.this.ReloadSequenceConfiguration
37 29302 1470 - 1471 Literal <nosymbol> 5
38 29473 1487 - 1552 Apply org.make.api.sequence.SequenceConfigurationActor.handleMessages SequenceConfigurationActor.this.handleMessages(scala.Predef.Map.empty[org.make.core.question.QuestionId, Nothing])(persistentSequenceConfigurationService)
46 28600 1859 - 2858 Apply akka.actor.typed.scaladsl.Behaviors.setup akka.actor.typed.scaladsl.Behaviors.setup[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol](((context: akka.actor.typed.scaladsl.ActorContext[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol]) => akka.actor.typed.scaladsl.Behaviors.receiveMessage[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol](((x0$1: org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol) => x0$1 match { case SequenceConfigurationActor.this.ReloadSequenceConfiguration => { context.pipeToSelf[Seq[org.make.core.sequence.SequenceConfiguration]](persistentSequenceConfigurationService.findAll())(((x0$2: scala.util.Try[Seq[org.make.core.sequence.SequenceConfiguration]]) => x0$2 match { case (value: Seq[org.make.core.sequence.SequenceConfiguration]): scala.util.Success[Seq[org.make.core.sequence.SequenceConfiguration]]((configurations @ _)) => SequenceConfigurationActor.this.UpdateSequenceConfiguration.apply(configurations) case (exception: Throwable): scala.util.Failure[Seq[org.make.core.sequence.SequenceConfiguration]]((e @ _)) => SequenceConfigurationActor.this.UpdateSequenceConfigurationsFailed.apply(e) })); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol] } case (configurations: Seq[org.make.core.sequence.SequenceConfiguration]): org.make.api.sequence.SequenceConfigurationActor.UpdateSequenceConfiguration((configurations @ _)) => { val configCache: scala.collection.immutable.Map[org.make.core.question.QuestionId,org.make.core.sequence.SequenceConfiguration] = configurations.map[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)](((configuration: org.make.core.sequence.SequenceConfiguration) => scala.Predef.ArrowAssoc[org.make.core.question.QuestionId](configuration.questionId).->[org.make.core.sequence.SequenceConfiguration](configuration))).toMap[org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration](scala.this.<:<.refl[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)]); SequenceConfigurationActor.this.handleMessages(configCache)(persistentSequenceConfigurationService) } case (e: Throwable): org.make.api.sequence.SequenceConfigurationActor.UpdateSequenceConfigurationsFailed((e @ _)) => { context.log.error("Unable to reload sequence configurations:", e); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol] } case (questionId: org.make.core.question.QuestionId, replyTo: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceConfigurationActor.CachedSequenceConfiguration]): org.make.api.sequence.SequenceConfigurationActor.GetSequenceConfiguration((questionId @ _), (replyTo @ _)) => { typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceConfigurationActor.CachedSequenceConfiguration](replyTo).!(SequenceConfigurationActor.this.CachedSequenceConfiguration.apply(configCache.getOrElse[org.make.core.sequence.SequenceConfiguration](questionId, org.make.core.sequence.SequenceConfiguration.default))); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol] } }))))
47 29372 1894 - 2852 Apply akka.actor.typed.scaladsl.Behaviors.receiveMessage akka.actor.typed.scaladsl.Behaviors.receiveMessage[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol](((x0$1: org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol) => x0$1 match { case SequenceConfigurationActor.this.ReloadSequenceConfiguration => { context.pipeToSelf[Seq[org.make.core.sequence.SequenceConfiguration]](persistentSequenceConfigurationService.findAll())(((x0$2: scala.util.Try[Seq[org.make.core.sequence.SequenceConfiguration]]) => x0$2 match { case (value: Seq[org.make.core.sequence.SequenceConfiguration]): scala.util.Success[Seq[org.make.core.sequence.SequenceConfiguration]]((configurations @ _)) => SequenceConfigurationActor.this.UpdateSequenceConfiguration.apply(configurations) case (exception: Throwable): scala.util.Failure[Seq[org.make.core.sequence.SequenceConfiguration]]((e @ _)) => SequenceConfigurationActor.this.UpdateSequenceConfigurationsFailed.apply(e) })); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol] } case (configurations: Seq[org.make.core.sequence.SequenceConfiguration]): org.make.api.sequence.SequenceConfigurationActor.UpdateSequenceConfiguration((configurations @ _)) => { val configCache: scala.collection.immutable.Map[org.make.core.question.QuestionId,org.make.core.sequence.SequenceConfiguration] = configurations.map[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)](((configuration: org.make.core.sequence.SequenceConfiguration) => scala.Predef.ArrowAssoc[org.make.core.question.QuestionId](configuration.questionId).->[org.make.core.sequence.SequenceConfiguration](configuration))).toMap[org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration](scala.this.<:<.refl[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)]); SequenceConfigurationActor.this.handleMessages(configCache)(persistentSequenceConfigurationService) } case (e: Throwable): org.make.api.sequence.SequenceConfigurationActor.UpdateSequenceConfigurationsFailed((e @ _)) => { context.log.error("Unable to reload sequence configurations:", e); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol] } case (questionId: org.make.core.question.QuestionId, replyTo: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceConfigurationActor.CachedSequenceConfiguration]): org.make.api.sequence.SequenceConfigurationActor.GetSequenceConfiguration((questionId @ _), (replyTo @ _)) => { typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceConfigurationActor.CachedSequenceConfiguration](replyTo).!(SequenceConfigurationActor.this.CachedSequenceConfiguration.apply(configCache.getOrElse[org.make.core.sequence.SequenceConfiguration](questionId, org.make.core.sequence.SequenceConfiguration.default))); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol] } }))
49 29974 1994 - 2042 Apply org.make.api.sequence.PersistentSequenceConfigurationService.findAll persistentSequenceConfigurationService.findAll()
49 30096 1975 - 2227 Apply akka.actor.typed.scaladsl.ActorContext.pipeToSelf context.pipeToSelf[Seq[org.make.core.sequence.SequenceConfiguration]](persistentSequenceConfigurationService.findAll())(((x0$2: scala.util.Try[Seq[org.make.core.sequence.SequenceConfiguration]]) => x0$2 match { case (value: Seq[org.make.core.sequence.SequenceConfiguration]): scala.util.Success[Seq[org.make.core.sequence.SequenceConfiguration]]((configurations @ _)) => SequenceConfigurationActor.this.UpdateSequenceConfiguration.apply(configurations) case (exception: Throwable): scala.util.Failure[Seq[org.make.core.sequence.SequenceConfiguration]]((e @ _)) => SequenceConfigurationActor.this.UpdateSequenceConfigurationsFailed.apply(e) }))
50 29561 2090 - 2133 Apply org.make.api.sequence.SequenceConfigurationActor.UpdateSequenceConfiguration.apply SequenceConfigurationActor.this.UpdateSequenceConfiguration.apply(configurations)
51 28730 2178 - 2215 Apply org.make.api.sequence.SequenceConfigurationActor.UpdateSequenceConfigurationsFailed.apply SequenceConfigurationActor.this.UpdateSequenceConfigurationsFailed.apply(e)
53 29303 2238 - 2252 TypeApply akka.actor.typed.scaladsl.Behaviors.same akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol]
56 28412 2391 - 2432 Apply scala.Predef.ArrowAssoc.-> scala.Predef.ArrowAssoc[org.make.core.question.QuestionId](configuration.questionId).->[org.make.core.sequence.SequenceConfiguration](configuration)
57 29370 2341 - 2450 ApplyToImplicitArgs scala.collection.IterableOnceOps.toMap configurations.map[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)](((configuration: org.make.core.sequence.SequenceConfiguration) => scala.Predef.ArrowAssoc[org.make.core.question.QuestionId](configuration.questionId).->[org.make.core.sequence.SequenceConfiguration](configuration))).toMap[org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration](scala.this.<:<.refl[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)])
57 30238 2445 - 2445 TypeApply scala.<:<.refl scala.this.<:<.refl[(org.make.core.question.QuestionId, org.make.core.sequence.SequenceConfiguration)]
58 28594 2461 - 2488 ApplyToImplicitArgs org.make.api.sequence.SequenceConfigurationActor.handleMessages SequenceConfigurationActor.this.handleMessages(configCache)(persistentSequenceConfigurationService)
60 29975 2553 - 2618 Apply org.slf4j.Logger.error context.log.error("Unable to reload sequence configurations:", e)
61 29093 2629 - 2643 TypeApply akka.actor.typed.scaladsl.Behaviors.same akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol]
63 28416 2716 - 2819 Apply akka.actor.typed.ActorRef.ActorRefOps.! typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceConfigurationActor.CachedSequenceConfiguration](replyTo).!(SequenceConfigurationActor.this.CachedSequenceConfiguration.apply(configCache.getOrElse[org.make.core.sequence.SequenceConfiguration](questionId, org.make.core.sequence.SequenceConfiguration.default)))
63 28737 2788 - 2817 Select org.make.core.sequence.SequenceConfiguration.default org.make.core.sequence.SequenceConfiguration.default
63 29284 2726 - 2819 Apply org.make.api.sequence.SequenceConfigurationActor.CachedSequenceConfiguration.apply SequenceConfigurationActor.this.CachedSequenceConfiguration.apply(configCache.getOrElse[org.make.core.sequence.SequenceConfiguration](questionId, org.make.core.sequence.SequenceConfiguration.default))
63 30100 2754 - 2818 Apply scala.collection.MapOps.getOrElse configCache.getOrElse[org.make.core.sequence.SequenceConfiguration](questionId, org.make.core.sequence.SequenceConfiguration.default)
64 30308 2830 - 2844 TypeApply akka.actor.typed.scaladsl.Behaviors.same akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol]
79 30027 3547 - 3577 Literal <nosymbol> "sequence-configuration-cache"
80 29097 3680 - 3684 Select org.make.api.sequence.SequenceConfigurationActor.name SequenceConfigurationActor.this.name
80 28719 3669 - 3685 ApplyToImplicitArgs akka.actor.typed.receptionist.ServiceKey.apply akka.actor.typed.receptionist.ServiceKey.apply[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol](SequenceConfigurationActor.this.name)((ClassTag.apply[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol](classOf[org.make.api.sequence.SequenceConfigurationActor$$SequenceConfigurationActorProtocol]): scala.reflect.ClassTag[org.make.api.sequence.SequenceConfigurationActor.SequenceConfigurationActorProtocol]))