1Backoffice
2==========
3
4This is technical documentation about the internal workings of Fossil.
5Ordinary Fossil users do not need to know about anything covered by this
6document.  The information here is intended for people who want to enhance
7or extend the Fossil code, or who just want a deeper understanding of
8the internal workings of Fossil.
9
10What Is The Backoffice
11----------------------
12
13The backoffice is a mechanism used by a
14[Fossil server](./server/) to do low-priority
15background work that is not directly related to the user interface.  Here
16are some examples of the kinds of work that backoffice performs:
17
18  1.  Sending email alerts and notifications
19  2.  Sending out daily digests of email notifications
20  3.  Other background email handling chores
21  4.  Automatic syncing of peer repositories
22  5.  Repository maintenance and optimization
23
24(As of 2018-08-07, only items 1 and 2 have actually been implemented.)
25The idea is that the backoffice handles behind-the-scenes work that does
26not have tight latency requirements.
27
28When Backoffice Runs
29--------------------
30
31A backoffice process is usually launched automatically by a webpage
32request.  After each webpage is generated, Fossil checks to see if any
33backoffice work needs to be done. If there is work to do, and no other
34process is already assigned to do the work, then a new backoffice process
35is started to do the work.
36
37This happens for every webpage, regardless of how that webpage is launched,
38and regardless of the purpose of the webpage.  This also happens on the
39server for "[fossil sync](/help?cmd=sync)" and
40[fossil clone](/help?cmd=clone)" commands which are implemented as
41web requests - albeit requests that the human user never sees.
42Web requests can arrive at the Fossil server via direct TCP/IP (for example
43when Fossil is started using commands like "[fossil server](/help?cmd=server)")
44or via [CGI](./server/any/cgi.md) or
45[SCGI](./server/any/scgi.md) or via SSH.
46A backoffice process might be started regardless of the origin of the
47request.
48
49The backoffice is not a daemon.  Each backoffice process runs for a short
50while and then exits.  This helps keep Fossil easy to manage, since there
51are no daemons to start and stop.  To upgrade Fossil to a new version,
52you simply replace the older "fossil" executable with the newer one, and
53the backoffice processes will (within a minute or so) start using the new
54one.  (Upgrading the executable on Windows is more complicated, since on
55Windows it is not possible to replace an executable file that is in active
56use.  But Windows users probably already know this.)
57
58The backoffice is serialized and rate limited.  No more than a single
59backoffice process will be running at once, and backoffice runs will not
60occur more frequently than once every 60 seconds.  (The 60-second spacing
61is controlled by the BKOFCE_LEASE_TIME macro in the
62[backoffice.c](/file/src/backoffice.c) source file.)
63
64If a Fossil server is idle, then no backoffice processes will be running.
65That means there are no extra processes sitting around taking up memory
66and process table slots for seldom accessed repositories.
67The backoffice is an on-demand system.
68A busy repository will usually have a backoffice
69running at all times.  But an infrequently accessed repository will only have
70backoffice processes running for a minute or two following the most recent
71access.
72
73Manually Running The Backoffice
74-------------------------------
75
76The automatic backoffice runs are sufficient for most installations.
77However, the daily digest of email notifications is handled by the
78backoffice.  If a Fossil server can sometimes go more than a day without
79being accessed, then the automatic backoffice will never run, and the
80daily digest might not go out until somebody does visit a webpage.
81If this is a problem, an administrator can set up a cron job to
82periodically run:
83
84>   fossil backoffice _REPOSITORY_
85
86That command will cause backoffice processing to occur immediately.
87Note that this is almost never necessary for an internet-facing
88Fossil repository, since most repositories will get multiple accesses
89per day from random robots, which will be sufficient to kick off the
90daily digest emails.  And even for a private server, if there is very
91little traffic, then the daily digests are probably a no-op anyhow
92and won't be missed.
93
94Automatic Backoffice Does Not Work On Some Systems
95--------------------------------------------------
96
97We have observed that the automatic backoffice does not work on
98some system - OpenBSD in particular.  We still do not understand why
99this is.  (If you have insights, please share them on the
100[Fossil Forum](https://fossil-scm.org/forum) so that we can perhaps
101fix the problem.)  For now, the backoffice must be run manually
102on OpenBSD systems.
103
104To set up fully-manual backoffice, first disable the automatic backoffice
105using the "[backoffice-disable](/help?cmd=backoffice-disable)" setting.
106
107>   fossil setting backoffice-disable on
108
109Then arrange to invoke the backoffice separately using a command
110like this:
111
112>   fossil backoffice --poll 30 _REPOSITORY-LIST_
113
114Multiple repositories can be named.  This one command will handle
115launching the backoffice for all of them.  There are additional useful
116command-line options.  See the "[fossil backoffice](/help?cmd=backoffice)"
117documentation for details.
118
119The backoffice processes run manually using the "fossil backoffice"
120command do not normally use a lease.  That means that you run the
121"fossil backoffice" command with --poll and you forget to disable
122automatic backoffice by setting the "backoffice-disable" flag, then
123you might have one backoffice running due command and another due
124to a webpage access, both at the same time.  This is harmless.  The
125only downside is that it uses extra CPU time.
126
127How Backoffice Is Implemented
128-----------------------------
129
130The backoffice is implemented by the
131"[backoffice.c](/file/src/backoffice.c)" source file.
132
133Serialization and rate limiting is handled by a single entry in the
134repository database CONFIG table named "backoffice".  This entry is
135called "the lease".  The value of the lease
136is a text string representing four integers, which
137are respectively:
138
139  1.  The process id of the "current" backoffice process
140  2.  The lease expiration time of the current backoffice process
141  3.  The process id of the "next" backoffice process
142  4.  The lease expiration time for the next backoffice process
143
144Times are expressed in seconds since 1970.  A process id of zero means
145"no process".  Sometimes the process id will be non-zero even if there
146is no corresponding process. Fossil knows how to figure out whether or
147not a process still exists.
148
149You can print out a decoded copy of the current backoffice lease using
150this command:
151
152>  fossil test-backoffice-lease -R _REPOSITORY_
153
154If a system has been idle for a long time, then there will be no
155backoffice processes.  (Either the process id entries in the lease
156will be zero, or there will exist no process associated with the
157process id.) When a new web request comes in, the system
158sees that no backoffice process is active and so it kicks off a separate
159process to run backoffice.
160
161The new backoffice process becomes the "current" process.  It sets a
162lease expiration time for itself to be 60 seconds in the future.
163Then it does the backoffice processing and exits.  Note that usually
164the backoffice process will exit long before its lease expires.  That
165is ok.  The lease is there to limit the rate at which backoffice processes
166run.
167
168If a new backoffice process starts up and sees that the "current" lease has
169yet to expire, the new process makes itself the "next" backoffice process
170and sets its expiration time to be 60 seconds past the expiration time of
171the "current" backoffice process.  The "next" process then puts itself to
172sleep until the "current" lease expires.  After the "current"
173lease expires and the "current" process has itself exited, then
174the "next" process promotes itself to the new "current" process.  It
175sets the current lease expiration to be 60 seconds in the future, runs
176whatever backoffice work is needed, then exits.
177
178If a new backoffice process starts up and finds that there is already
179a "current" lease and a "next" process, it exits without doing anything.
180This should happen only rarely, since the lease information is checked
181prior to spawning the backoffice process, so a conflict will only happen
182in a race.
183
184Because the "backoffice" entry of the CONFIG table is in the repository
185database, access to the lease is serialized.  The lease prevents more
186than one backoffice process from running at a time.  It prevents
187backoffice processes from running more frequently than once every 60 seconds.
188And, it guarantees (assuming processes are not killed out-of-band) that
189every web request will be followed within 60 seconds by a backoffice
190run.
191
192Debugging The Backoffice
193------------------------
194
195The backoffice should "just work".  It should not require administrator
196attention.  However, if you suspect that something is not working right,
197there are some debugging aids.
198
199We have already mentioned the command that shows the backoffice lease
200for a repository:
201
202>  fossil test-backoffice-lease -R _REPOSITORY_
203
204Running that command every few seconds should show what is going on with
205backoffice processing in a particular repository.
206
207There are also settings that control backoffice behavior.  The
208"backoffice-nodelay" setting prevents the "next" process from taking a
209lease and sleeping.  If "backoffice-nodelay" is set, that causes all
210backoffice processes to exit either immediately or after doing whatever
211backoffice works needs to be done.  If something is going wrong and
212backoffice leases are causing delays in webpage processing, then setting
213"backoffice-nodelay" to true can work around the problem until the bug
214can be fixed.  The "backoffice-logfile" setting is the name of a log
215file onto which is appended a short message everything a backoffice
216process actually starts to do the backoffice work.  This log file can
217be used to verify that backoffice really is running, if there is any
218doubt.  The "backoffice-disable" setting prevents automatic backoffice
219processing, if true.  Use this to completely disable backoffice processing
220that occurs automatically after each HTTP request.  The "backoffice-disable"
221setting does not affect the operation of the manual
222"fossil backoffice" command.
223Most installations should leave "backoffice-nodelay" and "backoffice-disable"
224set to their default values of off and
225leave "backoffice-logfile" unset or set to an empty string.
226