Skip to content

Commit

Permalink
feat(server): Replication errors & cancellation (#501)
Browse files Browse the repository at this point in the history
  • Loading branch information
dranikpg authored Nov 22, 2022
1 parent 77ed4a2 commit 893c741
Show file tree
Hide file tree
Showing 14 changed files with 543 additions and 199 deletions.
77 changes: 77 additions & 0 deletions src/server/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <absl/strings/str_cat.h>
#include <absl/types/span.h>

#include <atomic>
#include <boost/fiber/mutex.hpp>
#include <string_view>
#include <vector>
Expand Down Expand Up @@ -197,6 +198,82 @@ using AggregateStatus = AggregateValue<facade::OpStatus>;
static_assert(facade::OpStatus::OK == facade::OpStatus{},
"Default intitialization should be OK value");

// Re-usable component for signaling cancellation.
// Simple wrapper around atomic flag.
struct Cancellation {
void Cancel() {
flag_.store(true, std::memory_order_relaxed);
}

bool IsCancelled() const {
return flag_.load(std::memory_order_relaxed);
}

private:
std::atomic_bool flag_;
};

// Error wrapper, that stores error_code and optional string message.
class GenericError {
public:
GenericError() = default;
GenericError(std::error_code ec) : ec_{ec}, details_{} {
}
GenericError(std::error_code ec, std::string details) : ec_{ec}, details_{std::move(details)} {
}

std::pair<std::error_code, const std::string&> Get() const {
return {ec_, details_};
}

std::error_code GetError() const {
return ec_;
}

const std::string& GetDetails() const {
return details_;
}

operator bool() const {
return bool(ec_);
}

private:
std::error_code ec_;
std::string details_;
};

using AggregateGenericError = AggregateValue<GenericError>;

// Contest combines Cancellation and AggregateGenericError in one class.
// Allows setting an error_handler to run on errors.
class Context : public Cancellation {
public:
// The error handler should return false if this error is ignored.
using ErrHandler = std::function<bool(const GenericError&)>;

Context() = default;
Context(ErrHandler err_handler) : Cancellation{}, err_handler_{std::move(err_handler)} {
}

template <typename... T> void Error(T... ts) {
std::lock_guard lk{mu_};
if (err_)
return;

GenericError new_err{std::forward<T>(ts)...};
if (!err_handler_ || err_handler_(new_err)) {
err_ = std::move(new_err);
Cancel();
}
}

private:
GenericError err_;
ErrHandler err_handler_;
::boost::fibers::mutex mu_;
};

struct ScanOpts {
std::string_view pattern;
size_t limit = 10;
Expand Down
Loading

0 comments on commit 893c741

Please sign in to comment.