mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-22 01:20:39 +00:00
Commitaba475fe1daccidentally fixed a race, which happens in the following sequence of events: 1) storage service starts drain() via API for example 2) main's abort source is triggered, calling compaction_manager's do_stop() via subscription. 2.1) do_stop() initiates the stop but doesn't wait for it. 2.2) compaction_manager's state is set to stopped, such that compaction_manager::stop() called in defer_verbose_shutdown() will wait for the stop and not start a new one. 3) drain() calls compaction_manager::drain() changing the state from stopped to disabled. 4) main calls compaction_manager::stop() (as described in 2.2) and incorrectly tries to stop the manager again, because the state was changed in step 3.aba475fe1daccidentally fixed this problem because drain() will no longer take place if it detects the shutdown process was initiated (it does so by ignoring drain request if abort source's subscription was unlinked). This shows us that looking at the state to determine if stop should be performed is fragile, because once the state changes from A to B, manager doesn't know the state was A. To make it robust, we can instead check if the future that stores stop's promise is engaged, meaning that the stop was already initiated and we don't have to start a new one. Signed-off-by: Raphael S. Carvalho <raphaelsc@scylladb.com> Closes #11711