Skip to content

Scheduler prioritization

This page explains how the scheduler chooses which observation to run next on a given telescope. The mechanics here cut across every layer of the access model — telescope access grants, queues, queue access grants, and observing accounts — so it's worth reading Telescope access, Observing queues, and Access grants first if any of that vocabulary is new.

The short version: the scheduler walks a telescope's queues in priority order, and within each queue it orders eligible observations by the priority of their submitter's queue access grant. Higher queues come before lower; within a queue, higher-priority grants come before lower.


The three records that drive prioritization

TelescopeAccessGrant     ←─ entity ↔ telescope, total usage across ALL queues
        │
        │ has many
        ▼
ObservingQueueAccessGrant  ←─ entity ↔ one queue, priority within the queue,
        │                                          usage within the queue
        │ referenced by
        ▼
ObservingAccount          ←─ bundles queue access grants for submitters

TelescopeAccessGrant

Each telescope maintains an ordered set of telescope access grants — one per entity that's been admitted to observe with the telescope.

The grant carries the entity's total usage across all queues (time_used, plus the bookkeeping fields time_contested and time_waiting) and a shares value that's the input to ownership share-based prioritization.

Telescope access grants are not the same thing as the TelescopeAccessGrants that delegate read/update/delete on the telescope record — they share a name (and a model) but represent different intent. The one described here is the observing-time grant; an owner uses it to say "this entity is admitted to the telescope, with this many shares of its time."

ObservingQueueAccessGrant

Once an entity holds a telescope access grant, queue access grants hang off it — one per queue the entity is allowed to access.

A queue access grant carries:

  • The queue it applies to.
  • A back-reference to the parent telescope access grant (so the entity and the telescope are both implied).
  • order — the configured priority of this grant within the queue. Lower values are higher priority.
  • effective_order — the priority the scheduler actually uses, which is order for static queues and is recomputed by the scheduler for dynamic queues (see below).
  • time_used, time_contested, time_waiting — the entity's usage within this queue specifically, distinct from the parent telescope access grant's cross-queue totals.
  • An optional observing-policy override.

The split between "total usage on the telescope" (on the telescope access grant) and "usage in this queue" (on the queue access grant) is what lets a queue's prioritization mode talk about queue-local usage while ownership share-based prioritization can talk about telescope-wide usage.

ObservingAccount

Once an entity holds a queue access grant, they can include it in one or more observing accounts. An observing account is a bundle of:

  • One or more queue access grants (possibly across telescopes), and
  • A list of observing grants identifying which entities are allowed to add observations to those queues through this account (OwnerObservingGrant, MemberObservingGrant, GroupObservingGrant, DelegatedObservingGrant, etc. — see Observing accounts).

The account is what submitters interact with. They never pick a queue access grant directly; they pick an account, and the account exposes whichever queues its grants reach.


Queue prioritization modes

Each queue chooses exactly one prioritization mode, recorded as ObservingQueue.access_prioritization. The mode determines how the scheduler turns the queue's set of queue access grants into an ordered list:

Mode Behavior
Static (fixed) effective_order = the configured order on each queue access grant. Owner-set. Doesn't change as time is used.
Total-usage (ownership share-based) effective_order is recomputed each run so that entities under-using their telescope-wide share (TelescopeAccessGrant.shares vs. time_used) float to the top. Fair-share across the telescope.
Queue-usage Same shape as total-usage, but the usage comparison uses ObservingQueueAccessGrant.time_used instead. Fair-share within this queue.
Schedule (calendar) A calendar maps entity → time window. During an entity's window, that entity's grant floats to the top of the queue; outside it, the entity isn't considered.

The two usage-based modes both produce a dynamic ordering — the effective_order is the output of the prioritization model, not a field owners edit. The static mode is the only one where effective_order == order by construction.


How the scheduler orders observations

For a given telescope, at scheduler-run time:

  1. Walk the queues in queue order. ObservingQueue.order defines the priority order of queues on the telescope — lower values are higher priority. Queue enabled = false queues are skipped.
  2. Within each queue, order the queue access grants by effective_order. Lower is higher priority. The effective_order is what the queue's prioritization mode produced (static = configured, total-usage / queue-usage = share-based, schedule = calendar-driven).
  3. Within each grant, surface that grant's eligible observations. Eligibility filters out observations whose targets aren't observable now, whose policy constraints are failing, or whose funding account / grant has hit a quota. Observations from higher-priority grants come before those from lower-priority grants. Higher-priority queues come before lower-priority queues.
  4. Pick the next observation to dispatch. The scheduler then layers its slew / overhead model on top — among the highest-priority eligible observations, it prefers the one that's cheapest to start next — and dispatches one task.

ObservingQueue.can_interrupt controls whether a higher-priority queue is allowed to preempt an in-progress observation from a lower-priority queue, or whether it has to wait for the current observation to finish.

