Grails обещает потерять данные - похоже, не дожидаясь завершения друг друга - PullRequest
0 голосов
/ 15 апреля 2020

Следующий случайный вызов сначала 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 ]

0 голосов
/ 16 апреля 2020

Так что я думаю, что в редких случаях многопоточность работала немного, поэтому я удалил отдельные потоки между 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() })
}
0 голосов
/ 15 апреля 2020

Приведенное ниже решение пока работает. Тем не менее, я понятия не имею, почему ни один из вышеперечисленных блоков кода не делает.

Есть мысли?

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() })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...