Cover how the SSE pipeline is wired (HistoryAuditMonitor +
galaxy-sse-monitor + control-task fan-out + per-worker connection
manager), how to configure it, what statsd metrics to watch, and
how to set up nginx so /api/events/stream is not buffered.
Wire the new page into the admin toctree and add cross-references
from the nginx and scaling guides where SSE has operational impact.
Replace enable_sse_history_updates and enable_sse_entry_point_updates
with a single enable_sse_updates. The two flags shared the same SSE
connection plumbing (events/stream + dispatcher), and only the
HistoryAuditMonitor lifecycle has real per-process cost — entry-point
dispatch is event-driven and effectively free. One knob admins can flip.
Updates schema, sample config, server (app, configuration manager,
history_audit_monitor, sse_monitor), client stores and their tests,
integration tests, and the regenerated admin docs.
Three related additions to the SSE notification pipeline, bundled here
because they share ``SSEEventDispatcher._send`` as their modification
point:
1. Interactive-tool entry-point SSE channel
- ``entry_point_update`` dispatcher method + queue-worker handler.
- ``InteractiveToolManager.configure_entry_points`` dispatches a
wake-up event after the DB commit; the client refetches
``/api/entry_points`` on receipt (no payload).
- Frontend: new SSE event type, store subscription with XOR polling
fallback via ``enable_sse_entry_point_updates`` config flag.
- Integration + selenium tests.
2. Queue and SSE observability metrics
- Counters, timers, and periodic gauges for SSE dispatch, control-queue
task execution, control-queue depth (via kombu passive declare),
active SSE connections, dropped events, and active WorkerProcess
rows. Flow through the existing ``galaxy_statsd_client`` — no new
infra. Gauges are scheduled via Celery beat at ``queue_metrics_interval``
seconds (default 15). All instrumentation no-ops when statsd isn't
configured.
- Sub-emitter failures log once at WARNING and bump a
``galaxy.queue_metrics.error`` counter tagged by emitter so broken
emitters are visible in metrics without log spam.
3. Active-worker control-queue cache
- 30 s TTL cache on ``all_control_queues_for_declare`` with RLock
stampede protection. At 1000+ events/s this eliminates ~30 DB
round-trips/s per webapp for data that only changes on 60 s
heartbeat cadence. Empty results are not cached — would otherwise
silently drop every SSE event during the startup window.
Add real-time notification delivery via SSE to replace the 30-second
polling interval. The SSE endpoint streams notification_update,
broadcast_update, and notification_status events to connected clients.
Backend:
- New SSEConnectionManager (lib/galaxy/managers/sse.py) maps user IDs
to asyncio queues with thread-safe push via call_soon_threadsafe
- SSE streaming endpoint at GET /api/notifications/stream with
Last-Event-ID catch-up support and 30s keepalive
- Kombu control tasks (notify_users, notify_broadcast) fan out events
across all Galaxy worker processes
- Existing polling API unchanged for backward compatibility
Frontend:
- New useNotificationSSE composable using EventSource with auto-reconnect
- notificationsStore tries SSE first, falls back to polling after 5+
consecutive errors
Tests:
- API integration tests for SSE event delivery, broadcasts, and reconnect
- Selenium E2E tests for notification appearance and bell indicator
Add SSE-based real-time history update notifications
Replace aggressive 3-second history polling with Server-Sent Events
driven by database change detection, configurable via admin setting.
Backend:
- Add pg_notify() to PostgreSQL audit triggers for instant LISTEN/NOTIFY
- New HistoryAuditMonitor: PG LISTEN/NOTIFY with SQLite polling fallback
- New /api/events/stream SSE endpoint (uses StructuredApp, not MinimalManagerApp)
- Kombu control task "history_update" with message TTL (expiration=10s)
- Config: enable_sse_history_updates, history_audit_monitor_poll_interval
Frontend:
- Generalize useNotificationSSE → useSSE composable with event type filtering
- historyStore connects SSE for history_update events, triggers immediate refresh
- notificationsStore updated to use /api/events/stream and useSSE
- Polling kept as fallback at existing intervals
Tests:
- 5 integration tests: endpoint, dataset upload event, history ID in payload,
cross-user isolation, polling backward compatibility
Documents the 7-column `huggingface` data table schema, column
conventions, controlled vocabularies for pipeline_tag/domain, XML
filter patterns, and an example .loc entry.
Announced in galaxyproject/galaxy-hub#3923.
Introduce lib/galaxy/tool_util_models/yaml_parameters.py with a narrow
YamlGalaxyToolParameter union (extra=forbid) used for UserToolSource.inputs
and ToolSourceBase.inputs. v1 supports boolean, integer, float, text, select,
color, data, data_collection, conditional, repeat, section. XML-only fields
(truevalue, falsevalue, argument, is_dynamic, hidden, parameter_type) and
unsupported types (hidden, drill_down, data_column, genomebuild, group_tag,
baseurl, rules, directory) now reject at parse time.
to_internal() maps each YAML model onto the existing internal parameter
metamodel so no downstream pipeline needs to change shape. Production path
keeps re-parsing via YamlToolSource (plan option a).
UserToolSource envelope also gets extra=forbid - stray top-level keys like
argument: at the tool level fail fast. Regenerated ToolSourceSchema.json is
32KB (was 77KB); Monaco no longer autocompletes the leaked fields.
runtimeify() gains yaml_origin flag; evaluation.py passes it based on
tool_source.parse_class(). assert_yaml_v1_parameters() hard-fails on any
out-of-v1 type inside a YAML-origin bundle, recursing through whens/repeat/
section. XML path untouched.
doc/source/admin/user_defined_tools.md documents the supported set and
rejected types. 34 new tests in test_yaml_parameters.py cover red cases,
green round-trips, structural groups, the runtimeify guard, and a snapshot
blacklist on the published schema. test_parsing.py still green (83 tests).
No compat shim for existing beta DB rows that contain XML-only fields -
those will now fail validation on load and need to be recreated.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
only directories in `lib/galaxy` & `packages/*/galaxy`
All other files removed or moved to their own module
All references to those files updated, especially galaxy/version.py
The `tag_autocomplete_data`, `add_tag_async`, and `remove_tag_async`
endpoints served a long-removed jQuery/YUI autocomplete widget and have
zero non-self references in the codebase. Modern tagging uses
`PUT /api/tags` (`FastAPITags.update`).
Add a celery beat for renewal of Hashicorp Vault tokens.
This eliminates the need for manual token rotation when
using short-lived renewable tokens.
The approach:
- HashicorpVault checks token renewable status on startup (warning
if not renewable)
- New `renew_vault_token` Celery Beat task calls renew-self
- Configured via `vault_token_renewal_interval` in galaxy.yml
(default 0 = disabled)
- Requires Celery Beat to be running
Fixes https://github.com/galaxyproject/galaxy/issues/22187