blob: 48478471aa2f6c4b439ca8e6ed29657bda00c0ab [file] [log] [blame]
// 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 SRC_LEDGER_BIN_APP_PAGE_DELEGATE_H_
#define SRC_LEDGER_BIN_APP_PAGE_DELEGATE_H_
#include <lib/callback/operation_serializer.h>
#include <lib/fidl/cpp/interface_ptr_set.h>
#include <lib/fit/function.h>
#include <memory>
#include <queue>
#include <string>
#include <vector>
#include "src/ledger/bin/app/branch_tracker.h"
#include "src/ledger/bin/app/merging/merge_resolver.h"
#include "src/ledger/bin/app/page_impl.h"
#include "src/ledger/bin/app/sync_watcher_set.h"
#include "src/ledger/bin/fidl_helpers/bound_interface.h"
#include "src/ledger/bin/storage/public/data_source.h"
#include "src/ledger/bin/storage/public/journal.h"
#include "src/ledger/bin/storage/public/page_storage.h"
#include "src/ledger/bin/storage/public/types.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/weak_ptr.h"
namespace ledger {
class PageManager;
// A delegate for the implementation of the |Page| interface.
//
// PageDelegate owns PageImpl and BranchTracker. It makes sure that
// all operations in progress will terminate, even if the Page is no longer
// connected. When the page connection is closed and BranchTracker is also
// empty, the client is notified through |on_empty_callback| (registered by
// |set_on_empty()|).
class PageDelegate {
public:
PageDelegate(coroutine::CoroutineService* coroutine_service,
PageManager* manager, storage::PageStorage* storage,
MergeResolver* merge_resolver, SyncWatcherSet* watchers,
std::unique_ptr<PageImpl> page_impl);
~PageDelegate();
void Init(fit::function<void(storage::Status)> on_done);
void set_on_empty(fit::closure on_empty_callback) {
on_empty_callback_ = std::move(on_empty_callback);
}
// From Page interface, called by PageImpl:
void GetSnapshot(fidl::InterfaceRequest<PageSnapshot> snapshot_request,
std::vector<uint8_t> key_prefix,
fidl::InterfaceHandle<PageWatcher> watcher,
fit::function<void(Status)> callback);
void Put(std::vector<uint8_t> key, std::vector<uint8_t> value,
fit::function<void(Status)> callback);
void PutWithPriority(std::vector<uint8_t> key, std::vector<uint8_t> value,
Priority priority, fit::function<void(Status)> callback);
void PutReference(std::vector<uint8_t> key, Reference reference,
Priority priority, fit::function<void(Status)> callback);
void Delete(std::vector<uint8_t> key, fit::function<void(Status)> callback);
void Clear(fit::function<void(Status)> callback);
void CreateReference(
std::unique_ptr<storage::DataSource> data,
fit::function<void(Status, CreateReferenceStatus, ReferencePtr)>
callback);
void StartTransaction(fit::function<void(Status)> callback);
void Commit(fit::function<void(Status)> callback);
void Rollback(fit::function<void(Status)> callback);
void SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
fit::function<void(Status)> callback);
void WaitForConflictResolution(
fit::function<void(Status, ConflictResolutionWaitStatus)> callback);
private:
using StatusCallback = fit::function<void(storage::Status)>;
void PutInCommit(std::vector<uint8_t> key,
storage::ObjectIdentifier object_identifier,
storage::KeyPriority priority, StatusCallback callback);
// Runs |runnable| in a transaction, and notifies |callback| of the result. If
// a transaction is currently in progress, it reuses it, otherwise creates a
// new one and commits it before calling |callback|. This method is not
// serialized, and should only be called from a callsite that is serialized.
void RunInTransaction(fit::function<void(storage::Journal*)> runnable,
StatusCallback callback);
void CommitJournal(std::unique_ptr<storage::Journal> journal,
fit::function<void(storage::Status,
std::unique_ptr<const storage::Commit>)>
callback);
void CheckEmpty();
PageManager* manager_;
storage::PageStorage* storage_;
MergeResolver* merge_resolver_;
BranchTracker branch_tracker_;
fit::closure on_empty_callback_;
std::unique_ptr<storage::Journal> journal_;
callback::OperationSerializer operation_serializer_;
SyncWatcherSet* watcher_set_;
std::unique_ptr<PageImpl> page_impl_;
// This must be the last member of the class.
fxl::WeakPtrFactory<PageDelegate> weak_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(PageDelegate);
};
} // namespace ledger
#endif // SRC_LEDGER_BIN_APP_PAGE_DELEGATE_H_