Grails обещает потерю данных - по-видимому, не дожидаясь завершения друг друга
Следующие случайные вызовы getParentCustomers
или getAccountManagers
первый. Когда он это делает, он работает нормально. Однако то, что называется вторым, проходит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])
})
...
Однако я все равно получаю тот же результат.
ПРИМЕЧАНИЕ: Это тоже случайно. Иногда это работает нормально - передача одного и того же списка обоим методам. Но когда он ломается, всегда тот, кто срабатывает вторым.
Есть мысли по этому поводу?
2 ответа
Так что я думаю, что в редких случаях многопоточность немного срабатывала, поэтому я удалил отдельные потоки между getParentCustomers и getAccountManager, поскольку они все равно не делают внешних вызовов.
Я думаю, что одновременное использование 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() })
}
Приведенное ниже решение пока работает. Однако я понятия не имею, почему ни один из вышеперечисленных блоков кода этого не делает.
Какие-нибудь мысли?
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() })
}