You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/flow.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,13 +1,13 @@
1
-
# core.async.flow #
2
-
## Rationale ##
1
+
# core.async.flow
2
+
## Rationale
3
3
4
4
The [rationale](https://clojure.org/news/2013/06/28/clojure-clore-async-channels) for **core.async** says "There comes a time in all good programs when components or subsystems must stop communicating directly with one another." And core.async provides fundamental tools (channels) for doing that.
5
5
6
6
But using core.async well, e.g. keeping your I/O out of your computational logic, requires discipline and architectural savvy, and to do so consistently throughout an application or organization, conventions. Given channels, many architectural decisions remain regarding thread execution, backpressure, error handling etc. And often the topology of your network of communicating processes *emerges* out of the flow of control of your program as various pieces of code create threads and wire channels together, interleaved with computation, making it difficult to see the topology or administer it in one place.
7
7
8
8
The fundamental objective of __core.async.flow__ is to enable a strict separation of your application logic from its topology, execution, communication, lifecycle, monitoring and error handling, all of which are provided by and centralized in, c.a.flow, yielding more consistent, robust, testable, observable and operable systems.
9
9
10
-
## Overview ##
10
+
## Overview
11
11
12
12
__core.async.flow__ provides *concrete* implementations of two more abstractions - the '__process__' - a thread of activity, and the '__flow__' - a directed graph of processes communicating via channels. A single data structure describes your flow topology, and has all of the settings for threads, channels etc. A process accepts data from and provides data to channels. The process implementation in c.a.flow handles all channel I/O, thread lifecycle and coordination with the flow graph.
<html><head><metacharset="UTF-8" /><title>clojure.core.async.flow.spi documentation</title><linkrel="stylesheet" type="text/css" href="css/default.css" /><linkrel="stylesheet" type="text/css" href="css/highlight.css" /><scripttype="text/javascript" src="js/highlight.min.js"></script><scripttype="text/javascript" src="js/jquery.min.js"></script><scripttype="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><divid="header"><h2>Generated by <ahref="https://github.com/weavejester/codox">Codox</a></h2><h1><ahref="index.html"><spanclass="project-title"><spanclass="project-name"></span><spanclass="project-version"></span></span></a></h1></div><divclass="sidebar primary"><h3class="no-link"><spanclass="inner">Project</span></h3><ulclass="index-link"><liclass="depth-1 "><ahref="index.html"><divclass="inner">Index</div></a></li></ul><h3class="no-link"><spanclass="inner">Topics</span></h3><ul><liclass="depth-1 "><ahref="flow.html"><divclass="inner"><span>core.async.flow #</span></div></a></li></ul><h3class="no-link"><spanclass="inner">Namespaces</span></h3><ul><liclass="depth-1 "><ahref="clojure.core.async.html"><divclass="inner"><span>clojure.core.async</span></div></a></li><liclass="depth-1 "><ahref="clojure.core.async.flow.html"><divclass="inner"><span>clojure.core.async.flow</span></div></a></li><liclass="depth-1 current"><ahref="clojure.core.async.flow.spi.html"><divclass="inner"><span>clojure.core.async.flow.spi</span></div></a></li></ul></div><divclass="sidebar secondary"><h3><ahref="#top"><spanclass="inner">Public Vars</span></a></h3><ul><liclass="depth-1"><ahref="clojure.core.async.flow.spi.html#var-ProcLauncher"><divclass="inner"><span>ProcLauncher</span></div></a></li><liclass="depth-2 branch"><ahref="clojure.core.async.flow.spi.html#var-describe"><divclass="inner"><spanclass="tree"><spanclass="top"></span><spanclass="bottom"></span></span><span>describe</span></div></a></li><liclass="depth-2"><ahref="clojure.core.async.flow.spi.html#var-start"><divclass="inner"><spanclass="tree"><spanclass="top"></span><spanclass="bottom"></span></span><span>start</span></div></a></li><liclass="depth-1"><ahref="clojure.core.async.flow.spi.html#var-Resolver"><divclass="inner"><span>Resolver</span></div></a></li><liclass="depth-2 branch"><ahref="clojure.core.async.flow.spi.html#var-get-exec"><divclass="inner"><spanclass="tree"><spanclass="top"></span><spanclass="bottom"></span></span><span>get-exec</span></div></a></li><liclass="depth-2"><ahref="clojure.core.async.flow.spi.html#var-get-write-chan"><divclass="inner"><spanclass="tree"><spanclass="top"></span><spanclass="bottom"></span></span><span>get-write-chan</span></div></a></li></ul></div><divclass="namespace-docs" id="content"><h1class="anchor" id="top">clojure.core.async.flow.spi</h1><divclass="doc"><preclass="plaintext"></pre></div><divclass="public anchor" id="var-ProcLauncher"><h3>ProcLauncher</h3><h4class="type">protocol</h4><divclass="usage"></div><divclass="doc"><preclass="plaintext">Note - defining a ProcLauncher is an advanced feature and should not
4
+
be needed for ordinary use of the library. This protocol is for
5
+
creating new types of Processes that are not possible to create
6
+
with ::flow/process.
7
+
8
+
A ProcLauncher is a constructor for a process, a thread of activity.
9
+
It has two functions - to describe the parameters and input/output
10
+
requirements of the process and to start it. The launcher should
11
+
acquire no resources, nor retain any connection to the started
12
+
process. A launcher may be called upon to start a process more than
13
+
once, and should start a new process each time start is called.
14
+
15
+
The process launched process must obey the following:
16
+
17
+
It must have 2 logical statuses, :paused and :running. In
18
+
the :paused status operation is suspended and no output is
19
+
produced.
20
+
21
+
When the process starts it must be :paused
22
+
23
+
Whenever it is reading or writing to any channel a process must use
24
+
alts!! and include a read of the ::flow/control channel, giving it
25
+
priority.
26
+
27
+
Command messages sent over the ::flow/control channel have the keys:
28
+
::flow/to - either ::flow/all or a process id
29
+
::flow/command - ::flow/stop|pause|resume|ping or process-specific
30
+
31
+
It must act upon any, and only, control messages whose ::flow/to key is its pid or ::flow/all
32
+
It must act upon the following values of ::flow/command:
33
+
34
+
::flow/stop - all resources should be cleaned up and any thread(s)
35
+
should exit ordinarily - there will be no more subsequent use
36
+
of the process.
37
+
::flow/pause - enter the :paused status
38
+
::flow/resume - enter the :running status and resume processing
39
+
::flow/ping - emit a ping message (format TBD) to
40
+
the ::flow/report channel containing at least its pid and status
41
+
42
+
A process can define and respond to other commands in its own namespace.
43
+
44
+
A process should not transmit channel objects (use [pid io-id] data
45
+
coordinates instead) A process should not close channels
46
+
47
+
Finally, if a process encounters an error it must report it on the
48
+
::flow/error channel (format TBD) and attempt to continue, though it
49
+
may subsequently get a ::flow/stop command it must respect</pre></div><divclass="members"><h4>members</h4><divclass="inner"><divclass="public anchor" id="var-describe"><h3>describe</h3><divclass="usage"><code>(describe p)</code></div><divclass="doc"><preclass="plaintext">returns a map with keys - :params, :ins and :outs,
50
+
each of which in turn is a map of keyword to docstring
51
+
52
+
:params describes the initial arguments to setup the state for the process
53
+
:ins enumerates the input[s], for which the graph will create channels
54
+
:outs enumerates the output[s], for which the graph may create channels.
55
+
56
+
describe may be called by users to understand how to use the
57
+
proc. It will also be called by the impl in order to discover what
58
+
channels are needed.</pre></div></div><divclass="public anchor" id="var-start"><h3>start</h3><divclass="usage"><code>(start p {:keys [pid args ins outs resolver]})</code></div><divclass="doc"><preclass="plaintext">return ignored, called for the
59
+
effect of starting the process (typically, starting its thread)
60
+
61
+
where:
62
+
63
+
:pid - the id of the process in the graph, so that e.g. it can refer to itself in control, reporting etc
64
+
:args - a map of param->val, as supplied in the graph def
65
+
:ins - a map of in-id->readable-channel, plus the ::flow/control channel
66
+
:outs - a map of out-id->writeable-channel, plus the ::flow/error and ::flow/report channels
67
+
N.B. outputs may be nil if not connected
68
+
:resolver - an impl of spi/Resolver, which can be used to find
69
+
channels given their logical [pid cid] coordinates, as well as to
70
+
obtain ExecutorServices corresponding to the
71
+
logical :mixed/:io/:compute contexts</pre></div></div></div></div></div><divclass="public anchor" id="var-Resolver"><h3>Resolver</h3><h4class="type">protocol</h4><divclass="usage"></div><divclass="doc"><preclass="plaintext"></pre></div><divclass="members"><h4>members</h4><divclass="inner"><divclass="public anchor" id="var-get-exec"><h3>get-exec</h3><divclass="usage"><code>(get-exec _ context)</code></div><divclass="doc"><preclass="plaintext">returns the ExecutorService for the given context, one
72
+
of :mixed, :io, :compute</pre></div></div><divclass="public anchor" id="var-get-write-chan"><h3>get-write-chan</h3><divclass="usage"><code>(get-write-chan _ coord)</code></div><divclass="doc"><preclass="plaintext">Given a tuple of [pid cid], returns a core.async chan to
73
+
write to or nil (in which case the output should be dropped,
74
+
e.g. nothing is connected).</pre></div></div></div></div></div></div></body></html>
0 commit comments