Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Alpakka with Cloud PubSub

Alpakka with Cloud PubSub

masaki toyoshima

August 03, 2018
Tweet

More Decks by masaki toyoshima

Other Decks in Programming

Transcript

  1. Alpakka AkkaStream Connector for integration! AMQP, MQTT, SQS, SNS, Kinesis,

    Cloud PubSub, Azure Event Hub, Firebase cloud messaging, S3, Kafka, MongoDB, HBase, Slick, HTTP, TCP, etc,...
  2. Alpakka AkkaStream Connector for integration! AMQP, MQTT, SQS, SNS, Kinesis,

    Cloud PubSub, Azure Event Hub, Firebase cloud messaging, S3, Kafka, MongoDB, HBase, Slick, HTTP, TCP, etc,...
  3. (1 to 3) .map{ i => println(s"A: $i"); i }

    .map{ i => println(s"B: $i"); i } .map{ i => println(s"C: $i"); i } A:1 A:2 A:3 B:1 B:2 B:3 C:1 C:2 C:3 普通のScalaのコレクション
  4. Source(1 to 3) .map{ i => println(s"A: $i"); i }

    .map{ i => println(s"B: $i"); i } .map{ i => println(s"C: $i"); i } .runWith(Sink.ignore) A:1 A:2 B:1 A:3 B:2 C:1 B:3 C:2 C:3 Akka Stream
  5. Alpakka AkkaStream Connector for integration! AMQP, MQTT, SQS, SNS, Kinesis,

    Cloud PubSub, Azure Event Hub, Firebase cloud messaging, S3, Kafka, MongoDB, HBase, Slick, HTTP, TCP, etc,...
  6. public interface MessageReceiver { void receiveMessage( final PubsubMessage message, final

    AckReplyConsumer consumer ); } 〜Subscribe編〜 1件のmessageをどう処理するか、という処理モデル
  7. val subscriptionSource: Source[ReceivedMessage, NotUsed] = GooglePubSub.subscribe(projectId, apiKey, email, privateKey, subscription)

    val ackSink: Sink[AcknowledgeRequest, Future[Done]] = GooglePubSub.acknowledge(projectId, apiKey, email, privateKey, subscription) subscriber用に提供されているのはSourceとSink Soruceは最大1000件のMessageがくる Sinkは入ってきたやつのackを返す
  8. val subscriptionSource: Source[ReceivedMessage, NotUsed] = GooglePubSub.subscribe(projectId, apiKey, email, privateKey, subscription)

    val ackSink: Sink[AcknowledgeRequest, Future[Done]] = GooglePubSub.acknowledge(projectId, apiKey, email, privateKey, subscription) val doneF: Future[Done] = subscriptionSource .grouped(3) .map(msgs => AcknowledgeRequest(msgs.map(_.ackId))) .runWith(ackSink) Flow部分はアプリケーション固有の処理を。 ここでは単純に3件ずつの固まりにしてただack返すだけ
  9. val publishFlow: Flow[PublishRequest, Seq[String], NotUsed] = GooglePubSub.publish(projectId, apiKey, clientEmail, privateKey,

    topic) publisher用に提供されているのはFlow PublishRequestをinputにpublish実行してくれ その際、採番されたidがoutputとなる
  10. val publishFlow: Flow[PublishRequest, Seq[String], NotUsed] = GooglePubSub.publish(projectId, apiKey, clientEmail, privateKey,

    topic) val source: Source[PublishRequest, NotUsed] = { val msgs = (1 to 10).map { i => PubSubMessage( messageId = i.toString, data = new String(Base64.getEncoder.encode("Hello".getBytes)) )} Source.single(PublishRequest(msgs)) } val publishedMessageIds: Future[Done] = source.via(publishFlow).runWith(Sink.ignore)
  11. def pull(project: String, subscription: String, maybeAccessToken: Option[String], apiKey: String)( implicit

    as: ActorSystem, materializer: Materializer ): Future[PullResponse] = { import materializer.executionContext val uri: Uri = s"$PubSubGoogleApisHost/v1/projects/$project/subscriptions/$subscription:pull" val request = HttpApi.PullRequest(returnImmediately = true, maxMessages = 1000) PubSub用alpakkaライブラリの中身 Java API使ってると思いこんでたけど Cloud PubSubのWEB API呼んでるだけだった