Merge lp:~stephen-xemacs/mailman/sprint-2012-overview into lp:mailman

Proposed by Stephen Turnbull
Status: Merged
Merged at revision: 7122
Proposed branch: lp:~stephen-xemacs/mailman/sprint-2012-overview
Merge into: lp:mailman
Diff against target: 244 lines (+197/-3)
3 files modified
README.rst (+1/-0)
conf.py (+6/-3)
src/mailman/docs/8-miles-high.rst (+190/-0)
To merge this branch: bzr merge lp:~stephen-xemacs/mailman/sprint-2012-overview
Reviewer Review Type Date Requested Status
Mailman Coders Pending
Review via email: mp+97533@code.launchpad.net

Description of the change

Andrea Crotti's work making python setup.py build_sphinx work, plus my "Overview" document.
This branch contains and supersedes lp:~andrea-crotti-o/mailman/conf_py.

To build the docs on my Mac OS X/Macports system I used

$ python2.6 bootstrap.py # get python 2.6 from MacPorts
$ bin/buildout
$ python2.6 setup.py build_sphinx

The output ends up in src/mailman/docs/build/sphinx/html/README.html. No promises for
other platforms. :-p

New files in src/mailman/docs:
  8-miles-high.rst # ReST file containing notes from Mailman sprint at PyCon 2012
  chains.png # used by 8-miles-high:
  pipeline.png # from Barry Warsaw's Mailman presentation
  msg-flow.png # replaced by in-line graphviz code (will be removed)
Other changes to (1) fix build, and (2) integrate 8-miles-high into README.rst.

To post a comment you must log in.
7117. By Stephen Turnbull

Improved layout of graphviz version of chains.

7118. By Stephen Turnbull

source, chains, sink subgraphs form

7119. By Stephen Turnbull

groups help

7120. By Stephen Turnbull

We gots a graphviz! Now WAT?!

7121. By Stephen Turnbull

Remove redundant PNGs.

7122. By Stephen Turnbull

