From 43221fc7e29476d796bf9979cedb037b4eccc671 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 5 May 2016 16:47:27 +0300 Subject: [PATCH] sstables: make delete_atomically() throw a distinct exception when cancelled Throwing a runtime_error makes it impossible to catch the cancellation exception, so replace it with a distinct exception class. --- sstables/sstables.cc | 16 ++++++++++++++-- sstables/sstables.hh | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/sstables/sstables.cc b/sstables/sstables.cc index efc833b4ee..64932f444e 100644 --- a/sstables/sstables.cc +++ b/sstables/sstables.cc @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -2048,7 +2049,9 @@ do_delete_atomically(std::vector atomic_deletion_set, unsigne if (g_atomic_deletions_cancelled) { deletion_logger.debug("atomic deletions disabled, erroring out"); - throw std::runtime_error(sprint("atomic deletions disabled; not deleting %s", atomic_deletion_set)); + using boost::adaptors::transformed; + throw atomic_deletion_cancelled(atomic_deletion_set + | transformed(std::mem_fn(&sstable_to_delete::name))); } // Insert atomic_deletion_set into the list of sets pending deletion. If the new set @@ -2143,11 +2146,20 @@ cancel_atomic_deletions() { g_atomic_deletions_cancelled = true; for (auto&& pd : g_atomic_deletion_sets) { for (auto&& c : pd->completions) { - c->set_exception(std::runtime_error(sprint("Atomic sstable deletions cancelled; not deleting %s", pd->names))); + c->set_exception(atomic_deletion_cancelled(pd->names)); } } g_atomic_deletion_sets.clear(); g_shards_agreeing_to_delete_sstable.clear(); } +atomic_deletion_cancelled::atomic_deletion_cancelled(std::vector names) + : _msg(sprint("atomic deletions cancelled; not deleting %s", names)) { +} + +const char* +atomic_deletion_cancelled::what() const noexcept { + return _msg.c_str(); +} + } diff --git a/sstables/sstables.hh b/sstables/sstables.hh index 9aa116e1e8..f39bb9b762 100644 --- a/sstables/sstables.hh +++ b/sstables/sstables.hh @@ -605,12 +605,26 @@ struct sstable_to_delete { // shared among shard, so actual on-disk deletion of an sstable is deferred // until all shards agree it can be deleted. // +// When shutting down, we will not be able to complete some deletions. +// In that case, an atomic_deletion_cancelled exception is returned instead. +// // This function only solves the second problem for now. future<> delete_atomically(std::vector ssts); future<> delete_atomically(std::vector ssts); +class atomic_deletion_cancelled : public std::exception { + std::string _msg; +public: + explicit atomic_deletion_cancelled(std::vector names); + template + explicit atomic_deletion_cancelled(StringRange range) + : atomic_deletion_cancelled(std::vector{range.begin(), range.end()}) { + } + const char* what() const noexcept override; +}; + // Cancel any deletions scheduled by delete_atomically() and make their -// futures complete +// futures complete (with an atomic_deletion_cancelled exception). void cancel_atomic_deletions(); }