Reputation: 77661
I have created a Cloud Task that has a retry policy with max attempts set to (for example 4).
However, we want the Task to fallback to a default solution if the Task fails for the last time.
That is, if the Task fails on the first time we just log the error and return 500
. And again for the second time. And the third. Etc... but if the current TaskRetryCount
is the last attempt for that queue (i.e. 4 in this example) then we will execute some fallback behaviour before returning 500
for the last time.
I can see from the Cloud Tasks HTTP Handler docs that I can get the X-CloudTasks-TaskRetryCount
from the header of the request. But it doesn't seem to have a way to get the max-attempts
for the queue.
Is that something that I can get hold of?
Or am I approaching this wrongly? Is there a better way of doing what I'm trying to do.
Upvotes: 5
Views: 2539
Reputation: 2101
If you want to execute something on the last retry you can use the below code.
It uses @google-cloud/tasks to get maxAttempts
from the queue and then compares that to the taskRetryCount
found in the task header.
import { CloudTasksClient } from '@google-cloud/tasks';
// Get the task queue
const tasksClient = new CloudTasksClient();
const request = {
name: `projects/${PROJECT_ID}/locations/${LOCATION}/queues/${TASK_QUEUE_NAME}`,
};
const taskQueue = await tasksClient.getQueue(request);
// Get maxAttempts
const maxAttempts = Number(taskQueue[0].retryConfig?.maxAttempts);
// Get taskRetryCount
const taskRetryCount = Number(req.headers['x-cloudtasks-taskretrycount']);
// We need to use "taskRetryCount + 1" to trigger something on the last retry
// We need to check for "maxAttempts != -1" because -1 is unlimited attempts
if (maxAttempts != -1 && taskRetryCount + 1 == maxAttempts) {
// Do something here on the last retry
}
Note 1: I had to use lowercase headers for mine to work. I.e. x-cloudtasks-taskretrycount
instead of X-CloudTasks-TaskRetryCount
as found in the Google Docs.
Note 2: In the answer by @Avishay28 it is suggested to use x-cloudtasks-taskexecutioncount
instead of x-cloudtasks-taskretrycount
, but I believe that if your trying to do something in the last retry you should be using x-cloudtasks-taskretrycount
.
Here is the description taken from the docs:
So if your task returns a 5xx
code or something happened and the task never got executed, then taskretrycount
will be higher then taskexecutioncount
. And since the task will end when taskretrycount
is more than maxAttempts
there may be a situtation where the task will end before you can do something in the last task.
The other option is to use taskexecutioncount
and never return a 5xx
status error from your task, but I think that is likely to produce unexpected results in the future when you eventually forget that rule. Also it doesn't account for times when something else happened and the task never got executed.
Upvotes: 1
Reputation: 2456
You can retrieve the queue max attempts value using getQueue call and inspecting queue.retryConfig.maxAttempts, and use the header X-CloudTasks-TaskRetryCount
to check the current retry, if maxAttempt != -1 && maxAttempt == (retry+1) your in the last retry.
Note that X-CloudTasks-TaskRetryCount
counting only tasks that return 5xx status code, and also tasks that did not get to the execution phase (to your code).
If you want to count only failed attempts happend in your exeuction phase, you should use the header X-CloudTasks-TaskExecutionCount
and make sure your code return 4xx status code in case of an error.
As per the docs:
X-CloudTasks-TaskExecutionCount The total number of times that the task has received a response from the handler. Since Cloud Tasks deletes the task once a successful response has been received, all previous handler responses were failures. This number does not include failures due to 5XX error codes.
Upvotes: 0
Reputation: 3794
Assuming that the tasks are created with Cloud Tasks the queue-level retry settings apply to all tasks in the queue that were created using Cloud Tasks (as they cannot be set on individual tasks). Calling the projects.locations.queues.get method from the REST API should return the RetryConfig settings from the Queue that include the maxAttempts
field that you require.
For tasks created with the App Engine SDK you should refer to this docs (although I believe that approach is deprecated and not useful for your use case).
Upvotes: 0