Я пытаюсь реализовать прослушиватель записи в Map Scala.Реализация приемника ввода карты
Идея:
- мне нужно подписаться на карте от службы.
- Мне нужно уведомить всех подписчиков Карты, когда добавляется/обновляется запись с определенным ключом.
- Мне нужно иметь доступ к Карте из других служб, чтобы проверить значение записи.
Я не смог найти готовое решение для этого, поэтому я пытался реализовать его с Акки:
class TrackingService(system: ActorSystem) extends LazyLogging {
private val trackingActor = system.actorOf(TrackingActor.props)
private val duration = Duration(15, TimeUnit.SECONDS)
private implicit val timeout = Timeout(duration)
def fireEvent(key: String): Unit = {
TrackingActor ! EventFired(key)
}
def eventHappened(key: String): Future[Boolean] = {
TrackingActor ? DoesEventHappened(key)).mapTo[Boolean]
}
def registerHiddenCardListener(key: String, data: MyData): Unit = {
TrackingActor ! Subscribe(key, data)
}
}
case class EventFired(key: String)
case class EventHappened(key: String)
case class EventHappenedResponse(happened: Boolean)
case class Subscribe(key: String, data: Data)
class TrackingActor extends Actor with LazyLogging {
var eventMap: Map[String, Boolean] = Map.empty[String, Boolean]
var dataMap: Map[String, List[Data]] = Map.empty[String, List[Data]]
def receive: Receive = {
case Subscribe(key, data) =>
val currentData: List[Data] = dataMap.getOrElse(key, Nil)
val newData = data :: currentData
dataMap = dataMap + (key -> newData)
case EventHappened(key) => sender() ! EventHappenedResponse(eventMap.getOrElse(key, false))
case [email protected](key) =>
eventMap = eventMap + (key -> true)
for {
dataOpt <- dataMap.get(key)
data <- dataOpt
} {
// do callback with data (e.g. send email)
}
case x => logger.warn(s"Received unknown message: $x")
}
}
object TrackingActor {
def props: Props = Props(classOf[TrackingActor])
}
Что мне не нравится в этом решении: Я не люблю спрашивать шаблон, но мне нужно иметь доступ к записям из неактивных классов. Кроме того, мне не нравится иметь 2 карты, но мне нужно хранить где-то данные, которые следует использовать для обратного вызова.
Любые идеи о том, как я могу улучшить это?