#3387·quartznet

Remote dashboard: fronting schedulers in other processes, designed as one feature

Author: lahmaCreated Aug 24, 2026Updated Sep 12, 2026
Labelsfeature4.x

Quartz.Dashboard.Services.QuartzApiClient — the HTTP-backed IQuartzApiClient — is being removed for 4.0 (#3361): it was registered nowhere, ran nowhere, and drifted from the in-process client twice (Started vs Running, #3318; CronTrigger vs Cron, #3359). This issue is where a remote dashboard gets designed rather than rediscovered, so that if it comes back it comes back whole.

What "the dashboard fronts a scheduler in another process" needs

  1. A history source over the wire. The dashboard's execution history is an in-process store fed by DashboardHistoryPlugin; no Quartz HTTP API endpoint serves it, which is why the old client treated a 404 as "no history". Either the HTTP API grows a history endpoint (which means the scheduler's process keeps the history, with retention it owns), or the remote dashboard shows no history and says so.
  2. Credentials for the target. QuartzDashboardOptions.AuthorizationPolicy protects the UI; a remote call needs its own credential to the target's RequireAuthorization policy — token pass-through from the signed-in user, or a per-target client credential configured on the dashboard. The AddQuartzHttpClient registration already has the per-scheduler HttpClient shape to build on.
  3. One client, not two. IQuartzApiClient should be implemented once against the wire contract that Quartz now owns internally, with the in-process variant being the same code over an in-memory transport. Two hand-written implementations of one interface will drift again; nothing exercised the drift before and nothing would now.
  4. Several targets. A dashboard worth running remotely fronts more than one process. That needs a target list in options, a rule for scheduler names that collide across targets (prefix by target, or refuse), and a SchedulerRegistration.Origin value that says "remote target".
  5. Live events. DashboardLiveEventsPlugin broadcasts over the dashboard's own SignalR hub from inside the scheduler's process. A remote target has no such hub reachable by the dashboard; the API would need an event stream (SSE or a hub endpoint) or the live pages fall back to polling.

None of that is small, and none of it is 4.0. QuartzDashboardOptions.BaseUrl/ApiPath go with the client so the options type does not advertise a mode that does not exist.