Grails承诺会丢失数据-似乎不等待对方完成

问题描述 投票:0回答:2

以下内容首先随机调用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
2个回答
0
投票

下面的解决方案目前正在起作用。但是,我不知道为什么以上两个代码块都没有。

有什么想法吗?

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() })
}

0
投票

因此,我认为线程在极少数情况下表现不佳,因此我删除了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() })
}
© www.soinside.com 2019 - 2024. All rights reserved.