Skip to content

Commit d07ab67

Browse files
committed
Merge branch 'master' into dev-io-thread
2 parents bb7186c + cfb9573 commit d07ab67

File tree

17 files changed

+1503
-132
lines changed

17 files changed

+1503
-132
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,4 @@ pom.xml.versionsBackup
2828
.classpath
2929
ccw.repl.cmdhistory.prefs
3030
nbactions.xml
31+
.DS_Store

deps.edn

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,14 @@
2222
;; clj -M:outdated
2323
:outdated {:extra-deps {com.github.liquidz/antq {:mvn/version "2.11.1250"}}
2424
:main-opts ["-m" "antq.core"]}
25+
26+
;; Regenerate docs in docs/
27+
;; clj -X:docs
28+
:docs {:extra-deps {codox/codox {:mvn/version "0.10.8"}}
29+
:exec-fn codox.main/generate-docs
30+
:exec-args {:source-paths ["src/main/clojure"]
31+
:namespaces [clojure.core.async clojure.core.async.flow clojure.core.async.flow.spi]
32+
:doc-files ["doc/flow.md"]
33+
:output-path "docs"
34+
:html {:namespace-list :flat}}}
2535
}}

doc/flow.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
# core.async.flow #
2-
## Rationale ##
1+
# core.async.flow
2+
## Rationale
33

44
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.
55

66
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.
77

88
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.
99

10-
## Overview ##
10+
## Overview
1111

1212
__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.
1313

docs/clojure.core.async.flow.html

Lines changed: 206 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<!DOCTYPE html PUBLIC ""
2+
"">
3+
<html><head><meta charset="UTF-8" /><title>clojure.core.async.flow.spi documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name"></span> <span class="project-version"></span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="flow.html"><div class="inner"><span>core.async.flow #</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1 "><a href="clojure.core.async.html"><div class="inner"><span>clojure.core.async</span></div></a></li><li class="depth-1 "><a href="clojure.core.async.flow.html"><div class="inner"><span>clojure.core.async.flow</span></div></a></li><li class="depth-1 current"><a href="clojure.core.async.flow.spi.html"><div class="inner"><span>clojure.core.async.flow.spi</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="clojure.core.async.flow.spi.html#var-ProcLauncher"><div class="inner"><span>ProcLauncher</span></div></a></li><li class="depth-2 branch"><a href="clojure.core.async.flow.spi.html#var-describe"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>describe</span></div></a></li><li class="depth-2"><a href="clojure.core.async.flow.spi.html#var-start"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>start</span></div></a></li><li class="depth-1"><a href="clojure.core.async.flow.spi.html#var-Resolver"><div class="inner"><span>Resolver</span></div></a></li><li class="depth-2 branch"><a href="clojure.core.async.flow.spi.html#var-get-exec"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>get-exec</span></div></a></li><li class="depth-2"><a href="clojure.core.async.flow.spi.html#var-get-write-chan"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>get-write-chan</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">clojure.core.async.flow.spi</h1><div class="doc"><pre class="plaintext"></pre></div><div class="public anchor" id="var-ProcLauncher"><h3>ProcLauncher</h3><h4 class="type">protocol</h4><div class="usage"></div><div class="doc"><pre class="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><div class="members"><h4>members</h4><div class="inner"><div class="public anchor" id="var-describe"><h3>describe</h3><div class="usage"><code>(describe p)</code></div><div class="doc"><pre class="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><div class="public anchor" id="var-start"><h3>start</h3><div class="usage"><code>(start p {:keys [pid args ins outs resolver]})</code></div><div class="doc"><pre class="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-&gt;val, as supplied in the graph def
65+
:ins - a map of in-id-&gt;readable-channel, plus the ::flow/control channel
66+
:outs - a map of out-id-&gt;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><div class="public anchor" id="var-Resolver"><h3>Resolver</h3><h4 class="type">protocol</h4><div class="usage"></div><div class="doc"><pre class="plaintext"></pre></div><div class="members"><h4>members</h4><div class="inner"><div class="public anchor" id="var-get-exec"><h3>get-exec</h3><div class="usage"><code>(get-exec _ context)</code></div><div class="doc"><pre class="plaintext">returns the ExecutorService for the given context, one
72+
of :mixed, :io, :compute</pre></div></div><div class="public anchor" id="var-get-write-chan"><h3>get-write-chan</h3><div class="usage"><code>(get-write-chan _ coord)</code></div><div class="doc"><pre class="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

Comments
 (0)