libplanet
libplanet copied to clipboard
`IStore` crashes when `Swarm<T>` shuts down
Context
According to a report from TarogStar. IStore seems to crash when stopping the node.
Problem
https://github.com/planetarium/NineChronicles.Headless/blob/c5d2f8dff819c8d737db91fd2a4ae884dfc5df0f/Libplanet.Headless/Hosting/LibplanetNodeService.cs#L306-L318
When stopping NineChronicles.Headless, Swarm<T>.StopAsync() is called here. But
https://github.com/planetarium/libplanet/blob/977a79462cfe47b88606d6ef4e69b989b297a544/Libplanet.Net/Swarm.cs#L187-L204
Swarm<T>._workerCancellationTokenSoruce is not calling cancel when Swarm<T>.StopAsync()
https://github.com/planetarium/libplanet/blob/977a79462cfe47b88606d6ef4e69b989b297a544/Libplanet.Net/Swarm.cs#L168-L178
Instead, call Swarm<T>._workerCancellationTokenSource.Cancel() in Swarm<T>.Dispose()
https://github.com/planetarium/NineChronicles.Headless/blob/c5d2f8dff819c8d737db91fd2a4ae884dfc5df0f/Libplanet.Headless/Hosting/LibplanetNodeService.cs#L641-L650
The problem is, Dispose doesn't exist to terminate an asynchronous worker task. A request to cancel an asynchronous operation, called at Dispose time, does not guarantee that the asynchronous operation has completely terminated. Therefore, at the time of disposing of IStore that is called after that, a problem may occur when the asynchronous operations access the Disposed Store. And this can also cause problems with the DB used by the store's backend.
This issue has been automatically marked as stale because it has not had recent activity. Thank you for your contributions.