【问题标题】:Grails promises losing data - seemingly not waiting for each other to completeGrails 承诺丢失数据 - 似乎不等待对方完成
【发布时间】:2020-04-15 18:12:37
【问题描述】:

以下先随机调用getParentCustomersgetAccountManagers。当它运行时,它工作正常。但是,无论哪个被调用,第二个都会将null 传递给它。这些方法都不会以任何方式改变传入的值。我猜想有一些关于这些的上下文被调用的原因是指向response.salesChannels 的原始指针在任务之间丢失了。

Map response = [
    salesChannels:   null,
    accountManagers: null,
    parentCustomers: null,
    isrs:            null,
    operatingUnits:  null,
    businessUnits:   null
]

def t1 = task {
    response.salesChannels = salesChannelApiService.get(salesChannel)

    def t1a = task {
        response.parentCustomers = salesChannelTransformService.getParentCustomers(response.salesChannels)
    }
    def t1b = task {
        response.accountManagers = salesChannelTransformService.getAccountManagers(response.salesChannels)
    }

    waitAll([t1a, t1b])
}

def t2 = task {
    //... other stuff
}

def t3 = task {
    //... other stuff
}

waitAll([t1, t2, t3])

return response

我什至尝试修改内部结构以利用 onComplete

...
onComplete([task {
    return salesChannelApiService.get(salesChannel)
}], { salesChannels ->
    response.salesChannels = salesChannels

    def t1a = task {
        response.parentCustomers = salesChannelTransformService.getParentCustomers(salesChannels)
    }
    def t1b = task {
        response.accountManagers = salesChannelTransformService.getAccountManagers(salesChannels)
    }

    waitAll([t1a, t1b])
})
...

但是,我仍然得到相同的结果。

注意:这也是随机的。有时它工作正常 - 将相同的列表传递给两种方法。但当它破裂时,总是先触发第二个。

对此有什么想法吗?

【问题讨论】:

    标签: grails promise grails-3.2


    【解决方案1】:

    目前,以下解决方案正在运行。但是,我不知道为什么上述代码块都没有。

    有什么想法吗?

    def t1 = createPromise()
    
    task {
        response.salesChannels = salesChannelApiService.get(salesChannel)
    
        def t1a = createPromise()
        def t1b = createPromise()
    
        task {
            response.parentCustomers = salesChannelTransformService.getParentCustomers(response.salesChannels)
            t1a.accept()
        }
        task {
            response.accountManagers = salesChannelTransformService.getAccountManagers(response.salesChannels)
            t1b.accept()
        }
    
        onComplete([t1a, t1b], { a, b -> t1.accept() })
    }
    

    【讨论】:

      【解决方案2】:

      所以我认为线程在极少数情况下会出现问题,因此我删除了 getParentCustomers 和 getAccountManagers 之间的单独线程,因为它们无论如何都不会进行外部调用。

      我认为跨线程同时使用 response.salesChannels 会扰乱 response.salesChannels 的内存分配 - 并且每隔几百次调用就会随机抛出一个空指针异常。

      这似乎更可靠。

      def t1 = createPromise()
      
      task {
          response.salesChannels = salesChannelApiService.get(salesChannel)
      
          def t1a = createPromise()
      
          task {
              response.parentCustomers = salesChannelTransformService.getParentCustomers(response.salesChannels)
              response.accountManagers = salesChannelTransformService.getAccountManagers(response.salesChannels)
              t1a.accept()
          }
      
          onComplete([t1a], { a -> t1.accept() })
      }
      

      【讨论】:

        猜你喜欢
        • 2017-06-17
        • 2018-03-05
        • 1970-01-01
        • 1970-01-01
        • 2016-10-16
        • 2021-01-23
        • 1970-01-01
        相关资源
        最近更新 更多