All versions since 2.0.1
2.0.1
API version: 10.0.0
Fixed
- Optional input data slots (
minSlots=0) can be filled. An empty optional slot counted as configured from the start, so it never offeredSelectWorkData,SelectWorkDataCollectionorSetFolderSource, and clients failed with “action is not available”. The slot now offers these actions while it is empty or short of its minimum, and only while the job can still be edited.
2.1.0
API version: 10.0.0
Changed
- Job updates from workers are consumed from the new single-active-consumer queue
Job.All.Updates.SingleActive, one message at a time, so the updates of a job are applied in the order the worker sent them however many instances run. With competing consumers onJob.All.Updates, two instances could apply a job’s “finished” before its error (the failed job ended up completed) or before its result. When a listener stops it finishes the message in processing before a standby takes over. Workers are unaffected: routing keys and message contracts are unchanged. Delivery stays at least once: after a redelivery or a failover an output’s metadata comment can appear twice; its name and tags are unaffected. With more than one instance, an output that receives more than one metadata update can be left with the older one after a failover; a step that writes each output once sends one (README, “Job update messages”; issue #182). - Operator-facing: at startup JMA unbinds
Job.All.Updatesand drains what is left in it before consuming the new queue. The drain acknowledges what it applied only once the queue is empty: an interrupted drain fails the startup and leaves everything it had applied inJob.All.Updates, and the restarted pod applies it again, in order. An update published in the instant of the switch reaches both queues; its copy is skipped by message id, and never applied after a newer update of its job (an update applied a second time appends its output metadata comment again, like any redelivery). Roll this release out with a single instance, scale out afterwards. OnceJob.All.Updatesis empty it can be deleted together with thejob-all-updates-dead-letterbroker policy. Rolling back to an earlier release needs a controlled hand-back of the queue (README, “Rolling back to a release without the single-active queue”): deletingJob.All.Updates.SingleActivewithout it loses the updates only it holds.
Fixed
- A job update that is valid JSON but no usable message (
null, or without header or content) is dead-lettered instead of staying unacknowledged. The same holds for any message whose handler fails unexpectedly, in every listener; with the job-update listener taking one message at a time, such a message would otherwise have stopped all job updates. - A job update whose command found the job store temporarily unavailable (a database timeout, lost connection or failover) was dead-lettered at once, and the job’s later updates were applied without it: a failed job’s “finished” without its error left the job completed. It is now retried in place for about three and a half minutes, which holds the job updates behind it until the store is back; only a longer outage dead-letters it.
- Saving a job that has tags could fail as “resource already exists” when another save of the same job had just committed (every save replaces the job’s tag rows, and the stale save collided with the new ones before its version check). The job-update listener took that for an update already applied and dropped it, and API requests failed. It is now retried like any other concurrent modification.
- With several instances, an instance whose broker connection recovered re-created the command queues of jobs another instance had already finished (the RabbitMQ client’s automatic recovery re-declares every queue a connection declared and did not delete itself). Job command queues are left out of that recovery; they are durable, so those of running jobs survive a reconnect anyway.
2.1.1
API version: 10.0.0
Fixed
- Saving a job that has outputs could fail as “resource already exists” when another save of the same job had just committed, like the tag conflict fixed in 2.1.0: every save also replaces the job’s output usage rows, and the stale save collided with the new ones before its version check. When a worker set a job’s tags while the job-update listener saved the job’s start, either the worker’s request failed with 423 (
execute_workflowfailed, issue #184) or the listener dropped the start, leaving a completed job without its start time and worker. It is now retried like any other concurrent modification. Present since 2.0.0.
2.2.0
API version: 10.1.0
Added
UploadWorkDatacan file the new WorkData into a folder, tag it and mark it secret, all in the commit that creates it (issue #179). Before, each took a follow-up call (MoveToFolder,SetTags,MarkAsSecret), and a client failing between them left the WorkData in the root, untagged or not secret. The properties go in an optional form fieldUploadWorkDataParametersholding{"Folder": <folder URL>, "Tags": [...], "Secret": true}(every member optional), before or after the file. Sent before the file, an unknown or foreign folder or an invalid tag fails the upload before any content is stored; sent after it, the stored content is removed again. The upload still streams the file without buffering it. The SIRENUploadaction of the WorkData root lists the new field (classFileUploadActionWithParameter) and keeps the classFileUploadAction, so existing clients continue to work. Without the field an upload behaves as before.
Fixed
- Setting a WorkData’s tags with a null tag (
{"Tags":[null]}) failed with HTTP 500 instead of a validation error (400).
2.2.1
API version: 10.1.0
Fixed
- The Gitea release has the generated
openapi.jsonattached again. Every release since the switch to semantic versioning shipped without it.
2.3.0
API version: 10.1.1
Changed
- An output slot without a target folder now files its produced WorkData into the Job’s folder instead of the Owner’s root. The folder is the one the Job is in when it is scheduled; a Job at the root still writes its outputs to the root. Once a Job is scheduled, moving it does not move its outputs; a retry after a failed scheduling attempt files the already prepared outputs into the Job’s current folder. An explicit target set with
SetOutputFolderstill takes precedence. This includes sub-jobs created withInheritParentFolder: they sit in the parent’s folder, so their untargeted outputs now land there too. SetOutputFolderwith/now pins the output slot to the Owner’s root, so an output of a Job in a folder can still go to the root. Previously/cleared the target like an empty path; an empty path still clears it, and the slot then follows the Job’s folder. A/sent before this change was stored as no target, so such a slot of a not yet scheduled Job now follows the Job’s folder as well.
Fixed
DeleteJobchecks that the caller may access the Job (issue #197). Any user with a plan grant could delete another Owner’s Job by its id, across tenants, as long as the Job was not running and had no output WorkData. Now only the Job’s Owner or an admin can delete it; anyone else gets 403. The check runs before the sub-job check, so a caller without access no longer sees the ids of the Job’s sub-jobs in the error. Present since job deletion was added in 2024.- Creating a sub-job checks that the caller may access the parent Job (issue #198), through
CreateSubJoband throughRapidJobSetupwith aParentJobUrl. Any user with a plan grant could attach a sub-job to another Owner’s pending or processing Job; that Owner could then no longer delete their Job, and withInheritParentFolderthe sub-job carried their folder. Now only the parent’s Owner or an admin can create a sub-job under it; anyone else gets 403. Workers are unaffected: they act as the identity that scheduled the parent, which already passes the same check when reading the Job.
2.4.0 Latest
API version: 10.2.0
Added
- Action templates and cron triggers can be filed in folders, like Jobs, WorkData and ProcessingSteps. Both have a
MoveToFolderaction (omit the folder to move back to the root), aFolderPathproperty and aParentFolderlink.CreateActionTemplateandCreateCronTriggertake an optionalFolderto create the item directly in a folder. Filing only organizes the item: a template’s own folder does not decide where its jobs go, and a trigger’s schedule and linked templates are unchanged. A trigger and the templates it runs are filed independently. - Action templates have a job folder:
SetJobFoldersets the folder that jobs created from the template (by a trigger orExecuteNow) are filed into, shown asJobFolder. It is a path, like an output slot target: the folder, and any missing folders above it, are created when a job is created, under the job’s owner, and renaming or moving the folder does not update the setting. Their outputs then follow the job’s folder. An empty path or/clears it, and jobs are created at the root as before; unlike an output slot, an unset job folder does not fall back to the template’s own folder. - The template and trigger queries take the
Folder/FolderRecursivefilter of the other foldable queries. - Folder contents list templates and triggers next to Jobs, WorkData and ProcessingSteps, as
ActionTemplateandCronJobTriggerentities. Clients that only know the earlier types can skip them; the total count includes them. - The folder children
Containsfilter acceptsactiontemplateandactiontrigger.
Changed
DeleteFolderalso refuses a folder that holds templates or triggers.- The folder
Clearaction also deletes the templates and triggers in the folder and its descendant folders. It deletes triggers first, then templates, then Jobs, ProcessingSteps and WorkData. Deleting a template unlinks it from every trigger, including triggers outside the folder. The report lists them with the item typesActionTriggerandActionTemplate.