在Scala中使用AWS Java SDK V2时处理异步调用的更好方法? 背景
几天前,AWS Java SDK的版本在Scala中使用AWS Java SDK V2时处理异步调用的更好方法? 背景,scala,amazon-web-services,aws-sdk,amazon-sns,aws-java-sdk,Scala,Amazon Web Services,Aws Sdk,Amazon Sns,Aws Java Sdk,几天前,AWS Java SDK的版本2.1正式发布。与以前版本的SDK相比,它的主要卖点之一是如何处理异步调用 我决定使用Scala和新的SDK进行一些实验,但为了想出一种惯用的方法来处理SDK返回的未来,我经历了一些困难 问题 有没有一种方法可以让我用更少的样板代码做得更好、更成功 客观的 使用Scala处理AWS SDK for Java V2,并能够以惯用的方式处理成功和失败 实验 创建异步SNS客户端并异步提交消息500: 实验1-使用SDK返回的CompletableFuture 在
2.1
正式发布。与以前版本的SDK相比,它的主要卖点之一是如何处理异步调用
我决定使用Scala和新的SDK进行一些实验,但为了想出一种惯用的方法来处理SDK返回的未来,我经历了一些困难
问题
有没有一种方法可以让我用更少的样板代码做得更好、更成功
客观的
使用Scala处理AWS SDK for Java V2,并能够以惯用的方式处理成功和失败
实验
创建异步SNS客户端并异步提交消息500:
实验1-使用SDK返回的CompletableFuture
在这里,我创建一个唯一的请求并发布它。whenComplete
函数将响应转换为选项,因为该值可以为空。这很难看,因为处理成功/失败的方法必须检查响应中的null
实验2-在Scala Future中获得结果
在这里,我在CompletableFuture
上使用.get()
方法,这样我就可以处理Scala Future了
实验3-使用Scala-Java8-Compat
库将CompletableFuture
转换为Future
这是到目前为止我最喜欢的实现,只是我需要使用第三方
观察
- 总的来说,所有这些实现的执行速度大致相同,
比其他实现快一点点李>future.join()
- 这些函数初始化客户端并发布500条消息所用的时间约为2秒
- 此代码的顺序版本需要不到1分钟(55秒)的时间
- 您可以看到完整的代码
object CompletableFutureOps {
implicit class CompletableFutureToScala[T](cf: CompletableFuture[T]) {
def asScala: Future[T] = {
val p = Promise[T]()
cf.whenCompleteAsync{ (result, ex) =>
if (result == null) p failure ex
else p success result
}
p.future
}
}
}
def showByExample: Unit = {
import CompletableFutureOps._
(0 until 500).map { i =>
val f = CompletableFuture.supplyAsync(() => i).asScala
f.onComplete {
case Success(response) => println("Success: " + response)
case Failure(exception) => println(exception.getMessage)
}
f
}.foreach(Await.result(_, 5000.millis))
}
尽管
scala-java8-compat
自述文件仍然声明“该API目前仍处于试验阶段:我们还不能保证与未来版本的源代码或二进制兼容”,但它是scala作者工作的一部分,因此并不是真正的第三方。
(0 until 500).map { i =>
val jf = client.publish(PublishRequest.builder().topicArn(arn).message(messageScala + i.toString).build())
val sf: Future[PublishResponse] = Future { jf.get }
sf.onComplete {
case Success(response) => print(response.messageId)
case Failure(ex) => println(s"There was an error ${ex.getMessage}")
}
sf
}.foreach(Await.result(_, 5000.millis))
(0 until 500).map { i =>
val f = client.publish(PublishRequest.builder().topicArn(arn).message(messageScala + i.toString).build()).toScala
f.onComplete {
case Success(response) =>
case Failure(exception) => println(exception.getMessage)
}
f
}.foreach(Await.result(_, 5000.millis))
object CompletableFutureOps {
implicit class CompletableFutureToScala[T](cf: CompletableFuture[T]) {
def asScala: Future[T] = {
val p = Promise[T]()
cf.whenCompleteAsync{ (result, ex) =>
if (result == null) p failure ex
else p success result
}
p.future
}
}
}
def showByExample: Unit = {
import CompletableFutureOps._
(0 until 500).map { i =>
val f = CompletableFuture.supplyAsync(() => i).asScala
f.onComplete {
case Success(response) => println("Success: " + response)
case Failure(exception) => println(exception.getMessage)
}
f
}.foreach(Await.result(_, 5000.millis))
}