这段代码可以翻译成有状态的akka​​流吗?

时间:2017-09-10 12:42:55

标签: akka amazon-sqs akka-stream

enter image description here我正在尝试使用akka流监听sqs并从中获取消息q 使用此代码段:

当然这段代码片段一个接一个地获取消息(然后确认):

implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(ioThreadPoolSize))
val awsSqsClient: AmazonSQSAsync = AmazonSQSAsyncClientBuilder
  .standard()
  .withCredentials(new ClasspathPropertiesFileCredentialsProvider())
  .withEndpointConfiguration(new EndpointConfiguration(sqsEndpoint, configuration.regionName))
  .build()

val future = SqsSource(sqsEndpoint)(awsSqsClient)
  .takeWhile(_ => true)
  .mapAsync(parallelism = 2)(m => {
    val msgBody = SqsMessage.deserializeJson(m.getBody)
    msgBody match {
      case Right(body) => val id = getId(body) //do some stuff with the message may save state according the id
    }
    Future(m, Ack())
  })
  .to(SqsAckSink(sqsEndpoint)(awsSqsClient))
  .run()

我的问题是: 我可以获得多条消息,并将它们保存在例如有状态的地图中供以后使用吗?

例如,在收到5条消息后(所有这些消息都将被保存(每个州))

然后,如果特定条件发生,我会全部解决它们,如果不是,它们将返回队列(无论如何都会发生,因为可见性超时)?

感谢。

1 个答案:

答案 0 :(得分:0)

可能是您正在寻找grouped(或groupedWithin)组合子。这些允许您批量处理邮件并按组处理它们。 groupedWithin允许您在一定时间后发布批次,以防它尚未达到您确定的大小。文档参考here

在随后的检查流程中,您可以执行所需的任何逻辑,并在您希望消息被激活时发出序列,否则不发出它们。

示例:

  val yourCheck: Flow[Seq[MessageActionPair], Seq[MessageActionPair], NotUsed] = ???

  val future = SqsSource(sqsEndpoint)(awsSqsClient)
    .takeWhile(_ => true)
    .mapAsync(parallelism = 2){ ... }
    .grouped(5)
    .via(yourCheck)
    .mapConcat(identity)
    .to(SqsAckSink(sqsEndpoint)(awsSqsClient))
    .run()