Grails异步框架-使用Promises合并通过REST调用获取的数据

时间:2018-06-20 10:36:13

标签: asynchronous grails promise grails3

在我的Grails 3.3 Web应用程序中,我需要将对不同群集/位置的多个REST调用的响应合并到一个变量中。

作为快速原型,我使用了线程。

注意:在下面的所有示例中,我都从每个集群中收集ID列表,为简单起见,我使用的是单个集群(属于Cluster域类)。

List<Cluster> clusters = Cluster.findAllByIdInList(['london'])

CopyOnWriteArrayList ids = []

// ↓ to refactor
List<Thread> threads = []
clusters.each { Cluster cluster ->
  Thread t = new Thread() {
    public void run() {
      ClusterDownloader.ListResponse res = ClusterDownloader.getIds(cluster)
      println "Thread $cluster.id - $res"
      def clusterIds = (List) res.id ?: []
      ids.addAll(clusterIds)
    }
  }
  threads.add(t)
  t.start()
}
for(Thread t: threads)
  t.join()

println "++ $ids"
// ↑

在这种情况下,标准输出如预期的那样显示:

Thread london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
++ [01641c64b178c0a8520e17bc75d5728541b3]

我对Grails Async框架有所了解,并尝试将上述代码重构为:

// ↓ refactored
PromiseList promises = []
clusters.each { Cluster cluster ->
  Promise p = Promises.task {
    ClusterDownloader.getIds(cluster)
  }
  p.onComplete { ClusterDownloader.ListResponse res ->
    println "onComplete START $cluster.id - $res"
    def clusterIds = (List) res.id ?: []
    ids.addAll(clusterIds)
    println "onComplete END   $cluster.slug - $ids"
  }
  promises.add(p)
}

println "++ 1 ++ $ids"
Promises.waitAll(promises)
println "++ 2 ++ $ids"
// ↑

但在这种情况下,输出为:

++ 1 ++ []
++ 2 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3]

好像.waitAll方法在返回london集群的响应后,但在执行onComplete之前释放。 这实际上不是我所期望的,所以我尝试将onComplete方法链接到task定义:

Promise p = Promises.task { ... }
                    .onComplete { ... }

但是后来,我得到了甚至更奇怪的结果,似乎是println的半随机组合:

1.a。 onComplete的两次执行,id翻倍

++ 1 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
++ 2 ++ [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]

1.b。上面的变种

++ 1 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
++ 2 ++ [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]

2-两次执行,第二次不参与结果

++ 1 ++ []
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3]
++ 2 ++ [01641c64b178c0a8520e17bc75d5728541b3]
onComplete START london - [[id:01641c64b178c0a8520e17bc75d5728541b3,time:1529484934104]]
onComplete END   london - [01641c64b178c0a8520e17bc75d5728541b3, 01641c64b178c0a8520e17bc75d5728541b3]

我想我真的在这里缺少什么,真的很欢迎任何帮助。预先感谢!

0 个答案:

没有答案