blob: 65207085f0d2d22382e9c5021cadaf925775d0e8 [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 PERIDOT_BIN_LEDGER_APP_PAGE_DELEGATE_H_
#define PERIDOT_BIN_LEDGER_APP_PAGE_DELEGATE_H_
#include <memory>
#include <queue>
#include <string>
#include <vector>
#include <lib/callback/operation_serializer.h>
#include <lib/fidl/cpp/interface_ptr_set.h>
#include <lib/fit/function.h>
#include <lib/fxl/macros.h>
#include <lib/fxl/memory/weak_ptr.h>
#include "peridot/bin/ledger/app/branch_tracker.h"
#include "peridot/bin/ledger/app/merging/merge_resolver.h"
#include "peridot/bin/ledger/app/page_impl.h"
#include "peridot/bin/ledger/app/sync_watcher_set.h"
#include "peridot/bin/ledger/fidl_helpers/bound_interface.h"
#include "peridot/bin/ledger/storage/public/data_source.h"
#include "peridot/bin/ledger/storage/public/journal.h"
#include "peridot/bin/ledger/storage/public/page_storage.h"
#include "peridot/bin/ledger/storage/public/types.h"
namespace ledger {
class PageManager;
// A delegate for the implementation of the |Page| interface.
//
// PageDelegate owns PageDelayingFacade 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<PageDelayingFacade> page_delaying_facade);
~PageDelegate();
void Init(fit::function<void(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 PageDelayingFacade:
void GetSnapshot(fidl::InterfaceRequest<PageSnapshot> snapshot_request,
std::vector<uint8_t> key_prefix,
fidl::InterfaceHandle<PageWatcher> watcher,
Page::GetSnapshotCallback callback);
void Put(std::vector<uint8_t> key, std::vector<uint8_t> value,
Page::PutCallback callback);
void PutWithPriority(std::vector<uint8_t> key,
std::vector<uint8_t> value, Priority priority,
Page::PutWithPriorityCallback callback);
void PutReference(std::vector<uint8_t> key, Reference reference,
Priority priority, Page::PutReferenceCallback callback);
void Delete(std::vector<uint8_t> key, Page::DeleteCallback callback);
void Clear(Page::ClearCallback callback);
void CreateReference(std::unique_ptr<storage::DataSource> data,
fit::function<void(Status, ReferencePtr)> callback);
void StartTransaction(Page::StartTransactionCallback callback);
void Commit(Page::CommitCallback callback);
void Rollback(Page::RollbackCallback callback);
void SetSyncStateWatcher(fidl::InterfaceHandle<SyncWatcher> watcher,
Page::SetSyncStateWatcherCallback callback);
void WaitForConflictResolution(
Page::WaitForConflictResolutionCallback callback);
private:
using StatusCallback = fit::function<void(Status)>;
const storage::CommitId& GetCurrentCommitId();
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*, fit::function<void(Status)>)>
runnable,
StatusCallback callback);
void CommitJournal(
std::unique_ptr<storage::Journal> journal,
fit::function<void(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_;
storage::CommitId journal_parent_commit_;
std::unique_ptr<storage::Journal> journal_;
callback::OperationSerializer operation_serializer_;
SyncWatcherSet* watcher_set_;
std::unique_ptr<PageDelayingFacade> page_delaying_facade_;
// This must be the last member of the class.
fxl::WeakPtrFactory<PageDelegate> weak_factory_;
FXL_DISALLOW_COPY_AND_ASSIGN(PageDelegate);
};
} // namespace ledger
#endif // PERIDOT_BIN_LEDGER_APP_PAGE_DELEGATE_H_