diff --git a/services/backup/docker-server/contents/server/src/ReactorBase.h b/services/backup/docker-server/contents/server/src/ReactorBase.h new file mode 100644 --- /dev/null +++ b/services/backup/docker-server/contents/server/src/ReactorBase.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include + +namespace comm { +namespace network { + +struct EndConnectionError : public std::exception { + const char *what() const throw() { + return "connection ended"; + } +}; + +template +class ReactorBase : public grpc::ServerBidiReactor { + Request request; + Response response; + bool finished = false; + + void finish() { + if (this->finished) { + return; + } + this->finished = true; + this->Finish(grpc::Status::OK); + } + +public: + ReactorBase() { + this->StartRead(&this->request); + } + + void OnDone() override { + GPR_ASSERT(this->finished); + delete this; + } + + void OnReadDone(bool ok) override { + if (!ok) { + this->finish(); + return; + } + try { + this->response = this->handleRequest(this->request); + this->StartWrite(&this->response); + } catch (EndConnectionError &e) { + this->finish(); + } + } + + void OnWriteDone(bool ok) override { + if (!ok) { + gpr_log(GPR_ERROR, "Server write failed"); + return; + } + this->StartRead(&this->request); + } + + virtual Response handleRequest(Request request) = 0; +}; + +} // namespace network +} // namespace comm