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.scaladsl.Behaviors
24 import akka.actor.typed.{ActorRef, Behavior}
25 import cats.data.{NonEmptyList => Nel}
26 import org.make.api.sequence.SequenceBehaviour.ConsensusParam
27 import org.make.api.technical.ActorProtocol
28 import org.make.api.technical.sequence.SequenceCacheConfiguration
29 import org.make.core.proposal.indexed.{IndexedProposal, Zone}
30 import org.make.core.question.QuestionId
31 import org.make.core.sequence.{SequenceConfiguration, SequenceKind}
32 import scalacache._
33 import scalacache.guava._
34 import scalacache.modes.scalaFuture._
35 import scalacache.memoization.memoizeF
36 
37 import scala.concurrent.duration.DurationInt
38 import scala.concurrent.Future
39 import scala.concurrent.ExecutionContext.Implicits.global
40 
41 object SequenceCacheManager {
42 
43   type ConfiguredBehaviour = SequenceConfiguration => Future[SequenceBehaviour]
44 
45   def apply(
46     config: SequenceCacheConfiguration,
47     sequenceService: SequenceService,
48     sequenceConfigurationService: SequenceConfigurationService
49   ): Behavior[Protocol] = {
50     Behaviors.withTimers { timers =>
51       timers.startTimerWithFixedDelay(ExpireChildren, config.checkInactivityTimer)
52       handleMessage(Map.empty)(reloadProposals(config, sequenceService, sequenceConfigurationService), config)
53     }
54   }
55 
56   def reloadProposals(
57     sequenceCacheConfiguration: SequenceCacheConfiguration,
58     sequenceService: SequenceService,
59     sequenceConfigurationService: SequenceConfigurationService
60   )(key: CacheKey, behaviour: ConfiguredBehaviour)(): Future[Nel[IndexedProposal]] = {
61     @SuppressWarnings(Array("org.wartremover.warts.Recursion"))
62     def simpleSequence(behaviour: SequenceBehaviour, retries: Int = 3): Future[Nel[IndexedProposal]] = {
63       sequenceService.simpleSequence(Seq.empty, behaviour, Seq.empty, None).flatMap {
64         case Seq() =>
65           if (retries > 0) {
66             simpleSequence(behaviour, retries - 1)
67           } else {
68             Future.failed(
69               new IllegalStateException(
70                 s"Question ${key.questionId.value} might not have any proposals eligible for sequence."
71               )
72             )
73           }
74         case head +: tail => Future.successful(Nel(head, tail.toList))
75       }
76     }
77 
78     sequenceConfigurationService.getSequenceConfigurationByQuestionId(key.questionId).flatMap { config =>
79       val customConfig: SequenceConfiguration = config
80         .copy(mainSequence = config.mainSequence.copy(sequenceSize = sequenceCacheConfiguration.proposalsPoolSize))
81       behaviour(customConfig).flatMap(simpleSequence(_))
82     }
83   }
84 
85   @SuppressWarnings(Array("org.wartremover.warts.Recursion"))
86   def handleMessage(configCache: Map[CacheKey, ActorRef[SequenceCacheActor.Protocol]])(
87     implicit reloadProposals: (CacheKey, ConfiguredBehaviour) => () => Future[Nel[IndexedProposal]],
88     config: SequenceCacheConfiguration
89   ): Behavior[Protocol] = {
90     Behaviors.setup { context =>
91       def getProposal(cmd: GetProposalCmd, replyTo: ActorRef[IndexedProposal]): Behavior[Protocol] = {
92         configCache.get(cmd.key) match {
93           case None =>
94             val cache: ActorRef[SequenceCacheActor.Protocol] =
95               context.spawn(
96                 SequenceCacheActor(reloadProposals(cmd.key, cmd.behaviour), config),
97                 SequenceCacheActor.name(cmd.key)
98               )
99             context.watchWith(cache, ChildTerminated(cmd.key))
100             cache ! SequenceCacheActor.GetProposal(replyTo)
101             handleMessage(configCache ++ Map(cmd.key -> cache))
102           case Some(actorRef) =>
103             actorRef ! SequenceCacheActor.GetProposal(replyTo)
104             Behaviors.same
105         }
106       }
107 
108       Behaviors
109         .receiveMessage[Protocol] {
110           case cmd: GetProposalCmd => getProposal(cmd, cmd.replyTo)
111           case ExpireChildren =>
112             configCache.values.foreach { ref =>
113               ref ! SequenceCacheActor.Expire
114             }
115             Behaviors.same
116           case ChildTerminated(questionId) =>
117             handleMessage(configCache - questionId)
118         }
119     }
120   }
121 
122   implicit val guavaCache: Cache[ConsensusParam] = GuavaCache[ConsensusParam]
123 
124   def getCachedThreshold(getThreshold: () => Future[ConsensusParam]): Future[ConsensusParam] = {
125     memoizeF[Future, ConsensusParam](Some(1.hour)) {
126       getThreshold()
127     }
128   }
129 
130   sealed trait Protocol extends ActorProtocol
131 
132   sealed trait Command extends Protocol
133 
134   sealed trait GetProposalCmd extends Command {
135     val replyTo: ActorRef[IndexedProposal]
136     val key: CacheKey
137     def behaviour: ConfiguredBehaviour
138   }
139 
140   final case class GetProposal(id: QuestionId, replyTo: ActorRef[IndexedProposal]) extends GetProposalCmd {
141     override val key: CacheKey = CacheKey(id, SequenceKind.Standard)
142     override def behaviour: ConfiguredBehaviour = { config =>
143       Future.successful(SequenceBehaviourProvider[Unit].behaviour((), config, key.questionId, None))
144     }
145   }
146 
147   final case class GetConsensusProposal(
148     id: QuestionId,
149     threshold: () => Future[ConsensusParam],
150     replyTo: ActorRef[IndexedProposal]
151   ) extends GetProposalCmd {
152     override val key: CacheKey = CacheKey(id, SequenceKind.Consensus)
153     override def behaviour: ConfiguredBehaviour = { config =>
154       getCachedThreshold(threshold).map { param =>
155         SequenceBehaviourProvider[ConsensusParam].behaviour(param, config, key.questionId, None)
156       }
157     }
158   }
159 
160   final case class GetControversyProposal(id: QuestionId, replyTo: ActorRef[IndexedProposal]) extends GetProposalCmd {
161     override val key: CacheKey = CacheKey(id, SequenceKind.Controversy)
162     override def behaviour: ConfiguredBehaviour = { config =>
163       Future.successful(
164         SequenceBehaviourProvider[Zone.Controversy.type].behaviour(Zone.Controversy, config, key.questionId, None)
165       )
166     }
167   }
168   case object ExpireChildren extends Command
169   final case class ChildTerminated(key: CacheKey) extends Command
170 
171   val name: String = "sequence-cache-manager"
172   val SequenceCacheActorKey: ServiceKey[Protocol] = ServiceKey(name)
173 
174   final case class CacheKey(questionId: QuestionId, kind: SequenceKind)
175 }
Line Stmt Id Pos Tree Symbol Tests Code
50 30206 1851 - 2083 Apply akka.actor.typed.scaladsl.Behaviors.withTimers org.make.api.sequence.sequencecachemanagertest akka.actor.typed.scaladsl.Behaviors.withTimers[org.make.api.sequence.SequenceCacheManager.Protocol](((timers: akka.actor.typed.scaladsl.TimerScheduler[org.make.api.sequence.SequenceCacheManager.Protocol]) => { timers.startTimerWithFixedDelay(SequenceCacheManager.this.ExpireChildren, config.checkInactivityTimer); SequenceCacheManager.this.handleMessage(scala.Predef.Map.empty[org.make.api.sequence.SequenceCacheManager.CacheKey, Nothing])(((key: org.make.api.sequence.SequenceCacheManager.CacheKey, behaviour: org.make.api.sequence.SequenceCacheManager.ConfiguredBehaviour) => (() => SequenceCacheManager.this.reloadProposals(config, sequenceService, sequenceConfigurationService)(key, behaviour)())), config) }))
51 30408 1922 - 1936 Select org.make.api.sequence.SequenceCacheManager.ExpireChildren org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.ExpireChildren
51 29506 1938 - 1965 Select org.make.api.technical.sequence.SequenceCacheConfiguration.checkInactivityTimer org.make.api.sequence.sequencecachemanagertest config.checkInactivityTimer
51 28758 1890 - 1966 Apply akka.actor.typed.scaladsl.TimerScheduler.startTimerWithFixedDelay org.make.api.sequence.sequencecachemanagertest timers.startTimerWithFixedDelay(SequenceCacheManager.this.ExpireChildren, config.checkInactivityTimer)
52 28819 1973 - 2077 Apply org.make.api.sequence.SequenceCacheManager.handleMessage org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.handleMessage(scala.Predef.Map.empty[org.make.api.sequence.SequenceCacheManager.CacheKey, Nothing])(((key: org.make.api.sequence.SequenceCacheManager.CacheKey, behaviour: org.make.api.sequence.SequenceCacheManager.ConfiguredBehaviour) => (() => SequenceCacheManager.this.reloadProposals(config, sequenceService, sequenceConfigurationService)(key, behaviour)())), config)
52 29695 1998 - 2068 Apply org.make.api.sequence.SequenceCacheManager.reloadProposals org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.reloadProposals(config, sequenceService, sequenceConfigurationService)(key, behaviour)()
52 28285 1987 - 1996 TypeApply scala.collection.immutable.Map.empty org.make.api.sequence.sequencecachemanagertest scala.Predef.Map.empty[org.make.api.sequence.SequenceCacheManager.CacheKey, Nothing]
63 29382 2566 - 2575 TypeApply scala.collection.SeqFactory.Delegate.empty scala.`package`.Seq.empty[Nothing]
63 28993 2588 - 2597 TypeApply scala.collection.SeqFactory.Delegate.empty scala.`package`.Seq.empty[Nothing]
63 28750 2613 - 2613 Select scala.concurrent.ExecutionContext.Implicits.global scala.concurrent.ExecutionContext.Implicits.global
63 28363 2535 - 3028 ApplyToImplicitArgs scala.concurrent.Future.flatMap sequenceService.simpleSequence(scala.`package`.Seq.empty[Nothing], behaviour, scala.`package`.Seq.empty[Nothing], scala.None).flatMap[cats.data.NonEmptyList[org.make.core.proposal.indexed.IndexedProposal]](((x0$1: Seq[org.make.core.proposal.indexed.IndexedProposal]) => x0$1 match { case scala.`package`.Seq.unapplySeq[org.make.core.proposal.indexed.IndexedProposal](<unapply-selector>) <unapply> () => if (retries.>(0)) simpleSequence(behaviour, retries.-(1)) else scala.concurrent.Future.failed[Nothing](new java.lang.IllegalStateException(("Question ".+(key.questionId.value).+(" might not have any proposals eligible for sequence."): String))) case scala.`package`.+:.unapply[org.make.core.proposal.indexed.IndexedProposal, [_]Seq[_], Seq[org.make.core.proposal.indexed.IndexedProposal]](<unapply-selector>) <unapply> ((head @ _), (tail @ _)) => scala.concurrent.Future.successful[cats.data.NonEmptyList[org.make.core.proposal.indexed.IndexedProposal]](cats.data.NonEmptyList.apply[org.make.core.proposal.indexed.IndexedProposal](head, tail.toList)) }))(scala.concurrent.ExecutionContext.Implicits.global)
63 30432 2599 - 2603 Select scala.None scala.None
65 29511 2651 - 2662 Apply scala.Int.> retries.>(0)
66 28264 2678 - 2716 Apply org.make.api.sequence.SequenceCacheManager.simpleSequence simpleSequence(behaviour, retries.-(1))
66 29702 2678 - 2716 Block org.make.api.sequence.SequenceCacheManager.simpleSequence simpleSequence(behaviour, retries.-(1))
66 28789 2704 - 2715 Apply scala.Int.- retries.-(1)
68 30193 2748 - 2937 Apply scala.concurrent.Future.failed scala.concurrent.Future.failed[Nothing](new java.lang.IllegalStateException(("Question ".+(key.questionId.value).+(" might not have any proposals eligible for sequence."): String)))
68 29487 2748 - 2937 Block scala.concurrent.Future.failed scala.concurrent.Future.failed[Nothing](new java.lang.IllegalStateException(("Question ".+(key.questionId.value).+(" might not have any proposals eligible for sequence."): String)))
69 28921 2777 - 2923 Apply java.lang.IllegalStateException.<init> new java.lang.IllegalStateException(("Question ".+(key.questionId.value).+(" might not have any proposals eligible for sequence."): String))
74 30436 2997 - 3019 Apply cats.data.NonEmptyList.apply cats.data.NonEmptyList.apply[org.make.core.proposal.indexed.IndexedProposal](head, tail.toList)
74 29515 2979 - 3020 Apply scala.concurrent.Future.successful scala.concurrent.Future.successful[cats.data.NonEmptyList[org.make.core.proposal.indexed.IndexedProposal]](cats.data.NonEmptyList.apply[org.make.core.proposal.indexed.IndexedProposal](head, tail.toList))
74 28958 3007 - 3018 Select scala.collection.IterableOnceOps.toList tail.toList
78 29758 3106 - 3120 Select org.make.api.sequence.SequenceCacheManager.CacheKey.questionId org.make.api.sequence.sequencecachemanagertest key.questionId
78 29653 3040 - 3375 ApplyToImplicitArgs scala.concurrent.Future.flatMap org.make.api.sequence.sequencecachemanagertest sequenceConfigurationService.getSequenceConfigurationByQuestionId(key.questionId).flatMap[cats.data.NonEmptyList[org.make.core.proposal.indexed.IndexedProposal]](((config: org.make.core.sequence.SequenceConfiguration) => { val customConfig: org.make.core.sequence.SequenceConfiguration = { <artifact> val x$11: org.make.core.sequence.ExplorationSequenceConfiguration = { <artifact> val x$1: eu.timepit.refined.types.numeric.PosInt = sequenceCacheConfiguration.proposalsPoolSize; <artifact> val x$2: org.make.core.sequence.ExplorationSequenceConfigurationId = config.mainSequence.copy$default$1; <artifact> val x$3: eu.timepit.refined.types.numeric.PosInt = config.mainSequence.copy$default$3; <artifact> val x$4: org.make.core.technical.RefinedTypes.Ratio = config.mainSequence.copy$default$4; <artifact> val x$5: org.make.core.technical.RefinedTypes.Ratio = config.mainSequence.copy$default$5; <artifact> val x$6: org.make.core.sequence.ExplorationSortAlgorithm = config.mainSequence.copy$default$6; <artifact> val x$7: org.make.core.sequence.ExplorationSortAlgorithm = config.mainSequence.copy$default$7; <artifact> val x$8: org.make.core.technical.RefinedTypes.Ratio = config.mainSequence.copy$default$8; <artifact> val x$9: Int = config.mainSequence.copy$default$9; <artifact> val x$10: org.make.core.sequence.ExplorationSequenceConfiguration.SequenceThresholds = config.mainSequence.copy$default$10; config.mainSequence.copy(x$2, x$1, x$3, x$4, x$5, x$6, x$7, x$8, x$9, x$10) }; <artifact> val x$12: org.make.core.question.QuestionId = config.copy$default$1; <artifact> val x$13: org.make.core.sequence.SpecificSequenceConfiguration = config.copy$default$3; <artifact> val x$14: org.make.core.sequence.SpecificSequenceConfiguration = config.copy$default$4; <artifact> val x$15: org.make.core.sequence.SpecificSequenceConfiguration = config.copy$default$5; <artifact> val x$16: Int = config.copy$default$6; <artifact> val x$17: Option[Double] @scala.reflect.internal.annotations.uncheckedBounds = config.copy$default$7; <artifact> val x$18: Option[Double] @scala.reflect.internal.annotations.uncheckedBounds = config.copy$default$8; <artifact> val x$19: Option[Double] @scala.reflect.internal.annotations.uncheckedBounds = config.copy$default$9; <artifact> val x$20: Option[Int] @scala.reflect.internal.annotations.uncheckedBounds = config.copy$default$10; <artifact> val x$21: Double = config.copy$default$11; config.copy(x$12, x$11, x$13, x$14, x$15, x$16, x$17, x$18, x$19, x$20, x$21) }; behaviour.apply(customConfig).flatMap[cats.data.NonEmptyList[org.make.core.proposal.indexed.IndexedProposal]](((x$1: org.make.api.sequence.SequenceBehaviour) => simpleSequence(x$1, simpleSequence$default$2)))(scala.concurrent.ExecutionContext.Implicits.global) }))(scala.concurrent.ExecutionContext.Implicits.global)
78 30059 3130 - 3130 Select scala.concurrent.ExecutionContext.Implicits.global org.make.api.sequence.sequencecachemanagertest scala.concurrent.ExecutionContext.Implicits.global
80 30438 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$5 config.mainSequence.copy$default$5
80 29624 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$5 config.copy$default$5
80 30228 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$10 config.copy$default$10
80 29690 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$9 config.mainSequence.copy$default$9
80 29618 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$6 config.mainSequence.copy$default$6
80 28867 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$9 config.copy$default$9
80 30377 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$4 config.copy$default$4
80 29698 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$8 config.copy$default$8
80 29456 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$3 config.mainSequence.copy$default$3
80 29420 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$11 config.copy$default$11
80 30156 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$8 config.mainSequence.copy$default$8
80 28756 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$7 config.mainSequence.copy$default$7
80 28932 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$10 config.mainSequence.copy$default$10
80 30224 3226 - 3311 Apply org.make.core.sequence.ExplorationSequenceConfiguration.copy config.mainSequence.copy(x$2, x$1, x$3, x$4, x$5, x$6, x$7, x$8, x$9, x$10)
80 28926 3266 - 3310 Select org.make.api.technical.sequence.SequenceCacheConfiguration.proposalsPoolSize sequenceCacheConfiguration.proposalsPoolSize
80 28585 3190 - 3312 Apply org.make.core.sequence.SequenceConfiguration.copy config.copy(x$12, x$11, x$13, x$14, x$15, x$16, x$17, x$18, x$19, x$20, x$21)
80 30254 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$1 config.mainSequence.copy$default$1
80 30161 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$7 config.copy$default$7
80 29464 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$1 config.copy$default$1
80 29063 3246 - 3246 Select org.make.core.sequence.ExplorationSequenceConfiguration.copy$default$4 config.mainSequence.copy$default$4
80 28716 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$6 config.copy$default$6
80 28952 3206 - 3206 Select org.make.core.sequence.SequenceConfiguration.copy$default$3 config.copy$default$3
81 30383 3351 - 3368 Apply org.make.api.sequence.SequenceCacheManager.simpleSequence simpleSequence(x$1, simpleSequence$default$2)
81 29608 3350 - 3350 Select scala.concurrent.ExecutionContext.Implicits.global scala.concurrent.ExecutionContext.Implicits.global
81 28722 3319 - 3369 ApplyToImplicitArgs scala.concurrent.Future.flatMap behaviour.apply(customConfig).flatMap[cats.data.NonEmptyList[org.make.core.proposal.indexed.IndexedProposal]](((x$1: org.make.api.sequence.SequenceBehaviour) => simpleSequence(x$1, simpleSequence$default$2)))(scala.concurrent.ExecutionContext.Implicits.global)
90 28889 3703 - 4871 Apply akka.actor.typed.scaladsl.Behaviors.setup org.make.api.sequence.sequencecachemanagertest akka.actor.typed.scaladsl.Behaviors.setup[org.make.api.sequence.SequenceCacheManager.Protocol](((context: akka.actor.typed.scaladsl.ActorContext[org.make.api.sequence.SequenceCacheManager.Protocol]) => { def getProposal(cmd: org.make.api.sequence.SequenceCacheManager.GetProposalCmd, replyTo: akka.actor.typed.ActorRef[org.make.core.proposal.indexed.IndexedProposal]): akka.actor.typed.Behavior[org.make.api.sequence.SequenceCacheManager.Protocol] = configCache.get(cmd.key) match { case scala.None => { val cache: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol] = context.spawn[org.make.api.sequence.SequenceCacheActor.Protocol](SequenceCacheActor.apply(reloadProposals.apply(cmd.key, cmd.behaviour), config), SequenceCacheActor.name(cmd.key), context.spawn$default$3[Nothing]); context.watchWith[org.make.api.sequence.SequenceCacheActor.Protocol](cache, SequenceCacheManager.this.ChildTerminated.apply(cmd.key)); typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](cache).!(SequenceCacheActor.GetProposal.apply(replyTo)); SequenceCacheManager.this.handleMessage(configCache.++[akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]](scala.Predef.Map.apply[org.make.api.sequence.SequenceCacheManager.CacheKey, akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]](scala.Predef.ArrowAssoc[org.make.api.sequence.SequenceCacheManager.CacheKey](cmd.key).->[akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]](cache))))(reloadProposals, config) } case (value: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]): Some[akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]]((actorRef @ _)) => { typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](actorRef).!(SequenceCacheActor.GetProposal.apply(replyTo)); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceCacheManager.Protocol] } }; akka.actor.typed.scaladsl.Behaviors.receiveMessage[org.make.api.sequence.SequenceCacheManager.Protocol](((x0$1: org.make.api.sequence.SequenceCacheManager.Protocol) => x0$1 match { case (cmd @ (_: org.make.api.sequence.SequenceCacheManager.GetProposalCmd)) => getProposal(cmd, cmd.replyTo) case SequenceCacheManager.this.ExpireChildren => { configCache.values.foreach[Unit](((ref: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]) => typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](ref).!(SequenceCacheActor.Expire))); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceCacheManager.Protocol] } case (key: org.make.api.sequence.SequenceCacheManager.CacheKey): org.make.api.sequence.SequenceCacheManager.ChildTerminated((questionId @ _)) => SequenceCacheManager.this.handleMessage(configCache.-(questionId))(reloadProposals, config) })) }))
92 28870 3859 - 3866 Select org.make.api.sequence.SequenceCacheManager.GetProposalCmd.key org.make.api.sequence.sequencecachemanagertest cmd.key
92 30298 3843 - 3867 Apply scala.collection.MapOps.get org.make.api.sequence.sequencecachemanagertest configCache.get(cmd.key)
95 29659 3984 - 3984 TypeApply akka.actor.typed.scaladsl.ActorContext.spawn$default$3 org.make.api.sequence.sequencecachemanagertest context.spawn$default$3[Nothing]
95 28899 3976 - 4140 Apply akka.actor.typed.scaladsl.ActorContext.spawn org.make.api.sequence.sequencecachemanagertest context.spawn[org.make.api.sequence.SequenceCacheActor.Protocol](SequenceCacheActor.apply(reloadProposals.apply(cmd.key, cmd.behaviour), config), SequenceCacheActor.name(cmd.key), context.spawn$default$3[Nothing])
96 29427 4042 - 4049 Select org.make.api.sequence.SequenceCacheManager.GetProposalCmd.key org.make.api.sequence.sequencecachemanagertest cmd.key
96 30344 4026 - 4065 Apply scala.Function2.apply org.make.api.sequence.sequencecachemanagertest reloadProposals.apply(cmd.key, cmd.behaviour)
96 29614 4007 - 4074 Apply org.make.api.sequence.SequenceCacheActor.apply org.make.api.sequence.sequencecachemanagertest SequenceCacheActor.apply(reloadProposals.apply(cmd.key, cmd.behaviour), config)
96 28590 4051 - 4064 Select org.make.api.sequence.SequenceCacheManager.GetProposalCmd.behaviour org.make.api.sequence.sequencecachemanagertest cmd.behaviour
97 30061 4092 - 4124 Apply org.make.api.sequence.SequenceCacheActor.name org.make.api.sequence.sequencecachemanagertest SequenceCacheActor.name(cmd.key)
97 28795 4116 - 4123 Select org.make.api.sequence.SequenceCacheManager.GetProposalCmd.key org.make.api.sequence.sequencecachemanagertest cmd.key
99 30303 4194 - 4201 Select org.make.api.sequence.SequenceCacheManager.GetProposalCmd.key org.make.api.sequence.sequencecachemanagertest cmd.key
99 29459 4178 - 4202 Apply org.make.api.sequence.SequenceCacheManager.ChildTerminated.apply org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.ChildTerminated.apply(cmd.key)
99 28552 4153 - 4203 Apply akka.actor.typed.scaladsl.ActorContext.watchWith org.make.api.sequence.sequencecachemanagertest context.watchWith[org.make.api.sequence.SequenceCacheActor.Protocol](cache, SequenceCacheManager.this.ChildTerminated.apply(cmd.key))
100 29578 4216 - 4263 Apply akka.actor.typed.ActorRef.ActorRefOps.! org.make.api.sequence.sequencecachemanagertest typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](cache).!(SequenceCacheActor.GetProposal.apply(replyTo))
100 30349 4224 - 4263 Apply org.make.api.sequence.SequenceCacheActor.GetProposal.apply org.make.api.sequence.sequencecachemanagertest SequenceCacheActor.GetProposal.apply(replyTo)
101 28798 4276 - 4327 ApplyToImplicitArgs org.make.api.sequence.SequenceCacheManager.handleMessage org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.handleMessage(configCache.++[akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]](scala.Predef.Map.apply[org.make.api.sequence.SequenceCacheManager.CacheKey, akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]](scala.Predef.ArrowAssoc[org.make.api.sequence.SequenceCacheManager.CacheKey](cmd.key).->[akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]](cache))))(reloadProposals, config)
103 30158 4384 - 4423 Apply org.make.api.sequence.SequenceCacheActor.GetProposal.apply org.make.api.sequence.sequencecachemanagertest SequenceCacheActor.GetProposal.apply(replyTo)
103 29243 4373 - 4423 Apply akka.actor.typed.ActorRef.ActorRefOps.! org.make.api.sequence.sequencecachemanagertest typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](actorRef).!(SequenceCacheActor.GetProposal.apply(replyTo))
104 28903 4436 - 4450 TypeApply akka.actor.typed.scaladsl.Behaviors.same org.make.api.sequence.sequencecachemanagertest akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceCacheManager.Protocol]
109 29314 4476 - 4865 Apply akka.actor.typed.scaladsl.Behaviors.receiveMessage org.make.api.sequence.sequencecachemanagertest akka.actor.typed.scaladsl.Behaviors.receiveMessage[org.make.api.sequence.SequenceCacheManager.Protocol](((x0$1: org.make.api.sequence.SequenceCacheManager.Protocol) => x0$1 match { case (cmd @ (_: org.make.api.sequence.SequenceCacheManager.GetProposalCmd)) => getProposal(cmd, cmd.replyTo) case SequenceCacheManager.this.ExpireChildren => { configCache.values.foreach[Unit](((ref: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]) => typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](ref).!(SequenceCacheActor.Expire))); akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceCacheManager.Protocol] } case (key: org.make.api.sequence.SequenceCacheManager.CacheKey): org.make.api.sequence.SequenceCacheManager.ChildTerminated((questionId @ _)) => SequenceCacheManager.this.handleMessage(configCache.-(questionId))(reloadProposals, config) }))
110 29417 4560 - 4589 Apply org.make.api.sequence.SequenceCacheManager.getProposal org.make.api.sequence.sequencecachemanagertest getProposal(cmd, cmd.replyTo)
110 30266 4577 - 4588 Select org.make.api.sequence.SequenceCacheManager.GetProposalCmd.replyTo org.make.api.sequence.sequencecachemanagertest cmd.replyTo
112 29584 4635 - 4730 Apply scala.collection.IterableOnceOps.foreach org.make.api.sequence.sequencecachemanagertest configCache.values.foreach[Unit](((ref: akka.actor.typed.ActorRef[org.make.api.sequence.SequenceCacheActor.Protocol]) => typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](ref).!(SequenceCacheActor.Expire)))
113 28643 4691 - 4716 Select org.make.api.sequence.SequenceCacheActor.Expire org.make.api.sequence.sequencecachemanagertest SequenceCacheActor.Expire
113 30413 4685 - 4716 Apply akka.actor.typed.ActorRef.ActorRefOps.! org.make.api.sequence.sequencecachemanagertest typed.this.ActorRef.ActorRefOps[org.make.api.sequence.SequenceCacheActor.Protocol](ref).!(SequenceCacheActor.Expire)
115 28718 4743 - 4757 TypeApply akka.actor.typed.scaladsl.Behaviors.same org.make.api.sequence.sequencecachemanagertest akka.actor.typed.scaladsl.Behaviors.same[org.make.api.sequence.SequenceCacheManager.Protocol]
117 30127 4816 - 4855 ApplyToImplicitArgs org.make.api.sequence.SequenceCacheManager.handleMessage SequenceCacheManager.this.handleMessage(configCache.-(questionId))(reloadProposals, config)
122 30276 4938 - 4938 Select scalacache.CacheConfig.defaultCacheConfig org.make.api.sequence.sequencecachemanagertest scalacache.this.CacheConfig.defaultCacheConfig
122 29425 4928 - 4954 ApplyToImplicitArgs scalacache.guava.GuavaCache.apply org.make.api.sequence.sequencecachemanagertest scalacache.guava.GuavaCache.apply[org.make.api.sequence.SequenceBehaviour.ConsensusParam](scalacache.this.CacheConfig.defaultCacheConfig)
141 28622 5533 - 5535 Select org.make.api.sequence.SequenceCacheManager.GetProposal.id org.make.api.sequence.sequencecachemanagertest GetProposal.this.id
141 30338 5537 - 5558 Select org.make.core.sequence.SequenceKind.Standard org.make.api.sequence.sequencecachemanagertest org.make.core.sequence.SequenceKind.Standard
141 29559 5524 - 5559 Apply org.make.api.sequence.SequenceCacheManager.CacheKey.apply org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.CacheKey.apply(GetProposal.this.id, org.make.core.sequence.SequenceKind.Standard)
143 30133 5688 - 5690 Literal <nosymbol> ()
143 28834 5716 - 5720 Select scala.None scala.None
143 29237 5700 - 5714 Select org.make.api.sequence.SequenceCacheManager.CacheKey.questionId GetProposal.this.key.questionId
143 29389 5628 - 5722 Apply scala.concurrent.Future.successful scala.concurrent.Future.successful[org.make.api.sequence.SequenceBehaviour](SequenceBehaviourProvider.apply[Unit](sequence.this.SequenceBehaviourProvider.standard).behaviour((), config, GetProposal.this.key.questionId, scala.None))
143 28692 5671 - 5671 Select org.make.api.sequence.SequenceBehaviourProvider.standard sequence.this.SequenceBehaviourProvider.standard
143 30301 5646 - 5721 Apply org.make.api.sequence.SequenceBehaviourProvider.behaviour SequenceBehaviourProvider.apply[Unit](sequence.this.SequenceBehaviourProvider.standard).behaviour((), config, GetProposal.this.key.questionId, scala.None)
152 29520 5941 - 5977 Apply org.make.api.sequence.SequenceCacheManager.CacheKey.apply SequenceCacheManager.this.CacheKey.apply(GetConsensusProposal.this.id, org.make.core.sequence.SequenceKind.Consensus)
152 28628 5950 - 5952 Select org.make.api.sequence.SequenceCacheManager.GetConsensusProposal.id GetConsensusProposal.this.id
152 29930 5954 - 5976 Select org.make.core.sequence.SequenceKind.Consensus org.make.core.sequence.SequenceKind.Consensus
154 28796 6065 - 6074 Select org.make.api.sequence.SequenceCacheManager.GetConsensusProposal.threshold GetConsensusProposal.this.threshold
154 28661 6046 - 6195 ApplyToImplicitArgs scala.concurrent.Future.map SequenceCacheManager.this.getCachedThreshold(GetConsensusProposal.this.threshold).map[org.make.api.sequence.SequenceBehaviour](((param: org.make.api.sequence.SequenceBehaviour.ConsensusParam) => SequenceBehaviourProvider.apply[org.make.api.sequence.SequenceBehaviour.ConsensusParam](sequence.this.SequenceBehaviourProvider.consensus).behaviour(param, config, GetConsensusProposal.this.key.questionId, scala.None)))(scala.concurrent.ExecutionContext.Implicits.global)
154 29494 6080 - 6080 Select scala.concurrent.ExecutionContext.Implicits.global scala.concurrent.ExecutionContext.Implicits.global
155 30264 6099 - 6187 Apply org.make.api.sequence.SequenceBehaviourProvider.behaviour SequenceBehaviourProvider.apply[org.make.api.sequence.SequenceBehaviour.ConsensusParam](sequence.this.SequenceBehaviourProvider.consensus).behaviour(param, config, GetConsensusProposal.this.key.questionId, scala.None)
155 29241 6166 - 6180 Select org.make.api.sequence.SequenceCacheManager.CacheKey.questionId GetConsensusProposal.this.key.questionId
155 30099 6124 - 6124 Select org.make.api.sequence.SequenceBehaviourProvider.consensus sequence.this.SequenceBehaviourProvider.consensus
155 28839 6182 - 6186 Select scala.None scala.None
161 28763 6359 - 6397 Apply org.make.api.sequence.SequenceCacheManager.CacheKey.apply org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.CacheKey.apply(GetControversyProposal.this.id, org.make.core.sequence.SequenceKind.Controversy)
161 29935 6368 - 6370 Select org.make.api.sequence.SequenceCacheManager.GetControversyProposal.id org.make.api.sequence.sequencecachemanagertest GetControversyProposal.this.id
161 29524 6372 - 6396 Select org.make.core.sequence.SequenceKind.Controversy org.make.api.sequence.sequencecachemanagertest org.make.core.sequence.SequenceKind.Controversy
163 28620 6466 - 6607 Apply scala.concurrent.Future.successful scala.concurrent.Future.successful[org.make.api.sequence.SequenceBehaviour](SequenceBehaviourProvider.apply[org.make.core.proposal.indexed.Zone.Controversy.type](sequence.this.SequenceBehaviourProvider.controversy).behaviour(org.make.core.proposal.indexed.Zone.Controversy, config, GetControversyProposal.this.key.questionId, scala.None))
164 28419 6578 - 6592 Select org.make.api.sequence.SequenceCacheManager.CacheKey.questionId GetControversyProposal.this.key.questionId
164 29468 6493 - 6599 Apply org.make.api.sequence.SequenceBehaviourProvider.behaviour SequenceBehaviourProvider.apply[org.make.core.proposal.indexed.Zone.Controversy.type](sequence.this.SequenceBehaviourProvider.controversy).behaviour(org.make.core.proposal.indexed.Zone.Controversy, config, GetControversyProposal.this.key.questionId, scala.None)
164 30269 6594 - 6598 Select scala.None scala.None
164 30179 6518 - 6518 Select org.make.api.sequence.SequenceBehaviourProvider.controversy sequence.this.SequenceBehaviourProvider.controversy
164 29344 6552 - 6568 Select org.make.core.proposal.indexed.Zone.Controversy org.make.core.proposal.indexed.Zone.Controversy
171 29939 6751 - 6775 Literal <nosymbol> org.make.api.sequence.sequencecachemanagertest "sequence-cache-manager"
172 28771 6828 - 6844 ApplyToImplicitArgs akka.actor.typed.receptionist.ServiceKey.apply org.make.api.sequence.sequencecachemanagertest akka.actor.typed.receptionist.ServiceKey.apply[org.make.api.sequence.SequenceCacheManager.Protocol](SequenceCacheManager.this.name)((ClassTag.apply[org.make.api.sequence.SequenceCacheManager.Protocol](classOf[org.make.api.sequence.SequenceCacheManager$$Protocol]): scala.reflect.ClassTag[org.make.api.sequence.SequenceCacheManager.Protocol]))
172 29557 6839 - 6843 Select org.make.api.sequence.SequenceCacheManager.name org.make.api.sequence.sequencecachemanagertest SequenceCacheManager.this.name