Use minlen to disentagle the POSTING queue.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'README.rst'
2--- README.rst 2012-03-13 01:03:35 +0000
3+++ README.rst 2012-03-15 22:29:19 +0000
4@@ -37,6 +37,7 @@
5 src/mailman/docs/START
6 src/mailman/docs/DATABASE
7 src/mailman/docs/MTA
8+ src/mailman/docs/8-miles-high
9 src/mailman/bin/docs/*
10 src/mailman/commands/docs/*
11 src/mailman/database/docs/*
12
13=== removed directory '_static'
14=== removed directory '_templates'
15=== modified file 'conf.py'
16--- conf.py 2012-02-12 15:01:07 +0000
17+++ conf.py 2012-03-15 22:29:19 +0000
18@@ -25,10 +25,12 @@
19
20 # Add any Sphinx extension module names here, as strings. They can be extensions
21 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
22-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
23+extensions = ['sphinx.ext.autodoc',
24+ 'sphinx.ext.viewcode',
25+ 'sphinx.ext.graphviz']
26
27 # Add any paths that contain templates here, relative to this directory.
28-templates_path = ['_templates']
29+# templates_path = ['_templates']
30
31 # The suffix of source filenames.
32 source_suffix = '.rst'
33@@ -122,7 +124,7 @@
34 # Add any paths that contain custom static files (such as style sheets) here,
35 # relative to this directory. They are copied after the builtin static files,
36 # so a file named "default.css" will overwrite the builtin "default.css".
37-html_static_path = ['_static']
38+# html_static_path = ['_static']
39
40 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
41 # using the given strftime format.
42@@ -222,6 +224,7 @@
43 import errno
44 cwd = os.getcwd()
45 try:
46+ os.makedirs('build/sphinx/html')
47 os.chdir('build/sphinx/html')
48 os.symlink('README.html', 'index.html')
49 print 'index.html -> README.html'
50
51=== added file 'src/mailman/docs/8-miles-high.rst'
52--- src/mailman/docs/8-miles-high.rst 1970-01-01 00:00:00 +0000
53+++ src/mailman/docs/8-miles-high.rst 2012-03-15 22:29:19 +0000
54@@ -0,0 +1,190 @@
55+========================================
56+Notes from the PyCon 2012 Mailman Sprint
57+========================================
58+
59+.. authorship
60+ The notes are based on Barry Warsaw's description of the Mailman 3
61+ pipeline at the PyCon 2012 Mailman sprint on March 13, with
62+ diagrams from his "Mailman" presentation at PyCon 2012.
63+ Transcribed by Stephen Turnbull.
64+
65+These are notes from the Mailman sprint at PyCon 2012. They are not
66+terribly well organized, nor fully fleshed out. Please edit and push
67+branches to Launchpad at lp:mailman or post patches to <WHERE?> <URL?>.
68+
69+The intent of this document is to provide a view of Mailman 3's
70+workflow and structures from "eight miles high".
71+
72+
73+Basic Messaging Handling Workflow
74+---------------------------------
75+
76+Mailman accepts a message via the LMTP protocol (RFC 2033). It
77+implements a simple LMTP server internally based on the LMTP server
78+provided in the Python stdlib. The LMTP server's responsibility is to
79+parse the message into a tuple (*mlist*, *msg*, *msg_data*). If the
80+parse fails (including messages which Mailman considers to be invalid
81+due to lack of Message-Id as strongly recommended by RFC 2822 and RFC
82+5322), the message will be rejected, otherwise the tuple is pickled,
83+and the resulting *message pickle* added to one of the IN, COMMAND, or
84+BOUNCE processing queues.
85+
86+.. graphviz::
87+
88+ digraph msgflow {
89+ rankdir = LR;
90+ node [shape=box, color=lightblue, style=filled];
91+ msg [shape=ellipse, color=black, fillcolor=white];
92+ lmtpd [label="LMTP\nSERVER"];
93+ msg -> MTA [label="SMTP"];
94+ MTA -> lmtpd [label="LMTP"];
95+ lmtpd -> MTA [label="reject"];
96+ lmtpd -> IN -> POSTING [label=".pck"];
97+ lmtpd -> BOUNCES [label=".pck"];
98+ lmtpd -> COMMAND [label=".pck"];
99+ }
100+
101+The IN queue is processed by *filter chains* (explained below) to
102+determine whether the post (or administrative request) will be
103+processed. If not allowed, the message pickle is discarded, rejected
104+(returned to sender), or held (added to the MODERATION queue -- not
105+shown). Otherwise the message is added to the POSTING queue.
106+
107+Each of the COMMAND, BOUNCE, and POSTING queues is processed by a
108+*pipeline of handlers* as in Mailman 2's pipeline. (Some functions
109+such as spam detection that were handled in the Mailman 2 pipeline are
110+now in the filter chains.)
111+
112+Handlers may copy messages to other queues (*e.g.*, ARCHIVE), and
113+eventually posts for distribution end up in the OUT queue for
114+injection into the MTA.
115+
116+The VIRGIN queue is a special queue for messages created by Mailman.
117+
118+.. graphviz::
119+
120+ digraph pipeline {
121+ node [shape=box, style=rounded, group=0]
122+ { "MIME\ndelete" -> "cleanse headers" -> "add headers" -> \
123+ "calculate\nrecipients" -> "to digest" -> "to archive" -> \
124+ "to outgoing" }
125+ node [shape=box, color=lightblue, style=filled, group=1]
126+ { rank=same; POSTING -> "MIME\ndelete" }
127+ { rank=same; "to digest" -> DIGEST }
128+ { rank=same; "to archive" -> ARCHIVE }
129+ { rank=same; "to outgoing" -> OUT }
130+ }
131+
132+
133+Message Filtering
134+-----------------
135+
136+Once a message has been classified as a post or administrivia, rules
137+are applied to determine whether the message should be distributed or
138+acted on. Rules include things like "if the message's sender is a
139+non-member, hold it for moderation", or "if the message contains an
140+Approved field with a valid password, distribute it". A rule may also
141+make no decision, in which case the message pickle is passed on to the
142+next rule in the filter chain. The default set of rules looks
143+something like this:
144+
145+.. graphviz::
146+
147+ digraph chain_rules {
148+ rankdir=LR /* This gives the right orientation of the columns. */
149+ rank=same
150+ subgraph in { IN [shape=box, color=lightblue, style=filled] }
151+ subgraph rules {
152+ rankdir=TB
153+ rank=same
154+ node [shape=record]
155+ approved [group=0, label="<f0> approved | {<f1> | <f2>}"]
156+ emergency [group=0, label="<f0> emergency | {<f1> | <f2>}"]
157+ loop [group=0, label="<f0> loop | {<f1> | <f2>}"]
158+ modmember [group=0, label="<f0> member\nmoderated | {<f1> | <f2>}"]
159+ administrivia [group=0, label="<f0> administrivia | <f1>"]
160+ maxsize [group=0, label="<f0> max\ size | {<f1> | <f2>}"]
161+ any [group=0, label="<f0> any | {<f1> | <f2>}"]
162+ truth [label="<f0> truth | <f1>"]
163+ approved:f1 -> emergency:f0 [weight=100]
164+ emergency:f1 -> loop:f0
165+ loop:f1 -> modmember:f0
166+ modmember:f1 -> administrivia:f0
167+ administrivia:f1 -> maxsize:f0
168+ maxsize:f1 -> any:f0
169+ any:f1 -> truth:f0
170+ }
171+ subgraph queues {
172+ rankdir=TB
173+ rank=same
174+ node [shape=box, style=filled];
175+ DISCARD [shape=invhouse, color=black, style=solid];
176+ MODERATION [color=wheat];
177+ HOLD [color=wheat];
178+ }
179+ { POSTING [shape=box, style=filled, color=cyan]; }
180+
181+ IN -> approved:f0
182+ approved:f2 -> POSTING [minlen=2]
183+ loop:f2 -> DISCARD
184+ modmember:f2 -> MODERATION
185+
186+ emergency:f2:e -> HOLD
187+ maxsize:f2 -> MODERATION
188+ any:f2 -> MODERATION
189+ truth:f1 -> POSTING [minlen=2]
190+ }
191+
192+
193+Configuration
194+-------------
195+
196+Uses lazr.config.
197+
198+Each Runner's configuration object knows whether it should be started
199+when the Mailman daemon starts, and what queue the Runner manages.
200+
201+
202+Shell Commands
203+--------------
204+
205+bin/mailman: This is an ubercommand, with subcommands for all the
206+various things admins might want to do, similar to mailmanctl, but
207+with more functionality.
208+
209+bin/master: The runner manager: starts, watches, stops the runner
210+daemons.
211+
212+bin/runner: Individual runner daemons. Each instance is configured
213+with a configure object specified on the command line, and other
214+command line options.
215+
216+
217+User Model
218+----------
219+
220+A *user* represents a person. A user has an *id* and a *display
221+name*, and a list of addresses.
222+
223+Each *address* is a separate object, linked to a user with a user id.
224+
225+A list *member* is a link from a user to a mailing list. Each list
226+member has a user id, a mailing list name, an address (which may be
227+None, which will be replaced by the user's preferred address, a list
228+of preferences, and a *role* such as "owner" or "moderator". Roles
229+are used to determine what kinds of mail the user receives via that
230+membership. *Owners* will receive mail to *list*-owner, but not posts
231+and moderation traffic, for example. A user with multiple roles on a
232+single list will therefore have multiple memberships in that list, one
233+for each role.
234+
235+Roles are implemented by "magical, invisible" *rosters*.
236+
237+
238+List Styles
239+-----------
240+
241+Each list *style* is a named object. Its attributes are functions
242+used to apply the relevant style settings to the mailing list *at
243+creation time*. Since these are functions, they can be composed in
244+various ways, to create substyles, *etc*.