This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [actions/setup-python](https://github.com/actions/setup-python) | action | major | `v6` → `v7` | --- ### Release Notes <details> <summary>actions/setup-python (actions/setup-python)</summary> ### [`v7.0.0`](https://github.com/actions/setup-python/releases/tag/v7.0.0) [Compare Source](https://github.com/actions/setup-python/compare/v7.0.0...v7.0.0) #### What's Changed ##### Enhancements - Migrate to ESM and upgrade dependencies by [@​priyagupta108](https://github.com/priyagupta108) in [#​1330](https://github.com/actions/setup-python/pull/1330) - Pin SHA commits and update docs with latest versions by [@​HarithaVattikuti](https://github.com/HarithaVattikuti) in [#​1338](https://github.com/actions/setup-python/pull/1338) - Remove the pip-install input by [@​gowridurgad](https://github.com/gowridurgad) in [#​1336](https://github.com/actions/setup-python/pull/1336) ##### Bug Fix - Fix to Classify stderr warning messages as warnings instead of errors in annotations by [@​lmvysakh](https://github.com/lmvysakh) in [#​1335](https://github.com/actions/setup-python/pull/1335) - Validate and retry manifest fetch to prevent silent failures by [@​priyagupta108](https://github.com/priyagupta108) in [#​1332](https://github.com/actions/setup-python/pull/1332) ##### Dependency Upgrade - Bump certifi from 2020.6.20 to 2024.7.4 in /**tests**/data by [@​dependabot](https://github.com/dependabot) in [#​1328](https://github.com/actions/setup-python/pull/1328) - Remove EOL Python versions and Bumps numpy text fixture by [@​priya-kinthali](https://github.com/priya-kinthali) in [#​1333](https://github.com/actions/setup-python/pull/1333) - Upgrade [@​actions/cache](https://github.com/actions/cache) to 6.2.0 by [@​philip-gai](https://github.com/philip-gai) in [#​1337](https://github.com/actions/setup-python/pull/1337) #### New Contributors - [@​lmvysakh](https://github.com/lmvysakh) made their first contribution in [#​1335](https://github.com/actions/setup-python/pull/1335) - [@​philip-gai](https://github.com/philip-gai) made their first contribution in [#​1337](https://github.com/actions/setup-python/pull/1337) **Full Changelog**: <https://github.com/actions/setup-python/compare/v6...v7.0.0> ### [`v7`](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0) [Compare Source](https://github.com/actions/setup-python/compare/v6.3.0...v7.0.0) </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNTcuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI1Ny4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->Reviewed-on: #10 Co-authored-by: Renovate Bot <renovate@unbound.se>
subscriptions
Shared core for Shiny's cross-service read-your-writes GraphQL subscriptions (ADR-0009 tier-3, ADR-0012).
An entity shown in the UI is frequently projected from another service's
event, so the owning service exposes a GraphQL subscription, drives it from a
per-replica transient AMQP consumer, and pushes a lightweight poke once the
change is visible in its own read view — the client then refetches the
authoritative query. This package is the reusable, type-generic, hardened core
of that pattern, extracted from the hand-rolled copies in authz-service
(availableCompanies) and accounting-service (entryBasesChanged).
import "gitea.unbound.se/shiny/subscriptions"
// One registry per subscription, parameterised by the GraphQL payload type.
reg := subscriptions.New[model.EntryBasisChange](subscriptions.WithLogger(logger))
// Resolver: register a websocket consumer (key by company, user, …).
ch, cleanup, _ := reg.AddReceiver(companyID)
go func() { <-ctx.Done(); cleanup() }()
return ch, nil
// AMQP handler: gate the push on the read view, off the delivery goroutine.
reg.Submit(ev.CompanyID, func(ctx context.Context) (*model.EntryBasisChange, bool) {
basis, err := readView.FindEntryBasisById(ctx, id)
if err != nil {
return nil, false // transient read error — keep waiting
}
return &model.EntryBasisChange{ID: id, Removed: removed}, removed == (basis == nil)
})
What the registry owns (so services don't re-roll it): the keyed subscriber map,
non-blocking buffered fan-out (sends under the read lock so a close can't race a
send), a bounded worker pool that runs the read-view gate off the AMQP
delivery goroutine, and the retry/timeout budget. What stays in the service: the
event→(key, payload) mapping and the Producer read-view closure.
The poke is idempotent and drop-tolerant — the client refetches on any poke — so
the worker acks immediately and a dropped/duplicated poke self-heals. Wire an
Observer to surface dropped/skipped pushes as metrics.