blob: 97563e1afc439bf3e3b3e50d2be68603d6f14545 [file] [log] [blame]
// Copyright 2016 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_MANAGER_H_
#define SRC_LEDGER_BIN_APP_PAGE_MANAGER_H_
#include <fuchsia/ledger/internal/cpp/fidl.h>
#include <lib/callback/auto_cleanable.h>
#include <lib/callback/scoped_task_runner.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fit/function.h>
#include <memory>
#include <vector>
#include "src/ledger/bin/app/merging/merge_resolver.h"
#include "src/ledger/bin/app/page_delegate.h"
#include "src/ledger/bin/app/page_snapshot_impl.h"
#include "src/ledger/bin/app/sync_watcher_set.h"
#include "src/ledger/bin/environment/environment.h"
#include "src/ledger/bin/fidl/error_notifier.h"
#include "src/ledger/bin/fidl/include/types.h"
#include "src/ledger/bin/fidl_helpers/bound_interface.h"
#include "src/ledger/bin/storage/public/page_storage.h"
#include "src/ledger/bin/storage/public/page_sync_delegate.h"
#include "src/ledger/bin/sync_coordinator/public/page_sync.h"
#include "src/lib/fxl/time/time_delta.h"
namespace ledger {
// Manages a ledger page.
//
// PageManager owns all page-level objects related to a single page: page
// storage, and a set of FIDL PageImpls backed by the page storage. It is safe
// to delete it at any point - this closes all channels, deletes PageImpls and
// tears down the storage.
//
// When the set of PageImpls becomes empty, client is notified through
// |on_empty_callback|.
class PageManager {
public:
// Whether the page storage needs to sync with the cloud provider before
// binding new pages (|NEEDS_SYNC|) or whether it is immediately available
// (|AVAILABLE|).
enum class PageStorageState {
AVAILABLE,
NEEDS_SYNC,
};
// Both |page_storage| and |page_sync| are owned by PageManager and are
// deleted when it goes away.
PageManager(Environment* environment,
std::unique_ptr<storage::PageStorage> page_storage,
std::unique_ptr<sync_coordinator::PageSync> page_sync,
std::unique_ptr<MergeResolver> merge_resolver,
PageManager::PageStorageState state,
zx::duration sync_timeout = zx::sec(5));
~PageManager();
// Creates a new PageDelegate managed by this PageManager, and binds it to the
// given PageImpl.
void AddPageImpl(std::unique_ptr<PageImpl> page_impl,
fit::function<void(storage::Status)> on_done);
// Creates a new PageSnapshotImpl managed by this PageManager, and binds it to
// the request.
void BindPageSnapshot(std::unique_ptr<const storage::Commit> commit,
fidl::InterfaceRequest<PageSnapshot> snapshot_request,
std::string key_prefix);
// Create a new reference for the given object identifier.
Reference CreateReference(storage::ObjectIdentifier object_identifier);
// Retrieve an object identifier from a Reference.
storage::Status ResolveReference(
Reference reference, storage::ObjectIdentifier* object_identifier);
// Checks whether there are any unsynced commits or pieces in this page.
void IsSynced(fit::function<void(storage::Status, bool)> callback);
// Checks whether the page is offline and has no entries.
void IsOfflineAndEmpty(fit::function<void(storage::Status, bool)> callback);
// Returns true if this PageManager can be deleted without interrupting
// syncing, merging, or requests related to this page.
bool IsEmpty();
void set_on_empty(fit::closure on_empty_callback) {
on_empty_callback_ = std::move(on_empty_callback);
}
private:
void CheckEmpty();
void OnSyncBacklogDownloaded();
Environment* const environment_;
std::unique_ptr<storage::PageStorage> page_storage_;
std::unique_ptr<sync_coordinator::PageSync> page_sync_;
std::unique_ptr<MergeResolver> merge_resolver_;
const zx::duration sync_timeout_;
callback::AutoCleanableSet<fidl_helpers::BoundInterface<
PageSnapshot, PageSnapshotImpl,
ErrorNotifierBinding<fuchsia::ledger::PageSnapshotErrorNotifierDelegate>>>
snapshots_;
callback::AutoCleanableSet<PageDelegate> page_delegates_;
fit::closure on_empty_callback_;
bool sync_backlog_downloaded_ = false;
std::vector<std::pair<std::unique_ptr<PageImpl>,
fit::function<void(storage::Status)>>>
page_impls_;
SyncWatcherSet watchers_;
// Registered references.
std::map<uint64_t, storage::ObjectIdentifier> references_;
// Must be the last member field.
callback::ScopedTaskRunner task_runner_;
FXL_DISALLOW_COPY_AND_ASSIGN(PageManager);
};
} // namespace ledger
#endif // SRC_LEDGER_BIN_APP_PAGE_MANAGER_H_