Все проверки выполнены успешно
CI / test (push) Successful in 2m32s
Docker / Build and publish worker image (push) Successful in 18m17s
- reconnect safely after token rotation and retry leased results - reject malformed tasks and remove production cluster debug mutation - validate environment files and require immutable container images BREAKING CHANGE: Docker install, deploy, and Compose now require an immutable repository@sha256 image reference.
136 строки
6.3 KiB
Markdown
136 строки
6.3 KiB
Markdown
# Normal Tasks And Notifications
|
|
|
|
## Normal Check Execution
|
|
|
|
Normal work is centrally scheduled. The control plane owns PostgreSQL task
|
|
rows, selection, leases, retries, deadlines, and dead-letter state. The worker
|
|
owns only one execution attempt and its terminal report.
|
|
|
|
The implemented path is:
|
|
|
|
1. `internal/distworker/client.go` opens the authenticated WebSocket.
|
|
2. `internal/distworker/runner.go` selects a recognized populated task branch.
|
|
3. A bounded worker pool executes the task under its deadline.
|
|
4. `internal/checkexec/exec.go` dispatches to a database-free check package.
|
|
5. The runner queues one result and the result writer returns it to the control
|
|
plane with the exact lease token.
|
|
|
|
Implemented check kinds are HTTP, SSL, SSH, FTP, DNS, WHOIS, BSSL, LLM,
|
|
LLM-HTTP, ping, TCP, and UDP. Control-plane selection uses capabilities. The
|
|
runner and local executor share one supported-kind registry. Websocket task
|
|
envelopes require exactly one payload branch, matching non-empty outer/inner
|
|
job IDs, and a lease token. Unsupported checks return one terminal failed
|
|
result without execution. A safely attributable malformed single branch
|
|
returns a protocol failure; ambiguous and mismatched envelopes fail closed.
|
|
|
|
## Queue And Shutdown Rules
|
|
|
|
- Input and output queues are bounded. Backpressure must not create unbounded
|
|
goroutines or memory use.
|
|
- Concurrency is supplied by the control plane but clamped by the local
|
|
maximum.
|
|
- A task panic is recovered at the task boundary and reported as a failed
|
|
attempt; it must not kill the runner.
|
|
- SIGTERM stops accepting new tasks and waits for active dispatchers before the
|
|
execution pool closes. A bounded final-result drain across websocket shutdown
|
|
is not implemented yet.
|
|
- WebSocket reconnect does not re-run an in-flight or completed task.
|
|
- HTTP polling remains compatibility-only and must not become a second normal
|
|
scheduler.
|
|
|
|
## Delegated Notifications
|
|
|
|
`internal/distworker/notification.go` executes one pre-rendered delivery
|
|
attempt. It does not render alert policy and does not own retry scheduling.
|
|
|
|
| Method | State | Credential source |
|
|
| --- | --- | --- |
|
|
| Email | Implemented | scoped SMTP list from init/config |
|
|
| Telegram | Implemented | scoped bot list from init/config |
|
|
| Webhook | Implemented | current shared signing configuration |
|
|
| Mattermost | Implemented | current shared defaults/task endpoint |
|
|
| SMS | Explicitly unsupported | no provider selected |
|
|
| Voice | Explicitly unsupported | no provider selected |
|
|
|
|
SMS and voice return `permanent` with `unsupported_method`; they must never be
|
|
reported as delivered or silently dropped.
|
|
|
|
Worker result statuses are `delivered`, `retryable`, `permanent`, and
|
|
`partial`. Transport failures, provider rate limits, and provider 5xx responses
|
|
are retryable. Invalid recipients, authentication failures, malformed payloads,
|
|
and unsupported methods are permanent. Positive provider retry-after values
|
|
are included in the result; the control plane owns the actual retry time.
|
|
|
|
## Credentials
|
|
|
|
Credentials arrive in `WorkerInit.Credentials` and remain in memory. SMTP and
|
|
Telegram tasks may request a credential ID; the worker resolves only that ID
|
|
from the authorized pushed set. Missing IDs are permanent failures. Do not
|
|
fall back to another account's or platform credential.
|
|
|
|
The following fields must be redacted from logs and UI buffers: password,
|
|
token, API key, signing secret, hook URL, authorization headers, and fields
|
|
ending in `_secret`. Provider response text is bounded and must not include
|
|
response bodies that could contain secrets.
|
|
|
|
Webhook and Mattermost need persisted per-account credentials in the control
|
|
plane before they can claim the same isolation guarantees as SMTP and
|
|
Telegram. The worker wire shape already separates method configuration; do not
|
|
introduce environment-global fallback for private workers.
|
|
|
|
## Selfcheck Notifications
|
|
|
|
System selfcheck alerts are not normal notification tasks. They allow a worker
|
|
to notify configured system contacts when the control plane itself is
|
|
unreachable. They use system contacts and credentials from config, local
|
|
jitter, and local deduplication. They must not impersonate customer delivery or
|
|
mutate control-plane message state.
|
|
|
|
The local notifications page records both selfcheck and delegated delivery
|
|
attempts. Delegated rows contain job ID, method, status, duration, and time
|
|
only. Recipient, body, credentials, hook URL, authorization, provider response,
|
|
and error text are never copied into the bounded ring. Invalid deadlines and
|
|
recovered executor panics produce static permanent results and one redacted
|
|
local row.
|
|
|
|
## Implementation Work Packages
|
|
|
|
### N1: Runner Integration Coverage (partial)
|
|
|
|
Strict envelope/inner job-ID/lease validation and structured unsupported-kind
|
|
results are implemented with runner-boundary tests. Live WebSocket reconnect
|
|
and result-resend tests are implemented. Stale-lease acknowledgement and
|
|
bounded graceful final-drain tests remain.
|
|
|
|
### N2: Complete Local Delivery Audit (implemented)
|
|
|
|
Delegated notification outcomes are recorded in the bounded local notification
|
|
ring. `/notifications` renders selfcheck and delegated attempts without storing
|
|
recipient values, rendered body, credentials, provider responses, or errors.
|
|
|
|
### N3: Per-Account Webhook And Mattermost Credentials
|
|
|
|
Once the control plane sends credential IDs and account-scoped records, require
|
|
an exact credential match just like SMTP and Telegram. Remove global fallback
|
|
for private workers. Add cross-account negative tests.
|
|
|
|
### N4: SMS And Voice Providers
|
|
|
|
Select a provider and define a credential wire type before adding an executor.
|
|
Implementation must include timeout, retry classification, provider response
|
|
redaction, idempotency support, and contract tests. Until all are present,
|
|
retain the explicit permanent unsupported result.
|
|
|
|
## Acceptance Tests
|
|
|
|
- Every supported check kind can execute from a serialized task without a
|
|
database connection.
|
|
- A stale or missing lease token cannot produce an accepted normal result.
|
|
- One task causes at most one local execution during reconnect and duplicate
|
|
frame delivery.
|
|
- Private workers cannot resolve a credential outside their authorized set.
|
|
- SMTP 4xx/rate-limit conditions are retryable; invalid authentication is
|
|
permanent.
|
|
- SMS and voice remain explicit failures until provider tests exist.
|
|
- Logs and local UI contain no pushed credential values.
|