Commit aa378653 authored by Andrew Smith's avatar Andrew Smith Committed by Facebook GitHub Bot

Change MergeChannel public interface

Summary:
The current MergeChannel public interface has a few problems that have become more apparent with usage.

1. The output receiver does not contain the key associated with the input receiver that geneated the value. This often means that the user must transform input receivers before adding them to the merge channel to include the key, which wastes memory.
2. There is no way for a consumer of the output receiver to know if an input receiver was closed without an exception.
3. If an input receiver was closed with an exception, the entire merge channel is closed.

This diff changes the public API to fix these problems. Instead of returning an output receiver that just has values, the output receiver contains MergeChannelEvent objects. Each such event object has the key of the corresponding input receiver associated with the event, along with the event contents. There are four types of events:

1. A value was received through an existing input receiver.
2. A new input receiver was added.
3. An existing input receiver was removed.
4. An existing input receiver was closed (with or without an exception).

Note that we could theoretically avoid genering events for 2 and 3 (as they correspond with calls that the user makes to add and remove), but there are cases where it is useful to have 2 and 3. This way, an event is always received when an existing input receiver is removed, regardless of whether it was removed explicitly (through a call to removeReceiver) or implicitly (if the input receiver was closed).

Reviewed By: aary

Differential Revision: D33033374

fbshipit-source-id: 34f74cba3f765c76a80d448647d733ad38a2195c
parent 017ba9c3
......@@ -16,6 +16,7 @@
#pragma once
#include <folly/container/F14Set.h>
#include <folly/executors/SequencedExecutor.h>
#include <folly/experimental/channels/Channel.h>
......@@ -27,11 +28,29 @@ template <typename KeyType, typename ValueType>
class IMergeChannelProcessor;
}
struct MergeChannelReceiverAdded {};
struct MergeChannelReceiverRemoved {};
struct MergeChannelReceiverClosed {
folly::exception_wrapper exception;
};
template <typename KeyType, typename ValueType>
struct MergeChannelEvent {
using EventType = std::variant<
ValueType,
MergeChannelReceiverAdded,
MergeChannelReceiverRemoved,
MergeChannelReceiverClosed>;
KeyType key;
EventType event;
};
/**
* A merge channel allows one to merge multiple receivers into a single output
* receiver. The set of receivers being merged can be changed at runtime. Each
* receiver is added with a key that can be used to remove the receiver at a
* later point.
* A merge channel allows one to merge multiple receivers into a single
* output receiver. The set of receivers being merged can be changed at
* runtime. Each receiver is added with a key that can be used to remove
* the receiver at a later point.
*
* Example:
*
......@@ -81,6 +100,11 @@ class MergeChannel {
*/
void removeReceiver(KeyType key);
/**
* Returns a set of keys for receivers that are merged into this MergeChannel.
*/
folly::F14FastSet<KeyType> getReceiverKeys();
/**
* Closes the merge channel.
*/
......@@ -96,7 +120,9 @@ class MergeChannel {
* @param executor: The SequencedExecutor to use for merging values.
*/
template <typename KeyType, typename ValueType>
std::pair<Receiver<ValueType>, MergeChannel<KeyType, ValueType>>
std::pair<
Receiver<MergeChannelEvent<KeyType, ValueType>>,
MergeChannel<KeyType, ValueType>>
createMergeChannel(
folly::Executor::KeepAlive<folly::SequencedExecutor> executor);
} // namespace channels
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment