You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Лёгкий пакет для управления пулом задач (**envelopes**) поверх `k8s.io/client-go/util/workqueue` с ограничением параллелизма, ретраями, периодическим планированием, **stamps (middleware)** и хуками до/после выполнения.
3
+
Лёгкий пакет для управления пулом задач (**envelopes**) поверх `k8s.io/client-go/util/workqueue` с ограничением
4
+
параллелизма, ретраями, периодическим планированием, **stamps (middleware)** и хуками до/после выполнения.
4
5
5
-
> Основано на `workqueue` из client-go: очередь дедуплицирует одинаковые элементы (один и тот же **указатель**) и поддерживает rate-limiting / отложенное перепланирование.
6
+
> Основано на `workqueue` из client-go: очередь дедуплицирует одинаковые элементы (один и тот же **указатель**) и
7
+
> поддерживает rate-limiting / отложенное перепланирование.
6
8
7
9
---
8
10
9
11
## Что нового в API
10
12
11
13
-**Builder-подход для Envelope** — поля неэкспортируемые, настройка через `NewEnvelope(opts...)` и `With*`-опции:
12
14
```go
13
-
e:=pkg.NewEnvelope(
14
-
pkg.WithId(1),
15
-
pkg.WithType("email"),
16
-
pkg.WithInterval(5*time.Second),
17
-
pkg.WithDeadline(3*time.Second),
18
-
pkg.WithBeforeHook(func(ctx context.Context, e *pkg.Envelope) error { returnnil }),
|`invoke` вернул `nil`|`Forget`; если `interval > 0` → `AddAfter(interval)`|
140
+
| Контекст задачи истёк/отменён (`DeadlineExceeded`/`Canceled`) |`Forget`; если периодическая → `AddAfter(interval)`|
141
+
|`ErrStopEnvelope` (из `beforeHook`/`invoke`/`afterHook`) |`Forget` + поместить `_type` в **blacklist**|
142
+
| Ошибка в `beforeHook` (не `ErrStopEnvelope`) | Периодические: `AddRateLimited`; одноразовые: `Forget`|
143
+
| Ошибка в `invoke` (не `ErrStopEnvelope`) | Периодические: `AddRateLimited`; одноразовые: `Forget`|
144
+
| Ошибка в `afterHook` (не `ErrStopEnvelope`) | Возвращается наверх → те же правила, что и для обычной ошибки |
145
+
| Паника внутри обработки элемента | Элемент `Forget+Done`, стек логируется; воркер продолжает работу |
141
146
142
-
> Валидация: для периодических задач `deadline`**не должен превышать**`interval` — иначе `ErrAdditionEnvelopeToQueueBadIntervals`.
147
+
> Валидация: для периодических задач `deadline`**не должен превышать**`interval` — иначе
148
+
`ErrAdditionEnvelopeToQueueBadIntervals`.
143
149
144
150
---
145
151
@@ -150,11 +156,13 @@ Stamps — это обёртки вокруг `Invoker` (обработчика
150
156
-**Глобальные stamps** — задаются на очередь через `WithStamps(...)`.
151
157
-**Per-envelope stamps** — через `WithStampsPerEnvelope(...)` в `NewEnvelope(...)`.
152
158
153
-
Порядок: глобальные идут **первее** и становятся **внешними** (самыми «оборачивающими»), затем per-envelope — **внутренние**.
159
+
Порядок: глобальные идут **первее** и становятся **внешними** (самыми «оборачивающими»), затем per-envelope — *
160
+
*внутренние**.
154
161
155
162
### Встроенные stamps
156
163
157
-
-`BeforeAfterStamp(withTimeout)` — исполняет `beforeHook` и `afterHook` с отдельными тайм-бюджетами; любые ошибки, кроме `ErrStopEnvelope`, **возвращаются** наверх. Рекомендуемая функция тайм-бюджета:
164
+
-`BeforeAfterStamp(withTimeout)` — исполняет `beforeHook` и `afterHook` с отдельными тайм-бюджетами; любые ошибки,
165
+
кроме `ErrStopEnvelope`, **возвращаются** наверх. Рекомендуемая функция тайм-бюджета:
158
166
`WithHookTimeout(ctx, base=deadline, frac=0.5, min=800ms)` → `max(50% от deadline, 800ms)`.
159
167
-`LoggingStamp(l *log.Logger)` — логирует длительность и ошибку обработки конверта.
160
168
@@ -165,55 +173,58 @@ Stamps — это обёртки вокруг `Invoker` (обработчика
165
173
### Конструктор и геттеры
166
174
167
175
```go
168
-
e:=pkg.NewEnvelope(opts...)
176
+
e:=NewEnvelope(opts...)
169
177
170
-
id:= e.GetId()
178
+
id:= e.GetId()
171
179
name:= e.GetType()
172
-
st:= e.GetStamps()
180
+
st:= e.GetStamps()
173
181
```
174
182
175
183
### Опции `Envelope`
176
184
177
185
```go
178
-
pkg.WithId(id uint64)
179
-
pkg.WithType(t string)
180
-
pkg.WithInterval(d time.Duration)// 0 = одноразовая задача
181
-
pkg.WithDeadline(d time.Duration)// 0 = без таймаута
182
-
pkg.WithBeforeHook(func(ctx context.Context, e *Envelope) error)
183
-
pkg.WithInvoke(func(ctx context.Context) error)
184
-
pkg.WithAfterHook(func(ctx context.Context, e *Envelope) error)
185
-
pkg.WithStampsPerEnvelope(stamps ...Stamp)
186
+
WithId(id uint64)
187
+
WithType(t string)
188
+
WithInterval(d time.Duration) // 0 = одноразовая задача
189
+
WithDeadline(d time.Duration) // 0 = без таймаута
190
+
WithBeforeHook(func(ctx context.Context, e *Envelope) error)
191
+
WithInvoke(func(ctx context.Context) error)
192
+
WithAfterHook(func(ctx context.Context, e *Envelope) error)
193
+
WithStampsPerEnvelope(stamps ...Stamp)
186
194
```
187
195
188
196
### Опции очереди
189
197
190
198
```go
191
-
pkg.WithLimitOption(n)// число воркеров (>0)
192
-
pkg.WithWaitingOption(true|false) // ждать ли завершения воркеров в Stop()
193
-
pkg.WithStopModeOption(pkg.Drain|pkg.Stop)
194
-
pkg.WithLimiterOption(customLimiter)// если не задан — дефолтный
pkg.ErrStopEnvelope// поместить `_type` в blacklist
203
-
pkg.ErrEnvelopeInBlacklist// попытка добавить тип из blacklist
204
-
pkg.ErrEnvelopeQueueIsNotRunning// Add до Start/после Stop
205
-
pkg.ErrAdditionEnvelopeToQueueBadFields// пустой тип / nil invoke / отрицательные интервалы
206
-
pkg.ErrAdditionEnvelopeToQueueBadIntervals// deadline > interval для периодических
210
+
ErrStopEnvelope // поместить `_type` в blacklist
211
+
ErrEnvelopeInBlacklist // попытка добавить тип из blacklist
212
+
ErrEnvelopeQueueIsNotRunning // Add до Start/после Stop
213
+
ErrAdditionEnvelopeToQueueBadFields // пустой тип / nil invoke / отрицательные интервалы
214
+
ErrAdditionEnvelopeToQueueBadIntervals // deadline > interval для периодических
207
215
```
208
216
209
217
---
210
218
211
219
## Эксплуатационные заметки
212
220
213
-
-**Один объект — один запуск**: текущая реализация рассчитана на одноразовый жизненный цикл `Start/Stop`. Для повторного использования создайте **новый объект** очереди.
214
-
-**Дедупликация**: для указателей — по адресу. Не «переиспользуйте» один и тот же указатель для разных логических задач.
221
+
-**Один объект — один запуск**: текущая реализация рассчитана на одноразовый жизненный цикл `Start/Stop`. Для
222
+
повторного использования создайте **новый объект** очереди.
223
+
-**Дедупликация**: для указателей — по адресу. Не «переиспользуйте» один и тот же указатель для разных логических
224
+
задач.
215
225
-**Jitter**: чтобы периодические задачи не «стреляли строем», можно добавить случайный сдвиг к `AddAfter`.
216
-
-**Соблюдайте контекст** в `invoke`/хуках: долгие операции должны уважать `ctx.Done()`; иначе получится «карусель» таймаутов с перепланированием.
226
+
-**Соблюдайте контекст** в `invoke`/хуках: долгие операции должны уважать `ctx.Done()`; иначе получится «карусель»
0 commit comments