diff --git a/docs/architecture.md b/docs/architecture.md index b8b574bb..79f90dfb 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -32,7 +32,7 @@ For each `[Job]` class (see `Templates/Job.sbntxt`), nested in the user's partia current persisted definition on each call, including its acquisition limits. - **`Invoker`**: a singleton `IJobInvoker` that deserializes the payload and runs the handler through the Immediate.Handlers pipeline. -- **`JobDefinition`**: the runtime description (name, queue, attempts, timeout, backoff, cron, +- **`JobDefinition`**: the shared execution, storage, and monitoring description (name, queue, attempts, timeout, backoff, cron, overlap and misfire policies, concurrency, acquisition windows, and normalized routing tags). - **`PayloadJsonContext`**: hand-emitted System.Text.Json metadata for the payload and context types, so serialization never uses reflection. @@ -59,7 +59,11 @@ configuration surface (`ConfigureStorage`, `ConfigureWorkers`, `UseFairQueues`, - **Startup.** Initializes storage and submits the complete definition catalogue and code-defined schedules through `MergeJobDefinitionsListAsync`, even when workers are disabled. `StartAsync` completes this registration before returning. The storage - reconciles only definitions intersecting the server's effective tags. Metadata has no invoker or CLR type. + reconciles only definitions intersecting the server's effective tags. `JobDefinition` serializes its + queue settings through the nested `Queue` object. SQL storage maps that object to the existing queue + columns, and Redis reads older flat metadata at its storage boundary. The local invoker, CLR type, + and computed acquisition limits are excluded from JSON; definitions read from durable storage + have no runtime bindings. Execution uses the locally registered definitions. - **Polling loop.** Each iteration materializes due recurring schedules, builds a `JobAcquisitionRequest` from tag-eligible local definitions, free worker capacity, and queue/job concurrency limits, calls `IJobStorage.AcquireDueJobsAsync`, and writes the claimed records to an unbounded channel. On diff --git a/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/DefinitionTable.vue b/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/DefinitionTable.vue index 2be7f1a5..b0729576 100644 --- a/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/DefinitionTable.vue +++ b/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/DefinitionTable.vue @@ -41,7 +41,7 @@ defineEmits<{ - + {{ definition.name }} @@ -61,7 +61,7 @@ defineEmits<{ - {{ definition.queueName }} + {{ definition.queue.name }} {{ tag }}
{{ definition.cron }}{{ definition.timeZone }}
diff --git a/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/JobDetail.vue b/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/JobDetail.vue index ac0fb179..d048c802 100644 --- a/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/JobDetail.vue +++ b/src/Immediate.Jobs.Dashboard/DashboardClient/src/components/JobDetail.vue @@ -10,7 +10,7 @@ import { canCancelJob, canRetryJob, type JobAcquisitionState, - type JobDefinitionRecord, + type JobDefinition, type JobExecutionRecord, type JobRecord, type JobTelemetryLink, @@ -19,7 +19,7 @@ import { formatAcquisitionStatus, formatDate, formatJobState, formatJson } from const props = withDefaults(defineProps<{ job: JobRecord; - definition?: JobDefinitionRecord | undefined; + definition?: JobDefinition | undefined; acquisition?: JobAcquisitionState | undefined; definitionLoading?: boolean; definitionError?: string | undefined; @@ -402,9 +402,9 @@ function retryButtonLabel(job: JobRecord, pending: boolean): string {

Definition