]> Sergey Matveev's repositories - mmc.git/blob - doc/arch.texi
88fd2ad7b6d704bcfdc4aebba623b39448af9b48
[mmc.git] / doc / arch.texi
1 @node Architecture
2 @unnumbered Architecture
3
4 Brief scheme of commands, utilities and files involved is below.
5 @file{F} means files/FIFOs/directories creation and altering.
6 @file{R} means running of external programs.
7
8 @verbatim
9 cmd/start
10   F tmux.conf
11   R tmux -f tmux.conf
12     R tail -f debug | tai64n
13     R fzf **(/) | cmd/newwin
14     R cmd/mmc | tai64n
15      F users/.../{id,email,name,|in,out.rec,|status,last}
16      F chans/.../{id,info,out.rec,|users,last}
17      F file/{|get,|out}
18      R cmd/notify
19        R tmux display-message ...
20      R cmd/newwin
21        R cmd/rd/colourized
22          R cmd/rd < .../out.rec | spc
23        R cmd/wr
24          R for { rlwrap cat > .../in }
25
26 cmd/download
27   R echo ... > file/get
28   R tar xf < file/out
29
30 cmd/scrollback > history.rec
31 @end verbatim
32
33 @url{https://tools.suckless.org/ii/usage/, ii} IRC client's page has
34 many links to similar kind of chat software. There is some long-living
35 program, that deals with the messaging protocol and communicates with
36 other programs through the FIFO files.
37
38 There are user chats and group chats, both in IRC, XMPP and MM worlds.
39 Each user and channel have corresponding directory having the same name.
40 It contains @file{in} and @file{out} named pipes. Anything you write to
41 @file{in} will be send as a message to corresponding user/channel.
42 Reading from @file{out} will give you incoming messages from that
43 user/channel. That is the basic idea of the backend.
44
45 All you need is to write the frontend that will give you convenient
46 ability to deal with all that bunch of files. That is the most
47 complicated part of course. I do not like idea of having the single
48 window with consolidation of all chats, like using @command{multitail}
49 on several pipes. I do not like idea of purely CLI utility like
50 @url{https://github.com/agl/xmpp-client, github.com/agl/xmpp-client},
51 @url{https://en.wikipedia.org/wiki/MICQ, mICQ} or
52 @url{https://www.gnu.org/software/freetalk/, GNU Freetalk}, where you
53 have to carefully be aware of whom you are typing now. I like
54 @command{irssi} and @command{mcabber}, where you have got separate
55 window with per-user/channel output and input. We must have ability to
56 hide/close those windows/tabs/panes, automatically open them if they got
57 incoming events and we must be alerted about those events, at least by
58 bell character.
59
60 @url{https://github.com/tmux/tmux/wiki, tmux} is a perfect tool for
61 dynamic windows/tabs/panes management. It already has all necessary
62 functions to detect bell/alarms. It have ability to easily create you
63 own keybindings and already have massive amount of convenient hotkeys to
64 quickly navigate among all that windows. It already has history buffer
65 and ability to search in it. And it is likely to be already used by the
66 end user.
67
68 Messages have to be saved on filesystem. Unlike IRC, MM messages are
69 often multiline and can have additional metadata like unique identifiers
70 and attached files. So each message is a more complicated entity than
71 text string with appended timestamp and sender information. Each time
72 chat window is opened, I want to see tail of the corresponding history.
73 So instead of using FIFO that is @command{tee}-ed to ordinary
74 long-living file, I decided to use append-only
75 @url{https://www.gnu.org/software/recutils/, GNU Recutils}'es recfile.
76 And an additional program that translates it to convenient human
77 readable lines, also acting like @command{tail -f}.
78
79 It is crucial to read message you want to send not line by line, to be
80 able to send multiline messages in a single post. Closing the FIFO file
81 can be treated as the end of the message. To be able to use rich line
82 editing capabilities or even external editor, you can use great
83 @url{https://github.com/hanslub42/rlwrap, rlwrap} utility in an endless
84 loop.
85
86 So how all that decisions are composed together?
87
88 @itemize
89
90 @item @command{cmd/start} creates @file{debug} FIFO, prepares
91 configuration file for @command{tmux} (actually there is just single
92 path to the command replaced with the real one) and runs it with single
93 window split on two halves: one just shows debug messages (all raw MM
94 messages for debugging), another one runs @command{cmd/mmc} itself.
95
96 @item @command{cmd/mmc} logs in to the server, fetches a list of all
97 known users and channels I am subscribed to. Then it creates necessary
98 @file{users/NAME} and @file{chans/NAME} directories with some basic
99 regular information files (like identifiers and email addresses) with
100 various FIFOs.
101
102 @item Reading @file{users/.../status} shows you current user's status.
103 @file{chans/.../users} shows currently subscribed users.
104
105 @item @file{out.rec} is append-only database of passed messages.
106 @file{last} contains the identifier of the last received message. After
107 you log in, it is used to fetch newly appeared messages while you were
108 offline.
109
110 @item If some user changes its status, or someone is typing, then
111 @command{cmd/mmc} calls @command{cmd/notify} command with corresponding
112 message. Currently that handler just asks @command{tmux} to
113 @command{display-message} for 1.5 seconds.
114
115 @item If new message comes in, then @command{cmd/mmc} calls
116 @command{cmd/newwin} and tells what window it has to open.
117 @command{cmd/newwin} checks if @command{tmux} has opened it already.
118 Newly created window has the name of the user/channel and is split on
119 two parts:
120     @itemize
121     @item
122     one part contains the output of @command{cmd/rd} piped through
123     @url{http://supercat.nosredna.net/, supercat} (@command{spc}) for
124     colourizing.
125     @item
126     other part holds an endless cycle of @command{rlwrap}-ed
127     @command{cat} piped to corresponding @file{in} FIFO.
128     @end itemize
129
130 @item Also you can manually open desired chat window by pressing
131 predefined keybinding, that will show you
132 @command{https://github.com/junegunn/fzf, fzf}-backed list of all known
133 users and channels.
134
135 @item @command{cmd/rd} reads @file{out.rec} file and prints last ten
136 messages (by default) in human readable form. It does not close that
137 file, but regularly checks if it is updated, to immediately print the
138 newly appeared messages. It print bell character with each message, so
139 it sets an alert for window in @command{tmux}.
140
141 @end itemize
142
143 Outside that running @command{tmux} user can use @command{cmd/download}
144 utility to download specified file's identifier. It sends it identifier
145 to @file{file/get} and reads the archive with that file from
146 @file{file/out}. File is sent inside
147 @url{https://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_01,
148 pax archive} to keep its original name and MM's file identifier.