QueueResource in Activate
17 min
purpose queueresource is the activate resource type used to queue, retry, and throttle work that should not fail immediately when a downstream dependency is unavailable, busy, or rate limited in activate, a queueresource owns an activatebackgroundqueue the implementation creates or retrieves that queue by path using provisioningbackgroundthreads instance getorstart( ) , with the queue created as an activatebackgroundqueue for the resource’s backgroundprocess method a queue is typically used by integrations, service desk providers, and api backed workflows where activate needs to avoid overwhelming an external system retry transient failures suspend a workflow safely resume the job later through the job service keep visible queue depth using queue count where queueresource is configured where queueresource is configured a queueresource is configured as a resource node in activate the parent queue resource usually defines the shared defaults, while child queue resources represent individual integration queues parameter example value applies to purpose name queues parent queue resource the resource name shown in the activate resource tree a parent queue resource is often used as a container for individual child queues class innovation activate library\innovation activate queueresource parent queue resource defines the resource as a queueresource implementation queue retrysequence 1,1,1,1,1,5 parent or child queue resource defines the retry timing sequence used by the queue thread values are seconds once the sequence is exhausted, the final value is repeated queue submitdelay 1000 parent or child queue resource defines the delay, in milliseconds, between queued item submissions during queue processing transactionlimit 100/min parent or child queue resource defines the queue rate limit used by the queueresource limiter transactionspersecond 2 0 parent or child queue resource present in the supplied configuration in the current queueresource implementation, transactionlimit is the primary limiter setting, so confirm wider provider code before relying on this value for queue throttling queue count 0 child queue resource volatile operational state showing the current queue depth for a specific child queue this should be treated as runtime state rather than deployment configuration for example, a parent queue resource can define shared defaults such as retry sequence, submit delay, and transaction limit child queues can then inherit those defaults or override them when a specific integration needs different retry or throttling behaviour this structure lets activate keep shared queue defaults in one place while still giving each downstream integration its own visible backlog and queue specific tuning options core behaviour 1\ queue creation and startup queueresource getqueue() asks the background thread manager for a queue using the resource path as the key if no queue exists, it starts a new activatebackgroundqueue trygetqueue() checks whether the queue already exists without forcing a new background queue to start 2\ loading queued jobs when the queue is initialised, activate loads queued jobs using jobcollection loadqueuedjobs(this) each loaded job id is added to the background queue this is how queued jobs can be rehydrated after a restart 3\ queue count queuecount behaves differently depending on the activate context, for example the orchestrator when the orchestrator is running, queueresource reads the live queue count from the active background queue otherwise, it falls back to the queue count parameter the background queue updates queue count when items are added or removed because queue count is volatile state, it should be treated as operational data, not as functional configuration how shouldtry works shouldtry is the main guard used by scripts before they call an external system the implementation checks whether the current job session already contains the queue marker if it does, shouldtry returns true , because the job is already being replayed from the retry queue if not, it only returns true when the queue count is zero in plain terms if the current job is already in this queue allow the attempt else only allow the attempt if the queue is empty this prevents a busy queue from being bypassed by new jobs while still allowing queued jobs to continue retrying example example ticket submission the supplied script uses this pattern queueresource queue = evaluator getobject("=//resources/integration/queues/example") as queueresource; if (queue shouldtry) { resolvecategories( ); if (createincident( )) { ticket ticketnumber = ticketid; ticket state = servicedeskticket ticketstate submitted; ticket setinfo(); sd closeticket(ticket); return jobworkflow\ result nextstep; } } return jobworkflow\ result retry; the important design points are the queue is resolved from the resource tree queue shouldtry is checked before the external api call if the call succeeds, the ticket is updated and the workflow moves on if the queue is busy or the call should retry, the workflow returns retry non retryable exceptions are handled separately by setting the ticket and job to an error state this is a common pattern for service desk integrations because it separates retryable external failures from genuine workflow failures how queuejob(job) works queuejob(job) is the method used when a workflow needs to explicitly queue a job for retry it first checks whether the job is already marked as being in this queue if it is, the method exits to avoid duplicate queue entries when the orchestrator is running, it gets the background queue, checks whether the job id is already present, and adds the job id if needed it then suspends the workflow and, if the job is currently running, moves it to waitingaction the practical effect is the job stops running in the foreground the workflow is suspended against the queue resource the job is visible as waiting the background queue can resume it later background processing when the queue processes a job, backgroundprocess(jobid, log) refreshes the organisation context sets the current context name to the queue name loads the job by id marks the session as running from the queue creates a jobworkflow runs the job under runasjob executes workflow steps until the job completes or waits again if the workflow step returns waitaction , the queue logs a retry and returns false , allowing the job to continue later if an exception occurs, the queue logs the error and attempts to mark the job as complete with failure if it has not already completed retry timing retry timing is handled by activatebackgroundthread and activatebackgroundqueue the retry sequence is parsed from a comma or semicolon separated string when the queue needs the next timeout if the sequence is empty, it defaults to one minute if the current retry count is inside the sequence, it uses that value once the sequence is exhausted, it repeats the last value activatebackgroundqueue start() reads the queue’s retry sequence and submit delay when the queue starts important parameters parameter purpose class points the resource to innovation activate queueresource queue count volatile queue depth updated by the background queue queue retrysequence retry wake up sequence values are seconds, separated by commas or semicolons the last value repeats after the sequence is exhausted queue submitdelay delay in milliseconds between queued item submissions default is 1000 if not configured queue maxage maximum queue item age default is one day if not configured queue timeout how long an empty queue thread stays alive default is ten minutes transactionlimit rate limiter setting read from =/transactionlimit if blank, the queueresource limiter defaults to 10/sec transactionspersecond present in the supplied xml the current queueresource implementation uses transactionlimit for its limiter, so confirm wider provider code before relying on this parameter as the active queue throttle operational guidance keep queues specific use a separate queue for each external system or throttling boundary avoid sharing one queue across unrelated integrations unless they deliberately need a shared throttle treat queue count as state queue count is updated by the queue and should not be treated as a deployment setting tune retry timing carefully a sequence like 1,1,1,1,1,5 retries very quickly that may be useful for short lived locks but too aggressive for vendor outages for unstable apis, use longer retry windows prefer transactionlimit for current rate limiting the current queueresource implementation creates the limiter from =/transactionlimit and defaults to 10/sec when the value is blank watch the queue log the background queue writes log entries as it starts, attempts to submit queued items, and processes each queue pass it also writes limiter statistics when transactions have occurred troubleshooting checklist symptom what to check jobs are not retrying confirm the orchestrator is running queue processing depends on provisioningsystem isrunningasjobservice queue count is non zero check pending jobs for the queue using getqueuependingjobs @queue='\<queue name>' jobs retry too fast increase queue retrysequence , increase queue submitdelay , or lower transactionlimit jobs retry forever check whether the workflow keeps returning waitaction or retry confirm retryable and non retryable exceptions are separated external api is overloaded lower transactionlimit and increase queue submitdelay duplicate submission risk keep queue shouldtry immediately before the external submission call summary queueresource is activate’s queue backed retry and throttling resource it is used when workflows need to pause safely, retry later, and avoid overloading downstream systems the usual integration pattern is define a named queueresource set queue parameters such as queue retrysequence , queue submitdelay , and transactionlimit resolve the queue in script using evaluator getobject check queue shouldtry before calling the external api return retry or explicitly queue the job when the work should be replayed later let the orchestrator resume the workflow through backgroundprocess this makes queueresource especially useful for service desk submissions, vendor apis, and integrations where temporary failure should not immediately become job failure