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,73 @@ +#pragma once + +#include +#include +#include +#include + +namespace comm { +namespace network { + +template +class ReactorBase : public grpc::ServerBidiReactor { + Request request; + Response response; + + void finish(grpc::Status status = grpc::Status::OK); + +public: + ReactorBase(); + + void OnDone() override; + void OnReadDone(bool ok) override; + void OnWriteDone(bool ok) override; + + virtual std::unique_ptr + handleRequest(Request request, Response *response) = 0; +}; + +template +void ReactorBase::finish(grpc::Status status) { + this->Finish(status); +} + +template +ReactorBase::ReactorBase() { + this->StartRead(&this->request); +} + +template +void ReactorBase::OnDone() { + delete this; +} + +template +void ReactorBase::OnReadDone(bool ok) { + if (!ok) { + this->finish(grpc::Status(grpc::StatusCode::INTERNAL, "reading error")); + return; + } + try { + std::unique_ptr status = + this->handleRequest(this->request, &this->response); + if (status != nullptr) { + this->finish(*status); + return; + } + this->StartWrite(&this->response); + } catch (std::runtime_error &e) { + this->finish(grpc::Status(grpc::StatusCode::INTERNAL, e.what())); + } +} + +template +void ReactorBase::OnWriteDone(bool ok) { + if (!ok) { + std::cout << "Server write failed" << std::endl; + return; + } + this->StartRead(&this->request); +} + +} // namespace network +} // namespace comm