]> git.ipfire.org Git - thirdparty/squid.git/blame - src/base/AsyncJobs.dox
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / base / AsyncJobs.dox
CommitLineData
9a1b46cc 1/*
5b74111a 2 * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
9a1b46cc
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
3889d00c
AR
9/**
10\defgroup AsyncJobs Asynchronous Jobs
11\ingroup Components
12
13\section Terminology Terminology
14
15- \b Job: an AsyncJob object.
16- \b Creator: the code creating the job. Usually the Initiator.
4299f876 17- \b Start: the act of calling AsyncJob::Start with a job pointer.
3889d00c
AR
18- \b Initiator: the code starting the job. Usually the Creator.
19
20\section Life Typical life cycle
21
22-# Creator creates and initializes a job.
4299f876
AR
23-# If Initiator expects to communicate with the job after start,
24 then it stores the job pointer
25-# Initiator starts the job by calling AsyncJob::Start.
3889d00c
AR
26-# The job's start() method is called. The method usually schedules
27some I/O or registers to receive some other callbacks.
28-# The job runs and does what it is supposed to do. This usually involves
29scheduling I/O, setting timeouts, receiving Comm or Store callbacks, and
30then notifying Initiator of the final result.
31-# The job reaches its goal or encounters an error condition.
32-# The swanSong() method is called.
33-# The job object is destroyed.
34
35
36If you want to do something before starting the job, do it in the constructor
37or some custom method that the job creator will call _before_ calling
4299f876 38AsyncJob::Start():
3889d00c 39
829030b5 40 std::unique_ptr<MyJob> job(new MyJob(...)); // sync/blocking
3889d00c
AR
41 job->prepare(...); // sync/blocking
42 job->prepareSomethingElse(...); // sync/blocking
43 AsyncStart(job.release()); // non-blocking
44
45If you do not need complex preparations, it is better to do this instead:
46
4299f876 47 AsyncJob::Start(new MyJob(...));
3889d00c
AR
48
49Keep in mind that you have no async debugging, cleanup, and protections until
4299f876 50you call AsyncJob::Start with a job pointer.
3889d00c
AR
51
52
53\section Rules Basic rules
54
4299f876
AR
55- To start a job, use AsyncJob::Start.
56 Do not start the same job more than once.
60ce3189
AR
57
58- Never call start() directly. Treat this method as main() in C/C++.
3889d00c
AR
59
60- Never call swanSong() directly. If you are outside an AsyncCall
61handler, and want to kill the job, then call deleteThis(). If you are
62inside an AsyncCall handler, you have several options for job termination:
63
64 -# Call mustStop(reason) for errors that require further processing in
65the same method(s) chain, below/after the mustStop() call. Efficient.
66
67 -# Throw (via Must or directly) for errors that do not require further
68processing in the same method(s) chain, below/after the mustStop() call.
69Inefficient but simple and allows exiting from deeply nested method calls.
70
71 -# Otherwise, just finish the call. Your doneAll() should return true
72and the job will terminate successfully.
73
74swanSong() will be called automatically in all of these cases when the
75job is being terminated. It is a general cleanup method, like a
76destructor. The only difference is that a destructor must not throw.
77
78
79- Do not assume swanSong() is called in some perfectly nice job state.
80The job code or the code it calls may throw at any time after start()
81was called. The entry may be gone, the Abort may have been called, the
82fd may have been closed, etc.
83
84
85- Never call deleteThis() in contexts other than those documented above.
86It is a hack for the old-style code. You can avoid it and other
87old-style special precautions altogether if you convert sync calls into
88async ones. This is especially easy for old-style calls that have only
89one parameter ("data") or two simple parameters.
90
91
92- In swanSong, always call swanSong() of the parent, after you are done
93cleaning up your job. It does not matter whether the [current] parent
94swanSong() does nothing.
95
3071d963
AR
96- You must implement start() and doneAll() methods. These methods may be
97marked as pure virtual in future releases.
98
99- In doneAll(), always call doneAll() of the parent. If the parent is not
100done, you are not done. It does not matter whether the [current] parent
101doneAll() always returns true.
3889d00c
AR
102
103- If a job does not have a doneAll() method implemented, it is probably
104buggy. Any job must know what it wants to accomplish. Please note that
105doneAll() is for defining the successful termination goal/condition.
106Errors are handled by mustStop() or throw, as discussed above.
107
108Similarly, if your doneAll() implementation looks like "return isDone;",
109you are doing it wrong. Compute the condition directly rather than
110expecting various job methods to maintain some isDone variable correctly.
111
112
113- If a job does Comm I/O, it probably needs a Comm closing handler.
114
115- If a job stores a StoreEntry, it probably needs an entry Abort handler.
116
117- Ask yourself what the user will see/experience when the job throws,
118which could happen as early as in the start() method (technically, it
119can happen even earlier, during job creation and initialization). Are you
120OK with that?
121
122
123*/