Each pass through the loop emits an ObservingScheduleEvent per queue, and the overall run is summarized by a SchedulerRun. Those are the records to read first when diagnosing "why didn't my observation run." See Observing queues → Schedule events and scheduler runs.


Where observing accounts fit

The prioritization above is about queue access grants, not observing accounts. The account layer matters for which submitter is allowed to put an observation on the queue, and for quota throttling on top of dispatch, but the scheduler's ordering within a queue is determined by the queue access grant's effective_order, not by anything on the account.

That has two practical consequences:

  • An observation's priority is fixed at the moment it's submitted through a particular account → queue access grant. Switching accounts (if the observer has access to more than one) changes which queue and grant the observation lands on, which can change its priority.
  • Quotas on the account or its grants don't reorder the queue; they pause dispatch when exceeded. A high-priority observation whose account has hit a quota stalls in place rather than being reordered behind anyone else. See Observing accounts → Quotas.

Open: prioritization within an observing account

A single observing account can hold queue access grants spanning multiple queues — and sometimes multiple telescopes — and a single queue access grant can be referenced by multiple accounts. We have not yet specified whether an entity is allowed to express a preference among the queue access grants inside one of its accounts, or among the accounts a given submitter can choose from.

For now, when an account exposes more than one eligible target for the same observation, the scheduler treats them as interchangeable — the choice between them falls out of the per-queue ordering rules above plus the slew/overhead model, not out of any account-side priority field. If you have a use case that needs explicit account-side prioritization, raise it; it's an open design question, not a settled feature.


Reference

ObservingQueue Schema

Properties

Name Type Description
id Integer No description
queue_type Enum(maintenance, too, general, calibration, custom) No description
telescope_id Integer No description
name String(256) No description
slug String(256) No description
description String(Unbounded) No description
can_interrupt Boolean Whether or not the queue can interrupt lower priority queues
access_prioritization Enum(default, total_usage, queue_usage, schedule) No description
order Integer The order used to prioritize queues for a given telescope. Lower values are higher priority.
enabled Boolean Whether or not the queue is enabled. Disabled queues will not be scheduled.

Relationships

Relationship Name Type
telescope Telescope
access_grants ObservingQueueAccessGrant

ObservingQueueAccessGrant Schema

Properties

Name Type Description
id Integer The unique identifier for the queue access grant.
queue_id Integer The ID of the queue to which the allocation belongs.
telescope_access_grant_id Integer The ID of the telescope access grant providing access to this queue.
order Integer The order used to prioritize this allocation within the queue. Lower values are higher priority.
revoked Boolean Whether this allocation has been revoked. If true, the allocation is no longer valid.
effective_order Integer The effective order used to prioritize thisa llocation within the queue, taking into account the queue's prioritization policy and the allocation's own priority.
time_used Float The total time used by the account regardless of whether it was contested or not.
time_contested Float The total time used by the account when sibling accounts also had observations which could have been scheduled.
time_waiting Float The total time that the other accounts used while this account was waiting for its observations to be scheduled.
observing_policy_id Integer (Optional) No description

Relationships

Relationship Name Type
queue ObservingQueue
telescope_access_grant TelescopeAccessGrant
observing_accounts ObservingAccount
observing_policy ObservingPolicy

TelescopeAccessGrant Schema

Properties

Name Type Description
id Integer No description
telescope_id Integer No description
entity_id Integer The entity (user or organization) granted access to the telescope.
shares Float The number of shares this access grant has. This is used to determine how much time the entity can use the telescope.
time_used Float No description
time_contested Float No description
time_waiting Float No description
revoked Boolean Whether this access grant has been revoked. If true, the access grant is no longer valid.

Relationships

Relationship Name Type
telescope Telescope
entity Entity
invitation TelescopeAccessGrantInvitation
queue_access_grants ObservingQueueAccessGrant

ObservingScheduleEvent Schema

Properties

Name Type Description
id Integer No description
owner_id Integer (Optional) No description
telescope_id Integer (Optional) No description
priority Integer No description
created_on DateTime No description
updated_on DateTime (Optional) No description
start_on DateTime (Optional) No description
end_on DateTime (Optional) No description
end_time_unspecified Boolean No description
all_day Boolean No description
recurrence String(100) (Optional) No description
recurring_event_id Integer (Optional) No description
is_too Boolean No description
is_exclusive Boolean No description
description String(100) No description

Relationships

Relationship Name Type
owner Organization
telescope Telescope
users User
groups Group
organizations Organization
observations Observation

SchedulerRun Schema

Properties

Name Type Description
id Integer No description
started_at DateTime No description
finished_at DateTime (Optional) No description

Relationships

Relationship Name Type
tasks ObservationTask