@@ -20,8 +20,138 @@ Developer's Guide
2020This section will eventually contain a guide for those interested in developing their own
2121asynchronous, sender-based algorithms and execution contexts.
2222
23- Essential concepts
24- ------------------
23+ .. _CoreConceptsForDevelopers :
24+
25+ Core Concepts for Developers
26+ ----------------------------
27+
28+ People wishing to extend the Sender model by writing their own sender algorithms or
29+ schedulers, or by adapting another asynchronous model to the Sender model, should be
30+ familiar with the core concepts of the Sender model. These concepts define how senders,
31+ receivers, and schedulers interact.
32+
33+ .. graphviz ::
34+ :caption: The Sender Model of Asynchrony
35+ :align: center
36+
37+ digraph SenderModel {
38+ rankdir=TB;
39+ splines=false;
40+ fontsize=12;
41+ label=<<b>The Sender Model of Asynchrony</b><br/><br/>>;
42+ fontsize=18;
43+ labelloc=t;
44+
45+ node [fontname="Courier New", fontsize=11, shape=box, style=filled];
46+
47+ scheduler [label=<<b>scheduler</b><br/><br/>schedule(<i>scheduler</i>) → <i>sender</i>>, fillcolor="#2c6a91", fontcolor=white];
48+ sender [label=<<b>sender</b><br/><br/>connect(<i>sender</i>, <i>receiver</i>) → <i>operation-state</i>>, fillcolor="#d26937", fontcolor=white];
49+ receiver [label=<<table border="0" cellborder="0"> <tr> <td> <b>receiver</b></td> </tr> <tr> <td>set_value(<i>receiver</i>, vals...)</td> <td>→</td> <td>void</td> </tr> <tr> <td>set_error(<i>receiver</i>, err)</td> <td>→</td> <td>void</td> </tr> <tr> <td>set_stopped(<i>receiver</i>)</td> <td>→</td> <td>void</td> </tr> </table>>, fillcolor="#379dd2", fontcolor=white];
50+ environment [label=<<b>environment</b><br/>(key/value store)<br/><br/>key(<i>environment</i>) → value>, fillcolor="#2c682c", fontcolor=white];
51+ opstate [label=<<b>operation state</b><br/><br/>start(<i>operation-state</i>) → void>, fillcolor="#933b94", fontcolor=white];
52+
53+ // invisible dummy nodes
54+ connect [shape=point, width=0.01, height=0.01, label="", style=invis];
55+ complete [shape=point, width=0.01, height=0.01, label="", style=invis];
56+
57+ // Edges
58+ scheduler -> sender [penwidth=2, label=" schedule", labelfontname="Courier New"];
59+ environment -> receiver [penwidth=2, arrowhead=diamond];
60+ connect -> opstate [color=black, penwidth=2, labeldistance=2, labelangle=0, taillabel=< <table border="0" cellborder="0"> <tr> <td bgcolor="white">connect</td> </tr> </table> > ];
61+ sender -> receiver [color=black, penwidth=2, dir="both"];
62+ opstate -> complete [dir=none, style=dashed, label=" complete", fontsize=10, weight=0, labelangle=90, labeldistance=2];
63+ complete -> receiver [style=dashed, fontsize=10, weight=0];
64+ sender -> connect -> receiver [style=invis]
65+
66+ // Layout tweaking
67+ { rank = same; scheduler; environment; }
68+ { rank = same; sender; connect; receiver; }
69+ { rank = same; opstate; complete; }
70+ }
71+
72+ In addition to the :ref: `CoreConceptsForUsers `, developers should also be familiar with the
73+ following concepts:
74+
75+ 1. Receiver
76+ ^^^^^^^^^^^
77+
78+ A **receiver ** is an object that consumes the result of a sender. It defines three
79+ member functions that handle completion:
80+
81+ - ``.set_value(args...) ``: Called on success.
82+
83+ - ``.set_error(err) ``: Called on error.
84+
85+ - ``.set_stopped() ``: Called if the operation is canceled.
86+
87+ .. code-block :: cpp
88+
89+ struct MyReceiver {
90+ using receiver_concept = stdexec::receiver_t;
91+
92+ void set_value(int v) noexcept { /* success */ }
93+ void set_error(std::exception_ptr e) noexcept { /* error */ }
94+ void set_stopped() noexcept { /* cancellation */ }
95+ };
96+
97+ Receivers are an implementation detail of sender algorithms.
98+
99+ 2. Operation State
100+ ^^^^^^^^^^^^^^^^^^
101+
102+ Connecting a sender to a receiver yields an **operation state **, which:
103+
104+ - Represents the in-progress computation.
105+
106+ - Is started explicitly via ``.start() ``.
107+
108+ .. code-block :: cpp
109+
110+ auto op = stdexec::connect(sndr, MyReceiver{}); // Connect sender to receiver
111+ stdexec::start(op); // Start the operation
112+
113+ Operation states are immovable, and once started, they must be kept alive until the
114+ operation completes. Like receivers, operation states are typically an implementation
115+ detail of sender algorithms.
116+
117+ 3. Environments
118+ ^^^^^^^^^^^^^^^^^^
119+
120+ Environments are a key concept in the Sender model. An **environment ** is an unordered
121+ collection of key/value pairs, queryable at runtime via tag types. Every receiver has a
122+ (possibly empty) environment that can be obtained by passing the receiver to
123+ ``stdexec::get_env ``.
124+
125+ Environments provide a way to pass contextual information like stop tokens, allocators, or
126+ schedulers to asynchronous operations. That information is then used by the operation to
127+ customize its behavior.
128+
129+
130+ Core Customization Points
131+ -------------------------
132+
133+ Sender algorithms are defined in terms of **core customization points **. Below are the
134+ core customization points that define how senders and receivers interact:
135+
136+ .. list-table :: Core customization points
137+
138+ * - **CPO **
139+ - **Description **
140+ * - :cpp:member: `stdexec::connect `
141+ - Connects a sender to a receiver resulting in an operation state.
142+ * - :cpp:member: `stdexec::start `
143+ - Starts the operation.
144+ * - :cpp:member: `stdexec::set_value `
145+ - Called by the operation state to deliver a value to the receiver.
146+ * - :cpp:member: `stdexec::set_error `
147+ - Called by the operation state to deliver an error to the receiver.
148+ * - :cpp:member: `stdexec::set_stopped `
149+ - Called by the operation state to indicate that the operation was stopped.
150+ * - :cpp:member: `stdexec::get_env `
151+ - Retrieves the environment from a receiver.
152+
153+
154+
25155
26156* Receivers
27157* Custom Algorithms
0 commit comments