From 98df5d5e8cad79224eede36f97d602e7e5b03fcc Mon Sep 17 00:00:00 2001 From: Tony Zedginidze Date: Tue, 13 Oct 2026 11:58:44 +0200 Subject: [PATCH] docs: illustrate worker middleware and result storage flow --- docs/assets/worker-middleware-flow.png | Bin 0 -> 52377 bytes docs/assets/worker-middleware-flow.svg | 98 +++++++++++++++++++++++++ docs/extending-taskiq/middleware.md | 27 +++++++ 3 files changed, 125 insertions(+) create mode 100644 docs/assets/worker-middleware-flow.png create mode 100644 docs/assets/worker-middleware-flow.svg diff --git a/docs/assets/worker-middleware-flow.png b/docs/assets/worker-middleware-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..236933598749dbf391743b359d20d662bec2bfe1 GIT binary patch literal 52377 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

j6hb{c) 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 literal 0 HcmV?d00001 diff --git a/docs/assets/worker-middleware-flow.svg b/docs/assets/worker-middleware-flow.svg new file mode 100644 index 00000000..069da44f --- /dev/null +++ b/docs/assets/worker-middleware-flow.svg @@ -0,0 +1,98 @@ + +Embedded inter font subsets retain the following copyright and SIL OFL 1.1 license. The surrounding diagram retains its repository license. + +Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) Inter-Italic[opsz,wght].ttf: Copyright 2016 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Taskiq worker middleware and result storageWorker processing runs pre_execute, task execution, optional on_error and post_execute. Result storage precedes post_save, which runs only after successful storage. NoResultError skips storage.NoNoYesYesYesNopre_executeRun task and closedependenciesExecution error?on_errorpost_executeNoResultError?Save result in backendSave succeeded?post_saveSkip storageand post_saveHandle save error;no post_save \ No newline at end of file diff --git a/docs/extending-taskiq/middleware.md b/docs/extending-taskiq/middleware.md index 9e5ba1c4..add4b385 100644 --- a/docs/extending-taskiq/middleware.md +++ b/docs/extending-taskiq/middleware.md @@ -30,3 +30,30 @@ may use `self.broker` to do so. [Taskiq-pipelines](https://github.com/taskiq-python/taskiq-pipelines) uses middlewares to call next tasks. + +## Worker hook flow + +Worker hooks run after the message has been decoded and its task has been found. +The diagram shows one execution, assuming that the middleware hooks themselves +complete normally: + +![Worker middleware flow: pre_execute, task execution, optional on_error, post_execute, then result storage and post_save only if the result is saved successfully. NoResultError skips storage.](../assets/worker-middleware-flow.png) + +*Worker middleware flow. [Editable SVG](../assets/worker-middleware-flow.svg). +[Edit diagram](https://svgdiagram.ai/diagram-sources/taskiq-worker-middleware-flow?version=1).* + +1. `pre_execute` can modify the message before the task runs. +2. Task execution and dependency cleanup produce the result. If an execution + error was found, `on_error` runs before `post_execute`. +3. `post_execute` runs for both successful and failed task results. +4. A result containing `NoResultError` skips result storage and `post_save`. + Other results, including ordinary task errors, are passed to the result backend. +5. `post_save` runs only after the backend saves the result successfully. A save + error skips `post_save`; it is logged, and can also be propagated by the receiver. + +With multiple registered middlewares, `pre_execute` runs in registration order. +`on_error`, `post_execute`, and `post_save` run in reverse registration order. +These worker hooks are separate from the client-side `pre_send` and `post_send` +hooks. Exceptions raised by middleware hooks can interrupt this flow, so handle +them inside the middleware as described in the +[architecture overview](../guide/architecture-overview.md#middlewares).