-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add features to task queue functions #1423
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
- Add features to task queue functions. (#1423) | ||
- Update list of supported regions for 2nd Gen Functions. (#1402) |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -88,22 +88,72 @@ export interface TaskContext { | |||||
* The result of decoding and verifying an ODIC token. | ||||||
*/ | ||||||
auth?: AuthData; | ||||||
|
||||||
/** | ||||||
* The name of the queue. | ||||||
* Populated via the X-CloudTasks-QueueName header. | ||||||
*/ | ||||||
queueName: string; | ||||||
|
||||||
/** | ||||||
* The "short" name of the task, or, if no name was specified at creation, a unique | ||||||
* system-generated id. | ||||||
* This is the my-task-id value in the complete task name, ie, task_name = | ||||||
* projects/my-project-id/locations/my-location/queues/my-queue-id/tasks/my-task-id. | ||||||
* Populated via the X-CloudTasks-TaskName header. | ||||||
*/ | ||||||
id: string; | ||||||
|
||||||
/** | ||||||
* The number of times this task has been retried. | ||||||
* For the first attempt, this value is 0. This number includes attempts where the task failed | ||||||
* due to 5XX error codes and never reached the execution phase. | ||||||
* Populated via the X-CloudTasks-TaskRetryCount header. | ||||||
*/ | ||||||
retryCount: number; | ||||||
|
||||||
/** | ||||||
* 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. | ||||||
* Populated via the X-CluodTasks-TaskExecutionCount header. | ||||||
*/ | ||||||
executionCount: number; | ||||||
|
||||||
/** | ||||||
* The schedule time of the task, as an RFC 3339 string in UTC time zone | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* Populated via the X-CloudTasks-TaskETA header, which uses seconds since January 1 1970. | ||||||
*/ | ||||||
scheduledTime: string; | ||||||
|
||||||
/** | ||||||
* The HTTP response code from the previous retry. | ||||||
* Populated via the X-CloudTasks-TaskPreviousResponse header | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would suggest putting the additional comments like this under Or to put it as a single sentence. FYI everything under |
||||||
*/ | ||||||
previousResponse?: number; | ||||||
|
||||||
/** | ||||||
* The reason for retrying the task. | ||||||
* Populated via the X-CloudTasks-TaskRetryReason header. | ||||||
*/ | ||||||
retryReason?: string; | ||||||
|
||||||
/** | ||||||
* Raw request headers. | ||||||
*/ | ||||||
headers?: Record<string, string>; | ||||||
} | ||||||
|
||||||
/** | ||||||
* The request used to call a Task Queue function. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somewhat out of scope here, but "Task Queue" does not need caps. |
||||||
*/ | ||||||
export interface Request<T = any> { | ||||||
export type Request<T = any> = TaskContext & { | ||||||
/** | ||||||
* The parameters used by a client when calling this function. | ||||||
*/ | ||||||
data: T; | ||||||
|
||||||
/** | ||||||
* The result of decoding and verifying an ODIC token. | ||||||
*/ | ||||||
auth?: AuthData; | ||||||
} | ||||||
}; | ||||||
|
||||||
type v1TaskHandler = (data: any, context: TaskContext) => void | Promise<void>; | ||||||
type v2TaskHandler<Req> = (request: Request<Req>) => void | Promise<void>; | ||||||
|
@@ -119,7 +169,26 @@ export function onDispatchHandler<Req = any>( | |||||
throw new https.HttpsError("invalid-argument", "Bad Request"); | ||||||
} | ||||||
|
||||||
const context: TaskContext = {}; | ||||||
const headers: Record<string, string> = {}; | ||||||
for (const [key, value] of Object.entries(req.headers)) { | ||||||
if (!Array.isArray(value)) { | ||||||
headers[key] = value; | ||||||
} | ||||||
} | ||||||
|
||||||
const context: TaskContext = { | ||||||
queueName: req.header("X-CloudTasks-QueueName"), | ||||||
id: req.header("X-CloudTasks-TaskName"), | ||||||
retryCount: Number(req.header("X-CloudTasks-TaskRetryCount")), | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit* Can we make sure this won't below up if the request header isn't missing for some reason (e.g. when we invoke it in the emulator). Would prefer having safe default behavior in case these headers are missing for whatever reason (maybe log a warning when that happens?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now, the context object will just omit the missing headers if they are missing from the request object but still safely dispatch the handler with the context — what scenarios are you thinking about specifically? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh i thought this would blow up:
Not sure if I like |
||||||
executionCount: Number(req.header("X-CloudTasks-TaskExecutionCount")), | ||||||
scheduledTime: req.header("X-CloudTasks-TaskETA"), | ||||||
previousResponse: req.header("X-CloudTasks-TaskPreviousResponse") | ||||||
? Number(req.header("X-CloudTasks-TaskPreviousResponse")) | ||||||
: undefined, | ||||||
retryReason: req.header("X-CloudTasks-TaskRetryReason"), | ||||||
headers, | ||||||
}; | ||||||
|
||||||
if (!process.env.FUNCTIONS_EMULATOR) { | ||||||
const authHeader = req.header("Authorization") || ""; | ||||||
const token = authHeader.match(/^Bearer (.*)$/)?.[1]; | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc strings all look good!
Only question for me is whether "X-CloudTasks-QueueName" should be backticked as a literal. Or is the idea here that we are suggesting variables, where "QueueName" will actually be a unique name, and X maybe a number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, per offline, it sounds like we should backtick it for code font as in https://firebase.google.com/docs/functions/callable-reference#request_format_headers and elsewhere.