on master help sign in
Revised talk architecture document.
commitdb370a89e0ea955e6aa9bec104c90f2a062298bb authorFang <fang@fang.io> dateWed 3 May 2017, 00:41 (10 years ago) parent810324c
9 files changed+263−130
docs/talk/architecture.md+263−130 docs/talk/diagrams/flow-messaging.png docs/talk/diagrams/flow-reports.png docs/talk/diagrams/flow-subscriptions.png docs/talk/diagrams/talk_flow-lowdowns-subs.png docs/talk/diagrams/talk_flow-lowdowns-ui.png docs/talk/diagrams/talk_flow-messaging.png docs/talk/diagrams/talk_flow-reports.png docs/talk/diagrams/talk_flow-subscribe.png
docs/talk/architecture.md+263−130
@@ -1,208 +1,341 @@
1−# Talk architecture
21
3−This document is complemented by talk's source code, but doesn't require it. Definitions of data structures will be provided where useful.
2+# Talk architecture
43
5−>**Current implementation** remarks mention where the [current implementation](https://github.com/Fang-/arvo/tree/talk-split) differs from what is described, and why changing that to match this document would be desirable.
4+This document is complemented by talk's source code, but doesn't require it. Definitions of data structures, code snippets and diagrams will be provided where useful.
65
76
87## Overview
98
10−At the time of writing, talk is Urbit's biggest user-facing application, and fresh out of a big restructuring. Previously, talk the platform and talk the application were one and the same. Now, they have been split to help clarify their distinction, provide an example of how the platform can be used, and to aid in maintaining and extending it.
11−
12−Official Urbit terminology calls the platform a `guardian` (like a unix daemon) and the application an `agent`. You may also view them as your personal server and client. To be more semantically appropriate for talk, we're calling them `broker` and `reader` respectively.
9+Talk was Urbit's first big user-facing application, and continues to enjoy a prominent role in the Urbit landscape as the primary messaging bus.
1310
14−>It may be desirable to separate the platform from the "talk" name entirely, to decouple it from the client implementation we know and love. Also, "reader" is starting to feel more and more incorrect.
11+To be clear, we make a distinction between "talk the platform" and "talk the chat application". The latter makes use of the former for most of its functionality, and serves as an example of things that can be built on top of the platform. (Also see the small Twitter clone, [feed](http://urbit.org/fora/posts/~2017.4.12..21.14.00..fe17~/).)
12+This document, however, focusses on the platform. In talk's case, we refer to this "server" (or `guardian`, in Urbit terminology) as the *broker*. It manages an identity's messages, subscriptions, and more.
1513
16−Everyone (per identity) has a single broker that does all the heavy lifting. This broker can be used by any number of readers to help them realize their messaging functionality. Examples include the talk application we're all familiar with and the brand new Twitter clone [feed](http://urbit.org/fora/posts/~2017.4.12..21.14.00..fe17~/).
1714
18−Since reader implementations will vary widely, we'll be looking exclusively at the functionality the broker provides and how that can be used. In order to do so, we first look at the core concepts that govern talk's architecture, then delve continuously deeper by examining the interfaces the broker offers, seeing how communication between brokers happens, and finally looking at how it's all implemented.
15+## Core concepts & functionality
1916
20−## Core concepts
21−
22−Before we dive into interfacing with the broker, we need to understand how it sees the world. Let's pull up part of the structure for the broker's state, and some structures that relate to it.
17+To begin to gain an understanding of how the broker functions, let's look at its state mold.
2318
2419```
25−++ house :: broker state
26− $: stories/(map knot story) :: conversations
27− readers/(map bone (set knot)) :: our message readers
28− :: ... ::
29− == ::
30−++ story :: wire content
31− $: grams/(list telegram) :: all messages
32− locals/atlas :: local presence
33− remotes/(map partner atlas) :: remote presence
34− shape/config :: configuration
35− mirrors/(map station config) :: remote config
36− followers/(map bone river) :: subscribers
20+++ state :> broker state
21+ $: stories/(map knot story) :< conversations
22+ readers/(map bone (set knot)) :< our message readers
3723 :: ... ::
3824 == ::
39−++ config :: party configuration
40− $: sources/(set partner) :: pulls from
25+++ story :> wire content
26+ $: grams/(list telegram) :< all messages
27+ locals/group :< local presence
28+ remotes/(map partner group) :< remote presence
29+ shape/config :< configuration
30+ mirrors/(map circle config) :< remote config
31+ followers/(map bone river) :< subscribers
4132 :: ... ::
4233 == ::
4334```
4435
36+Aside from keeping track of `readers`, the different applications that use the broker, it also stores a map of stories.
37+
4538### Stories
4639
47−A `story` is the structure in which a local `station`'s full state is stored. All its messages and configuration, as well as those of other stations.
40+Stories are the primary driver behind the broker. Whether you're hosting a group chat, or just want a place to aggregate messages into, a `story` will be created for it. They contain all data they need to be complete, from messages to metadata.
41+
42+Looking carefully at that metadata, stories seem to store both "local" and "remote" versions. This is to facilitate the "aggregate messages" use-case mentioned above, and core to how subscriptions function. Looking at the `config` structure, we see the following attribute:
4843
49−Why those of other stations? Observe that a station's configuration contains `sources`. These are the station's subscriptions, from which is receives messages and metadata like presences and configurations. When you subscribe to a foreign station, you're not subscribing your identity to it. Rather, you're telling whatever story your reader is using to subscribe to it.
44+```
45+src/(set partner) :< pulls from
46+```
5047
51−Because subscriptions are essentially story-to-story instead of broker-to-story, it is easy for different reader implementations to isolate their functionality from each other. For example, cli-talk uses the `%mailbox` story for subscriptions and message management, and feed uses a `%feed` story for doing the same. Neither have to deal with each other's data, but they can still choose to subscribe to it if they want to (and know the name of the story the other application uses).
48+Every story has a set of sources from which it receives data. If there's nothing in this set, the story will only receive messages people explicitly target towards it. If there *are* sources in that set, then their message will get forwarded to the story automatically. Presences and configurations for those sources are kept track of as well.
5249
53−>**Current implementation** of "cli-talk" (and web-talk too) instantiates with default mailbox and journal stations. This is likely not desirable. Applications should specify their own stories. Using defaults will just end up with them becoming bloated streams of unfiltered noise.
50+In short, stories store messages. They get these either directly, or through any sources they have subscribed to.
5451
55−### `partner` or `station`?
52+### Partners
5653
54+Though these sources are `partner` structures, we can see remote configurations are only stored for so-called `circle`s.
55+
56+```
57+++ partner (each circle passport) :< message target
58+++ circle {hos/ship nom/knot} :< native target
59+++ passport :> foreign target
60+ $% {$twitter p/cord} :< twitter handle
61+ == ::
5762```
58−++ partner (each station passport) :: interlocutor
59−++ station (pair ship knot) :: domestic flow
63+
64+A `partner` is either a `circle` or a `passport`. A `circle` is a native partner, one created by the broker: a named story hosted on a ship, usually represented as `~ship/story`.
65+A `passport` is a non-native partner, such as a Twitter feed. The possibilities for passports are endless... but none of them are properly implemented yet, so for the rest of this document we'll assume a `partner` is always a `circle`.
66+
67+### Access control
68+
69+Though not important to the broker's architecture, the way access control for stories works is useful to understand. There are currently four security modes:
70+
71+```
72+++ security :> security mode
73+ $? $black :< channel, blacklist
74+ $white :< village, whitelist
75+ $green :< journal, author list
76+ $brown :< mailbox, our r, bl w
77+ == ::
6078```
6179
62−A `partner` is either a `station` (a "chat room" hosted on a ship's broker, represented as `~ship-name/station-name`) or a `passport`, which represents a non-station target. An example of a passport is a Twitter handle. Since passports aren't yet fully implemented for any kind of usage, we'll ignore them.
80+A `channel` is publicly readable and writable, with a blacklist for banishing.
81+A `village` is privately readable and writable, with a whitelist for inviting.
82+A `journal` is publicly readable and privately writable, with a whitelist for authors.
83+A `mailbox` is readable by its owner and publicly writable, with a blacklist for blocking.
6384
64−## Interfaces for readers
85+### Federation
6586
66−Now that we know how a broker keeps track of things, we should have an easier time understanding the different interfaces it offers for user/reader actions.
87+One of the primary aspects of Urbit is its decentralized nature. The broker can happily make use of that by federating circles. That is, hosting them on multiple ships simultaneously. They share all messages, presence and configuration, regardless of where that data or change originated.
88+This can help spread heavy load across multiple ships, makes circles easier to access, and allows for fallback in case one of the hosts goes offline.
6789
68−>The interfaces presented here are suggestions, backed by functional implementations. Adding a new interface for existing functionality is trivial. These may be changed or added to as the use cases for talk (the platform) evolve.
90+
91+## Interfaces for applications
92+
93+Applications can interact with the broker in two complementary ways: they can tell it what actions to perform, and they can subscribe to its state changes.
94+
95+### Interactions
96+
97+The broker can be commanded by poking it with `action`s.
6998
7099```
71−++ action :: user action
72− $% :: station configuration ::
73− {$create (trel knot cord posture)} :: create station
74− {$depict (pair knot cord)} :: change description
75− {$delete (pair knot (unit @t))} :: delete + announce
76− {$permit (trel knot ? (set ship))} :: invite/banish
77− {$source (trel knot ? (set partner))} :: un/sub p to/from r
100+++ action :> user action
101+ $% :: circle configuration ::
102+ {$create nom/knot des/cord sec/security} :< create circle
103+ {$delete nom/knot ano/(unit cord)} :< delete + announce
104+ {$depict nom/knot des/cord} :< change description
105+ {$permit nom/knot inv/? sis/(set ship)} :< invite/banish
106+ {$source nom/knot sub/? src/(set partner)} :< un/sub to/from src
107+ {$enlist nom/knot fed/? sis/(set ship)} :< dis/allow federation
108+ {$burden circle} :< help federate
78109 :: messaging ::
79− {$convey (list thought)} :: post exact
80− {$phrase (pair (set partner) (list speech))} :: post easy
110+ {$convey tos/(list thought)} :< post exact
111+ {$phrase aud/(set partner) ses/(list speech)} :< post easy
81112 :: personal metadata ::
82− {$status (pair (set partner) status)} :: our status update
113+ {$status cis/(set circle) sat/status} :< our status update
83114 :: changing shared ui ::
84− {$human (pair ship human)} :: new identity
85− {$glyph (pair char (set partner))} :: bind a glyph
86− == ::
87−++ reaction :: user information
88− $: kind/?($info $fail) :: result
89− what/@t :: explain
90− why/(unit action) :: cause
115+ {$human sip/ship man/human} :< new identity
116+ {$glyph gyf/char pas/(set partner) bin/?} :< un/bind a glyph
91117 == ::
92118```
93119
94−>**Current implementation** doesn't include *all* of the above actions yet, but adding them in is trivial since the functionality is already there.
120+The largest part of these actions concern themselves with managing local circles. `nom` is always the name used to identify the relevant story. To disambiguate between "add" and "delete" type actions (for permissions, subscriptions and federation), a loob `?` is used.
95121
96−>**Current implementation** uses a `(set knot)` for `%status` commands, which limits us to updating our status on local stations only.
122+To send messages, two interfaces are available. `%convey` lets you specify all details of the messages, including its timestamp, serial, and fully assembled audience. `%phrase`, on the other hand, takes care of that for you, allowing you to specify just the target partners and message contents.
97123
98−Most of these `action`s should (hopefully) be fairly self-explanatory. Loobs `?` are used to differentiate between "add" and "delete" actions, `knot`s are used to specify local stations, `partner`s are targets of actions and...
99−"shared ui"? Yes, some UI state gets stored in the broker. Currently these are nicknames and glyph bindings. Those get kept up to date across readers to ensure the user can easily identify other users and stations in a familiar manner, regardless of what reader they're using. (Of course, readers can choose to ignore this if they want to.)
124+`%status` is useful for setting your own presence and nickname in a circle, so others can see if you're active.
100125
101−To give the broker a way to communicate warnings and errors to the readers, it can send them a `reaction`. This way, even though the broker itself isn't user-facing, it can still inform the user of potential failure of their action, or other warnings.
126+> **Current implementation** implements a `%status` command that only works for local circles.
127+
128+"Shared UI" encompasses UI data that should be consistent across applications. For example, if the user sets a local nickname for an identity, they expect to see that nickname regardless of the application they're currently using. The same goes for glyph bindings, for easy audience targeting.
129+
130+Sometimes, in response to a user action, the broker will respond with a `reaction`.
131+
132+```
133+++ reaction :> user information
134+ $: res/?($info $fail) :< result
135+ wat/cord :< explain
136+ why/(unit action) :< cause
137+ == ::
138+```
102139
103−By using these interfaces exclusively, a reader as functional as our current talk can be implemented. Most of the reader code will go towards UI-related tasks, since the broker generically implements all messaging functionality.
140+These are used to inform the application (and thus the user) of any unexpected side effects or errors that occurred as a result of the action they issued.
104141
105−### Reader subscriptions
142+### Subscriptions
106143
107−Those interfaces alone can't provide the reader with any data, however. It still needs to subscribe itself to the stories it's interested in. Let's take a look at a `%peer` move that does just that!
144+To receive data from a broker, applications will have to subscribe to it. A `%peer` move for doing so looks something like this:
108145
109146```
110−:* ost.hid :: bone
111− %peer :: move type
112− /story/some-story :: diff path
113− [our %broker] :: peer target
114− /reader/some-story :: peer path
115−==
147+:* ost.hid :< bone
148+ %peer :< move type
149+ /story/[some-story] :< diff path
150+ [our %broker] :< peer target
151+ /reader/[some-story] :< peer path
152+== ::
116153```
117154
118−Fairly standard. We should mention the paths being used here, however.
119−The diff path is simply something for the reader to use to identify what subscription a diff came from. That is, what story the diff relates to. Not all readers will need this (cli-talk doesn't!), but that's entirely up to the implementation.
120−The peer path informs the broker as to what kind of subscription this is. We always start with `/reader` to identify this as a reader subscription. If we leave the path at that, we subscribe to changes to the shared UI state. If we append a story name to it, we subscribe to changes to that story.
155+The diff path is for the application to use to identify what subscription a diff came from. That is, what story the diff relates to. Not all applications will care for this.
156+The peer path informs the broker of the intent of the subscription. It always starts with `/reader` to indicate we're a client application, not another broker. If the path ends there, it subscribes to shared UI changes. If it goes on to specify a story name, it subscribes to changes to that story.
121157
122−Over a subscription we can either get sent a `reaction` as described above, or a `lowdown`. Let's see what that looks like.
158+These changes get sent as `lowdown`s.
123159
124160```
125−++ lowdown :: changed shared state
161+++ lowdown :> new/changed state
126162 $% :: story state ::
127− {$confs (unit config) (map station (unit config))}:: changed configs
128− {$precs (pair atlas (map partner atlas))} :: changed presences
129− {$grams (pair @ud (list telegram))} :: new grams
163+ $: $confs :< configs
164+ loc/(unit config) :< local config
165+ rem/(map circle (unit config)) :< remote configs
166+ == ::
167+ {$precs reg/crowd} :< presences
168+ {$grams num/@ud gaz/(list telegram)} :< messages
130169 :: ui state ::
131− {$glyph (jug char (set partner))} :: new bindings
132− {$names (map ship (unit human))} :: new identities
170+ {$glyph (jug char (set partner))} :< glyph bindings
171+ {$names (map ship (unit human))} :< nicknames
133172 == ::
134173```
135174
136−`lowdown`s inform a reader of changes to story or UI state. You'll see these cover most of the story state we described above.
137−
138−It's important to note that lowdowns contain just that which has changed, just the "diff". This is why configurations are wrapped in `unit`s, so we can signify deletion. This means simple readers that don't even keep state can still inform you when someones presence has changed.
175+Aside from the initial lowdown that is sent when a subscription starts, these contains exclusively the changes as they occur. Configurations are wrapped in `unit`s so that deletion can be indicated. This also means that simple applications don't necessarily need to keep state. If all they want to do is show events as they happen, then the broker subscription will provide all they need.
139176
140−>Sending "just the diff" is a little bit trickier for `config`s, since they're a more complex structure than "just a map of maps". For now, the best we do is send only the configs that have changed, but not the individual changes within those configs.
141177
142178## Communication between brokers
143179
180+Brokers can communicate with other brokers to send commands and subscription updates.
181+
182+### Interaction
183+
184+To request changes to a story, brokers can send `command`s.
185+
144186```
145−++ command :: effect on party
146− $% {$review (list thought)} :: deliver
187+++ command :> effect on story
188+ $% {$review tos/(list thought)} :< deliver
189+ $: $burden :< starting fed state
190+ nom/knot ::
191+ cof/lobby ::
192+ pes/crowd ::
193+ gaz/(list telegram) ::
194+ == ::
195+ {$relief nom/knot who/(set ship)} :< federation ended
147196 == ::
148197```
149198
150−>**Current implementation** hasn't deprecated the `%design` and `%publish` commands yet. They should be, because they have `action` equivalents and are exclusively used by your own identity.
199+A `%review` command contains messages. These are sent to foreign brokers to be published to one of their stories.
200+
201+`%burden` and `%relief` commands are used for federation. The former signals the sender wants to start federating story `nom`, and contains any pre-existing state that needs to be merged into it. The latter signals that the hosts in `who` will no longer be federating the story.
151202
152−When you tell your broker to post a message (through the `%convey` or `%phrase` commands), it looks at the audience you want the message to be sent to. For each station, it sends a `%review` command to the host ship, asking for the message to be reviewed and accepted.
203+### Subscriptions
153204
154−When a message gets added to a story, or a presence or configuration in it gets changed, all who are subscribed to that story get notified. This is done via `report`s.
205+Brokers subscribe to other brokers whenever a source gets added to a story's configuration. (Likewise, they unsubscribe when a source is removed.) Subscribers, also knows as story "followers", get sent `report`s whenever changes occur.
155206
156207```
157−++ report :: talk update
158− $% {$cabal config} :: local config
159− {$group register} :: presences
160− {$grams (pair @ud (list telegram))} :: thoughts
208+++ report :> update
209+ $% {$lobby cab/lobby} :< config neighborhood
210+ {$crowd reg/crowd} :< presence
211+ {$grams num/@ud gaz/(list telegram)} :< thoughts
161212 == ::
162−++ register (pair atlas (map partner atlas)) :: ping me, ping srcs
213+++ lobby {loc/config rem/(map circle config)} :< our & srcs configs
214+++ crowd {loc/group rem/(map partner group)} :< our & srcs presences
163215```
164216
165−>Whereas lowdowns send just the information that has changed, reports always send the entire thing. It might technically be possible to send just the diff, but this needs to be looked into further. Diffs are in a bit of a vague spot currently anyway, see below.
217+There are three different kinds of reports, for configurations, presences, and messages.
166218
167−Non-message reports include both local and remote presences. This is useful in federation, where subscribers are also interested in the presences on related stations.
219+Attentive eyes may have seen this in lowdowns as well, they contains both local and remote data. This is required for federation to share full state, and some regular subscribers might take interest in that data as well.
168220
169−>Federation is, at the time of writing, largely untested. Messages and presences seem to work fine, but configuration sharing isn't in yet. The solution that's currently in try-out development is having a "federator whitelist", and using a special command to signify a ship starts federating, so that users don't have to manually chain sources together.
170221
171−>**Current implementation** also sends remote configurations in the `%cabal` report. This doesn't seem to be useful for anything. In case of federation, you would want all stations to copy each other's configuration.
222+## Broker implementation
172223
224+Now that we know what gets sent over the wire and why, let's see what happens whenever such events happen. We won't be covering everything, but enough to illustrate the general flow.
173225
174−## Broker implementation
226+First though, it's useful to understand how the broker's code is structured. It consists of two primary cores that are used as engines for applying changes to state and producing moves for output.
227+
228+* `++ta` is the transaction core. For every event that happens, be it a poke, peer of diff, the transaction core gets put to work to process it. Once it's done, it produces a list of moves and the new state.
229+* `++so` is the story core, used by `++ta` for applying changes to stories. In doing so, it may add moves to the transaction core for it to produce.
230+
231+Once all work in an engine core has finished, its `-done` arm is called to produce moves and apply the changes it made back into the application state.
232+
233+In the diagrams that follow, regular lines indicate flows that always happen. Dashed lines indicate flows that are traversed if the described condition is met.
234+Below the diagrams you will find brief explanations of the involved arms. In a particularly bright future, these might be available on-hover instead.
235+For brevity, utility arms that aren't a direct and important part of the flow have been omitted.
236+
237+### Subscriptions
238+
239+Broker-to-broker subscriptions happen when a source gets added to a story. This is done with a `%source` action, and results in a `%peer` move being sent. Upon receiving a peer, the broker validates the subscription and sends the current state.
240+
241+![subscriptions implementation flow](./diagrams/flow-subscriptions.png "subscriptions implementation flow")
242+
243+```
244+++ poke-talk-action :< we got poked with an action.
245+ ++ ta-action :< applies an action.
246+ ++ ta-config :< (re)configures a story.
247+ ++ so-reform :< changes the configuration of the story.
248+ ++ so-acquire :< subscribes the story to new sources.
249+:: ::
250+++ peer :< we got peered.
251+ ++ ta-subscribe :< sends initial data: current state.
252+ ++ so-report-lobby :< sends a report with configurations.
253+ ++ so-notify :< changes a ship's presence in the story.
254+ ++ so-report-crowd :< sends a report with presences.
255+ ++ so-start :< determines the backlog of messages to send.
256+ ++ so-first-grams :< sends a range of messages and adds follower.
257+```
258+
259+### Reports
260+
261+Once a subscription has been established, the broker will receive reports. `%lobby` and `%group` reports are applied through the following flow. Note how, when a `%lobby` from a federating ship is received, this authoritatively changes the story's configuration.
262+
263+![report diff implementation flow](./diagrams/flow-reports.png "report diff implementation flow")
264+
265+```
266+++ diff-talk-report :< we got a subscription report.
267+ ++ ta-diff-report :< applies a report to the story it's intended for.
268+ ++ so-diff-report :< applies a report.
269+ ++ so-lobby :< stores updated configuration.
270+ ++ so-reform :< changes the configuration of the story.
271+ ++ so-report-lobby :< sends a report with configuration.
272+ ++ so-remind :< stores updated presences.
273+ ++ so-report-crowd :< sends a report with presences.
274+```
275+
276+### Messaging
277+
278+To send messages, the user sends a `%convey` or `%phrase` action, resulting in a `%review` command being sent to the involved partners. Receiving a `%review` command causes its messages to be added to the story, which sends a `%grams` report to followers and a `%grams` lowdown to all reader applications.
279+
280+![messaging implementation flow](./diagrams/flow-messaging.png "messaging implementation flow")
281+
282+```
283+++ poke-talk-action :< we got poked with an action.
284+ ++ ta-action :< applies an action.
285+:: ::
286+++ poke-talk-command :< we get poked with a command.
287+ ++ ta-apply :< applies a command.
288+ ++ ta-think :< consumes each message in the given list.
289+ ++ ta-consume :< conducts a message to each partner in audience.
290+ ++ ta-conduct :< records or sends a message.
291+ ++ ta-transmit :< sends a message to a partner.
292+ ++ ta-record :< stores a message in a story.
293+:: ::
294+++ diff-talk-report :< we got a subscription report.
295+ ++ ta-diff-report :< applies a report to the story it's intended for.
296+ ++ so-diff-report :< applies a report.
297+ ++ so-lesson :< learns a list of messages.
298+ ++ so-learn :< either adds or modifies a message.
299+ ++ so-append :< adds a new message to the story.
300+ ++ so-revise :< modifies an existing message in the story.
301+ ++ so-refresh :< sends messages to all interested subscribers.
302+```
303+
304+
305+## The future
306+
307+Talk is neither complete nor perfect. There are still problems that need to be solved and features that need to be implemented.
308+
309+### Architectural issues
310+
311+To distribute commands and reports to all that are affected by it, the broker takes a "propagate changes" approach. If, in processing a report, any state changes, new state gets sent to all interested brokers... even those it got the report from in the first place. This results in a lot of unnecessary data transfer, where everyone always gets notified of each other's state changes, regardless of whether those changes are old news or not.
312+
313+While not a practical problem (yet, things work fine at the current scale of use), it does underline the need for a more structured approach to the broker's subscription model. In an ideal world, every interested node gets notified of a set of changes exactly once.
314+
315+### Features and functionality
316+
317+To turn talk into a [sustainable social platform](https://urbit.org/fora/posts/~2017.4.26..18.00.25..b93c~/), it needs a number of things.
318+
319+Primarily, discoverability of circles. A possible solution for realizing this is making it possible for users to add friends, which would have their broker subscribe to a list of circles the added friends are in. Of course, one will be able to set joined circles as "private" to keep them from being visible to others.
320+
321+Eventually, content self-moderation might need to be implemented. Users would flag their content if it is potentially offensive. Others would easily be able to filter out content that might offend them.
322+This functionality brings its own large sets of challenges that need to be tackled.
323+
324+Additionally, federation might be put to broader use. Knowing a circle is federated could help fall back to alternative hosts in case the one the broker originally subscribed to is unavailable.
325+Implementation-wise, care would need to be taken for this to not get ugly. Not to mention, when/how would availability of a host be verified?
326+
327+Smaller functionality that still needs to be implemented includes:
328+* Extended permissions management. Being able to black-/whitelist entire ship classes.
329+* Improved presence functionality. Actually using the presence system, and sending "typing", "idle", etc. statuses.
330+* Per-circle message rules. Dis/allow unicode, enforce line length, etc.
331+* Flexible on-subscribe scrollback. Some cases may want more than just a day's worth.
332+* Talkpolls.
333+
334+
335+## Further reading
336+
337+To gain a more thorough understanding of the broker's inner workings, take a look at its source code. It comes with inline documentation.
338+[link]
175339
176−For every event (poke, peer, etc.) the broker receives, it calls an arm from the `++ra` core. The event gets processed, and if needed, the `++pa` core is invoked to make changes to stories. If anything interesting happens, an event is sent to relevant brokers and/or readers.
177−
178−Below you'll find diagrams outlining the arm flows for various common events. If you want to see what they do in more detail, looking at the code might be a good idea.
179−
180−@TODO update diagrams where necessary, put them here, walk the reader through them briefly.
181−
182−
183−## Roadmap
184−
185−Things currently on the to-do list, roughly in order of priority:
186−(Cleanup, rewriting for clarity and improving inline documentation will be done once we have a shippable talk.)
187−
188−* **Architecture** / high-impact changes
189− * Implement federation.
190− * Should config be determined by the original station, or should "federators" be allowed to make changes as well?
191− * Is anyone allowed to federate any station they can subscribe to? (Definitely not if the above is "allowed to make changes"!)
192− * Move fora things out of the broker.
193− * *Maybe* make it its own reader app?
194− * Improve presence capabilities.
195− * Separate presence from handles.
196− * Command for setting our presence in a foreign station.
197− * "Typing", "idle", etc.
198− * Extended permissions management?
199− * It might be nice to be able to white/blacklist entire classes
200−* **Functionality**
201− * Flexible subscribe ranges.
202− * As opposed to the current always-default "a day old, and everything newer forever". of ships (ie, disallow all comets.)
203− * List (accessible) stations on ships.
204− * Talkpolls!
205− * Per-channel message sanitization configuration?
206− * Allow/disallow capitals, unicode, etc.
207− * Better glyph management.
208− * Better line splitting.
340+To see an expansive example of an application that uses the broker, take a look at the code of the talk reader. This, too, comes with inline documentation.
341+[link]
docs/talk/diagrams/flow-messaging.pngnew file

Binary file not shown.

docs/talk/diagrams/flow-reports.pngnew file

Binary file not shown.

docs/talk/diagrams/flow-subscriptions.pngnew file

Binary file not shown.

docs/talk/diagrams/talk_flow-lowdowns-subs.pngdeleted

Binary file not shown.

docs/talk/diagrams/talk_flow-lowdowns-ui.pngdeleted

Binary file not shown.

docs/talk/diagrams/talk_flow-messaging.pngdeleted

Binary file not shown.

docs/talk/diagrams/talk_flow-reports.pngdeleted

Binary file not shown.

docs/talk/diagrams/talk_flow-subscribe.pngdeleted

Binary file not shown.