Revision 887c7aa6 doc/design-2.3.rst
b/doc/design-2.3.rst | ||
---|---|---|
205 | 205 |
a restart or crash of the master daemon. |
206 | 206 |
|
207 | 207 |
Priorities also need to be considered inside the locking library to |
208 |
ensure opcodes with higher priorities get locks first, but the design
|
|
209 |
changes for this will be discussed in a separate section.
|
|
208 |
ensure opcodes with higher priorities get locks first. See
|
|
209 |
:ref:`locking priorities <locking-priorities>` for more details.
|
|
210 | 210 |
|
211 | 211 |
Worker pool |
212 | 212 |
+++++++++++ |
... | ... | |
243 | 243 |
With these changes, the job queue will be able to implement per-job |
244 | 244 |
priorities. |
245 | 245 |
|
246 |
.. _locking-priorities: |
|
247 |
|
|
248 |
Locking |
|
249 |
+++++++ |
|
250 |
|
|
251 |
In order to support priorities in Ganeti's own lock classes, |
|
252 |
``locking.SharedLock`` and ``locking.LockSet``, the internal structure |
|
253 |
of the former class needs to be changed. The last major change in this |
|
254 |
area was done for Ganeti 2.1 and can be found in the respective |
|
255 |
:doc:`design document <design-2.1>`. |
|
256 |
|
|
257 |
The plain list (``[]``) used as a queue is replaced by a heap queue, |
|
258 |
similar to the `worker pool`_. The heap or priority queue does automatic |
|
259 |
sorting, thereby automatically taking care of priorities. For each |
|
260 |
priority there's a plain list with pending acquires, like the single |
|
261 |
queue of pending acquires before this change. |
|
262 |
|
|
263 |
When the lock is released, the code locates the list of pending acquires |
|
264 |
for the highest priority waiting. The first condition (index 0) is |
|
265 |
notified. Once all waiting threads received the notification, the |
|
266 |
condition is removed from the list. If the list of conditions is empty |
|
267 |
it's removed from the heap queue. |
|
268 |
|
|
269 |
Like before, shared acquires are grouped and skip ahead of exclusive |
|
270 |
acquires if there's already an existing shared acquire for a priority. |
|
271 |
To accomplish this, a separate dictionary of shared acquires per |
|
272 |
priority is maintained. |
|
273 |
|
|
274 |
To simplify the code and reduce memory consumption, the concept of the |
|
275 |
"active" and "inactive" condition for shared acquires is abolished. The |
|
276 |
lock can't predict what priorities the next acquires will use and even |
|
277 |
keeping a cache can become computationally expensive for arguable |
|
278 |
benefit (the underlying POSIX pipe, see ``pipe(2)``, needs to be |
|
279 |
re-created for each notification anyway). |
|
280 |
|
|
281 |
The following diagram shows a possible state of the internal queue from |
|
282 |
a high-level view. Conditions are shown as (waiting) threads. Assuming |
|
283 |
no modifications are made to the queue (e.g. more acquires or timeouts), |
|
284 |
the lock would be acquired by the threads in this order (concurrent |
|
285 |
acquires in parentheses): ``threadE1``, ``threadE2``, (``threadS1``, |
|
286 |
``threadS2``, ``threadS3``), (``threadS4``, ``threadS5``), ``threadE3``, |
|
287 |
``threadS6``, ``threadE4``, ``threadE5``. |
|
288 |
|
|
289 |
:: |
|
290 |
|
|
291 |
[ |
|
292 |
(0, [exc/threadE1, exc/threadE2, shr/threadS1/threadS2/threadS3]), |
|
293 |
(2, [shr/threadS4/threadS5]), |
|
294 |
(10, [exc/threadE3]), |
|
295 |
(33, [shr/threadS6, exc/threadE4, exc/threadE5]), |
|
296 |
] |
|
297 |
|
|
298 |
|
|
246 | 299 |
IPv6 support |
247 | 300 |
------------ |
248 | 301 |
|
Also available in: Unified diff