blob: cff7dd14349f6cad0a0d3587f81dcdbd9de259e4 [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_SESSIONMGR_MESSAGE_QUEUE_MESSAGE_QUEUE_MANAGER_H_
#define PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_MESSAGE_QUEUE_MANAGER_H_
#include <functional>
#include <map>
#include <memory>
#include <queue>
#include <string>
#include <utility>
#include <fuchsia/ledger/cpp/fidl.h>
#include <fuchsia/modular/cpp/fidl.h>
#include <lib/async/cpp/operation.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fidl/cpp/string.h>
#include <lib/fxl/macros.h>
#include "peridot/lib/ledger_client/ledger_client.h"
#include "peridot/lib/ledger_client/page_client.h"
#include "peridot/lib/ledger_client/types.h"
namespace modular {
class MessageQueueStorage;
struct MessageQueueInfo;
// Manages message queues for components. One MessageQueueManager
// instance is used by all ComponentContextImpl instances, and manages
// the message queues for all component instances. The
// fuchsia::modular::ComponentContext instance is responsible for deleting the
// message queues it has created, otherwise they are persisted.
class MessageQueueManager : PageClient {
public:
MessageQueueManager(LedgerClient* ledger_client,
fuchsia::ledger::PageId page_id, std::string local_path);
~MessageQueueManager() override;
// An enum describing the types of events that can be watched via
// |RegisterWatcher|.
enum WatcherEventType {
// Triggers when there is a new message on the watched messsage queue.
NEW_MESSAGE,
// Triggers when the watched message queue is deleted.
QUEUE_DELETED,
};
void ObtainMessageQueue(
const std::string& component_namespace,
const std::string& component_instance_id, const std::string& queue_name,
fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request);
void DeleteMessageQueue(const std::string& component_namespace,
const std::string& component_instance_id,
const std::string& queue_name);
void DeleteNamespace(const std::string& component_namespace,
std::function<void()> done);
void GetMessageSender(
const std::string& queue_token,
fidl::InterfaceRequest<fuchsia::modular::MessageSender> request);
// Registers a watcher that will be called when there is a new message on a
// queue corresponding to |component_namespace| x |component_instance_id| x
// |queue_name|.
//
// |component_namespace| is the namespace of the watching component (i.e. the
// creator of the queue).
// |component_instance_id| is the namespace of the watching component (i.e.
// the creator of the queue).
// |queue_name| is the name of the message queue.
//
// Only one message watcher can be active for a given queue, and registering a
// new one will remove any existing watcher.
void RegisterMessageWatcher(const std::string& component_namespace,
const std::string& component_instance_id,
const std::string& queue_name,
const std::function<void()>& watcher);
// Registers a watcher that gets notified when a message queue with
// |queue_token| is deleted.
//
// Only one deletion watcher can be active for a given queue, and registering
// a new one will remove any existing watcher.
//
// |watcher_namespace| is the namespace of the component that is watching the
// message queue deletion.
// |watcher_instance_id| is the instance id of the component that is watching
// the message queue deletion.
// |queue_token| is the message queue token for the queue to be observed.
// |watcher| is the callback that will be triggered.
//
// Note that this is different from |RegisterMessageWatcher|, where the passed
// in namespace, instance ids, and queue name directly describe the queue.
void RegisterDeletionWatcher(const std::string& component_namespace,
const std::string& component_instance_id,
const std::string& queue_token,
const std::function<void()>& watcher);
// Drops the watcher for |component_namespace| x |component_instance_id| x
// |queue_name|.
void DropMessageWatcher(const std::string& component_namespace,
const std::string& component_instance_id,
const std::string& queue_name);
// Drops the watcher described by |queue_info| from watching for the
// deletion of the queue with |queue_token|.
void DropDeletionWatcher(const std::string& watcher_namespace,
const std::string& watcher_instance_id,
const std::string& queue_token);
private:
using ComponentNamespace = std::string;
using ComponentInstanceId = std::string;
using ComponentQueueName = std::string;
template <typename Value>
using ComponentQueueNameMap = std::map<
ComponentNamespace,
std::map<ComponentInstanceId, std::map<ComponentQueueName, Value>>>;
using DeletionWatchers =
std::map<std::string, std::map<std::string, std::function<void()>>>;
// Returns the |MessageQueueStorage| for the queue_token. Creates it
// if it doesn't exist yet.
MessageQueueStorage* GetMessageQueueStorage(const MessageQueueInfo& info);
// Clears the |MessageQueueStorage| for the queue_token.
void ClearMessageQueueStorage(const MessageQueueInfo& info);
// Clears the |MessageQueueStorage| for all the queues in the provided
// component namespace.
void ClearMessageQueueStorage(const std::string& component_namespace);
// |FindQueueName()| and |EraseQueueName()| are helpers used to operate on
// component (namespace, id, queue name) mappings.
// If the given message queue |info| is found the stored pointer value, or
// nullptr otherwise.
template <typename ValueType>
const ValueType* FindQueueName(
const ComponentQueueNameMap<ValueType>& queue_map,
const MessageQueueInfo& info);
// Erases the |ValueType| stored under the provided |info|.
// Implementation is in the .cc.
template <typename ValueType>
void EraseQueueName(ComponentQueueNameMap<ValueType>& queue_map,
const MessageQueueInfo& info);
// Erases all |ValueType|s under the provided namespace.
// Implementation is in the .cc.
template <typename ValueType>
void EraseNamespace(ComponentQueueNameMap<ValueType>& queue_map,
const std::string& component_namespace);
const std::string local_path_;
// A map of queue_token to |MessageQueueStorage|.
std::map<std::string, std::unique_ptr<MessageQueueStorage>> message_queues_;
// A map of queue_token to |MessageQueueInfo|. This allows for easy lookup of
// message queue information for registering watchers that take message queue
// tokens as parameters.
std::map<std::string, MessageQueueInfo> message_queue_infos_;
// A map of component instance id and queue name to queue tokens.
// Entries are only here while a |MessageQueueStorage| exists.
ComponentQueueNameMap<std::string> message_queue_tokens_;
// A map of component instance id and queue name to watcher
// callbacks. If a watcher is registered before a
// |MessageQueueStorage| exists then it is stashed here until a
// |MessageQueueStorage| is available.
ComponentQueueNameMap<std::function<void()>> pending_watcher_callbacks_;
// A map containing watchers that are to be notified when the described
// message queue is deleted.
ComponentQueueNameMap<DeletionWatchers> deletion_watchers_;
OperationCollection operation_collection_;
// Operations implemented here.
class GetQueueTokenCall;
class GetMessageSenderCall;
class ObtainMessageQueueCall;
class DeleteMessageQueueCall;
class DeleteNamespaceCall;
FXL_DISALLOW_COPY_AND_ASSIGN(MessageQueueManager);
};
} // namespace modular
#endif // PERIDOT_BIN_SESSIONMGR_MESSAGE_QUEUE_MESSAGE_QUEUE_MANAGER_H_