1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
//! Configuring `takeaway`.
//----------- Config -----------------------------------------------------------
use NonZeroUsize;
use crate::;
/// Configuration for a [`Queue`].
///
/// This is a collection of the settings for a [`Queue`] that need to be
/// determined before it can be created. It provides a builder-pattern API
/// for easy use, ending in [`Config::build()`] to create the final [`Queue`].
///
/// To create a [`Config`], use [`Default`] if the `std` feature is enabled;
/// otherwise, decide on a number of workers and use [`Config::new()`]. All
/// available settings are described below.
///
/// # Settings
///
/// The following settings are currently defined:
///
/// ## Number of Workers
///
/// The number of workers used to execute tasks. Precisely this many
/// [`Worker`]s will be associated with the [`Queue`]; it is the caller's
/// responsibility to drive them all.
///
/// [`Worker`]: crate::Worker
///
/// `takeaway` is intended for CPU-heavy task processing, so it's
/// not recommended to use more workers than the host machine can run
/// simultaneously. If you want to perform CPU-heavy work _alongside_
/// `takeaway`, you could configure a smaller number of workers.
///
/// This is configured in [`Config::new()`]. If the `std` feature is enabled,
/// [an implementation][impl-default] of [`Default`] is provided which sets it
/// to [`std::thread::available_parallelism()`]. The configured value can be
/// accessed through [`Config::num_workers()`].
///
/// [impl-default]: #impl-Default-for-Config
///
/// ## Batch Size
///
/// The ideal size to group tasks in for processing. `takeaway` has to share
/// information about tasks between different workers, and this incurs a
/// communication / synchronization cost. To amortize this, `takeaway` operates
/// on _batches_ of tasks, and this setting controls the maximum size of each
/// batch. `takeaway` will aim to group tasks in the largest batches possible,
/// i.e. it will aim for this size.
///
/// The default batch size is 64. Reducing the batch size can improve task
/// distribution, e.g. getting high-priority tasks to be executed faster, at the
/// cost of increased communication overhead. Increasing the batch size will
/// have the opposite effect, worsening task distribution but reducing overhead.
/// Only consider tuning the batch size if `takeaway` has a performance impact
/// on your program, or if you notice high-priority tasks getting delayed.
///
/// This can be configured by [`Config::with_batch_size()`], and the configured
/// value can be accessed through [`Config::batch_size()`].
///
/// ## One-shot Mode
///
/// `takeaway` can be used in two distinct modes, depending on your program's
/// needs: *daemon mode* (the default), where `takeaway` will never shut down
/// (automatically) because it expects new tasks to be introduced at any time;
/// and *one-shot mode*, where `takeaway` will shut down the moment all known
/// tasks are complete.
///
/// In one-shot mode, `takeaway` expects to be launched with an initial set of
/// tasks; as these tasks are executed, they may spawn sub-tasks as well. Tasks
/// are not expected to be added externally. As soon as all tasks (i.e. the
/// initial set and their descendants) finish, [`Queue::shutdown()`] will be
/// called.
///
/// In either mode, you can call [`Queue::shutdown()`] at any time to shut down
/// the system manually. If one-shot mode does not quite meet your needs, you
/// can track completion yourself and initiate a shutdown appropriately. You
/// may also wish to initiate a shutdown in response to CTRL-C.
///
/// This can be configured by [`Config::with_oneshot()`], and the configured
/// value can be accessed through [`Config::oneshot()`].