| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_IMPL_H_ |
| #define PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_IMPL_H_ |
| |
| #include <memory> |
| #include <thread> |
| |
| #include <lib/async/dispatcher.h> |
| #include <lib/callback/auto_cleanable.h> |
| #include <lib/fit/function.h> |
| |
| #include "peridot/bin/cloud_provider_firestore/firestore/firestore_service.h" |
| #include "peridot/bin/cloud_provider_firestore/firestore/listen_call.h" |
| #include "peridot/bin/cloud_provider_firestore/grpc/read_stream_drainer.h" |
| |
| namespace cloud_provider_firestore { |
| |
| template <typename ResponseType> |
| using SingleResponseReader = grpc::ClientAsyncResponseReader<ResponseType>; |
| |
| template <typename ResponseType> |
| struct SingleResponseCall { |
| void set_on_empty(fit::closure on_empty) { |
| this->on_empty = std::move(on_empty); |
| } |
| |
| // Context used to make the remote call. |
| grpc::ClientContext context; |
| |
| // Reader used to retrieve the result of the remote call. |
| std::unique_ptr<SingleResponseReader<ResponseType>> response_reader; |
| |
| // Response of the remote call. |
| ResponseType response; |
| |
| // Response status of the remote call. |
| grpc::Status status; |
| |
| // Callback to be called upon completing the remote call. |
| fit::function<void(bool)> on_complete; |
| |
| // Callback to be called when the call object can be deleted. |
| fit::closure on_empty; |
| }; |
| |
| using DocumentResponseCall = |
| SingleResponseCall<google::firestore::v1beta1::Document>; |
| |
| using CommitResponseCall = |
| SingleResponseCall<google::firestore::v1beta1::CommitResponse>; |
| |
| using ListDocumentsResponseCall = |
| SingleResponseCall<google::firestore::v1beta1::ListDocumentsResponse>; |
| |
| using EmptyResponseCall = SingleResponseCall<google::protobuf::Empty>; |
| |
| using RunQueryCall = |
| ReadStreamDrainer<grpc::ClientAsyncReaderInterface< |
| google::firestore::v1beta1::RunQueryResponse>, |
| google::firestore::v1beta1::RunQueryResponse>; |
| |
| // Implementation of the FirestoreService interface. |
| // |
| // This class is implemented as a wrapper over the Firestore connection. We use |
| // a polling thread to wait for request completion on the completion queue and |
| // expose a callback-based API to the client. |
| class FirestoreServiceImpl : public FirestoreService { |
| public: |
| FirestoreServiceImpl(std::string server_id, async_dispatcher_t* dispatcher, |
| std::shared_ptr<grpc::Channel> channel); |
| |
| ~FirestoreServiceImpl() override; |
| |
| // FirestoreService: |
| const std::string& GetDatabasePath() override { return database_path_; } |
| |
| const std::string& GetRootPath() override { return root_path_; } |
| |
| void GetDocument( |
| google::firestore::v1beta1::GetDocumentRequest request, |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| fit::function<void(grpc::Status, google::firestore::v1beta1::Document)> |
| callback) override; |
| |
| void ListDocuments( |
| google::firestore::v1beta1::ListDocumentsRequest request, |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| fit::function<void(grpc::Status, |
| google::firestore::v1beta1::ListDocumentsResponse)> |
| callback) override; |
| |
| void CreateDocument( |
| google::firestore::v1beta1::CreateDocumentRequest request, |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| fit::function<void(grpc::Status, google::firestore::v1beta1::Document)> |
| callback) override; |
| |
| void DeleteDocument(google::firestore::v1beta1::DeleteDocumentRequest request, |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| fit::function<void(grpc::Status)> callback) override; |
| |
| void Commit(google::firestore::v1beta1::CommitRequest request, |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| fit::function<void(grpc::Status, |
| google::firestore::v1beta1::CommitResponse)> |
| callback) override; |
| |
| void RunQuery(google::firestore::v1beta1::RunQueryRequest request, |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| fit::function<void( |
| grpc::Status, |
| std::vector<google::firestore::v1beta1::RunQueryResponse>)> |
| callback) override; |
| |
| std::unique_ptr<ListenCallHandler> Listen( |
| std::shared_ptr<grpc::CallCredentials> call_credentials, |
| ListenCallClient* client) override; |
| |
| void ShutDown(fit::closure callback) override; |
| |
| private: |
| void SetUpContext(grpc::ClientContext* context, |
| std::shared_ptr<grpc::CallCredentials> call_credentials); |
| |
| void Poll(); |
| |
| const std::string server_id_; |
| const std::string database_path_; |
| const std::string root_path_; |
| |
| async_dispatcher_t* const dispatcher_; |
| std::thread polling_thread_; |
| |
| std::unique_ptr<google::firestore::v1beta1::Firestore::Stub> firestore_; |
| grpc::CompletionQueue cq_; |
| |
| // Single-request single-response calls. |
| callback::AutoCleanableSet<DocumentResponseCall> document_response_calls_; |
| callback::AutoCleanableSet<CommitResponseCall> commit_response_calls_; |
| callback::AutoCleanableSet<ListDocumentsResponseCall> |
| list_documents_response_calls_; |
| callback::AutoCleanableSet<EmptyResponseCall> empty_response_calls_; |
| |
| // Single-request stream-response calls. |
| callback::AutoCleanableSet<RunQueryCall> run_query_calls_; |
| |
| // Stream-request stream-response calls. |
| callback::AutoCleanableSet<ListenCall> listen_calls_; |
| }; |
| |
| } // namespace cloud_provider_firestore |
| |
| #endif // PERIDOT_BIN_CLOUD_PROVIDER_FIRESTORE_FIRESTORE_FIRESTORE_SERVICE_IMPL_H_ |