After you implement and configure an instance lifecycle hook, Function Compute invokes it when the corresponding lifecycle event occurs. This topic describes how to implement instance lifecycle hooks in a custom image.
Background
A function instance's lifecycle includes Initializer and PreStop hooks. The Initializer hook has two types: invoke code and execute instruction. Currently, only GPU-accelerated functions support the execute instruction type of Initializer hook. For more information, see Configure instance lifecycle.
Instance lifecycle hooks follow the same billing rules as regular invocation requests. However, you can view their execution logs only in Real-time Log, Function Logs, or Advanced Logs. The Invocation Request List does not show hook logs. For more information, see View instance lifecycle hook logs.
Currently, logs generated by execute instruction hooks cannot be written to Function Log.
Implementing hook methods
A function instance's lifecycle in Function Compute includes Initializer and PreStop hooks. You can configure an Initializer hook as either invoke code or execute instruction, but not both.
Invoke code
After you configure a hook of the invoke code type, the system sends a POST /initialize or GET /pre-stop HTTP request to your function when a function instance starts or stops. You need to respond to this request in your business code.
|
Path |
Request |
Expected response |
|
(Optional) POST |
|
The value returned by the Initializer hook. Status code
Note
When the Initializer hook times out or fails, the server always returns an HTTP 200 status code. You must check the |
|
(Optional) GET |
|
The value returned by the PreStop hook. Status code
|
To use an Initializer hook in your custom image, you must implement the logic for the /initialize path and POST method in your HTTP server. The same principle applies to the PreStop hook. The following example shows a sample program for a Python 3.10 custom runtime.
If you do not set an Initializer for a function, you do not need to implement the /initialize path. In this case, even if your HTTP server implements the /initialize path, its logic is not invoked. The same principle applies to the PreStop hook.
import os
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route('/initialize', methods=['POST'])
def init_invoke():
rid = request.headers.get('x-fc-request-id')
print("FC Initialize Start RequestId: " + rid)
# do your things
print("FC Initialize End RequestId: " + rid)
return "OK"
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def hello_world(path):
rid = request.headers.get('x-fc-request-id')
print("FC invoke Start RequestId: " + rid)
# do your things
print("FC invoke End RequestId: " + rid)
return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]
@app.route('/pre-stop', methods=['GET'])
def prestop_invoke():
rid = request.headers.get('x-fc-request-id')
print("FC PreStop Start RequestId: " + rid)
# do your things
print("FC PreStop End RequestId: " + rid)
return "OK"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
In addition to the preceding working example, the following /initialize examples show error scenarios in Python.
@app.route('/initialize', methods=['POST'])
def init():
raise Exception("hahaha")
return "OK", 200, []@app.route('/initialize', methods=['POST'])
def init():
return "OK", 404, []
Execute instruction
You can configure an execute instruction hook to run an initialization script when a function instance starts. You can use any shell implementation, such as /bin/bash, /bin/sh, /bin/csh, or /bin/zsh, as long as it is supported by the function's runtime environment.
The Function Compute console provides /bin/bash and /bin/sh as preset options. The following example uses /bin/sh.
#!/bin/sh
URL="http://localhost:7860"
REQUEST_PATH="sdapi/v1/txt2img"
JSON_DATA='{
"prompt": "",
"steps": 1,
"height": 8,
"width": 8
}'
temp_file=$(mktemp)
trap 'rm -f "$temp_file"' EXIT
if ! http_code=$(curl -s -w "%{http_code}" \
-H "Content-Type: application/json" \
-d "$JSON_DATA" \
-o "$temp_file" \
-X POST "$URL"/"$REQUEST_PATH"); then
echo "{\"status\": \"curl_error\", \"code\": $curl_exit_code}" \
| jq . >&2
exit 1
fi
response=$(<"$temp_file")
echo "http code $http_code"
if [ "$http_code" -eq 200 ]; then
echo "$response" | jq -r '.' || printf "%s\n" "$response"
exit 0
else
echo "$response_body" \
| jq -c 'if type == "object" then . else {raw: .} end' 2>/dev/null \
| jq -s '{status: "http_error", code: $code, response: .[0]}' \
--arg code "$http_code" \
>&2
exit 1
fi
An exit code of 0 indicates success; any other value indicates failure. You can write error information to standard error (stderr) in your script to help identify the cause of errors. For example, the following code snippet shows that after a curl request fails, relevant error information is output and the exit code is set to 1.
if ! http_code=$(curl -s -w "%{http_code}" \
-H "Content-Type: application/json" \
-d "$JSON_DATA" \
-o "$temp_file" \
-X POST "$URL"/"$REQUEST_PATH"); then
echo "{\"status\": \"curl_error\", \"code\": $curl_exit_code}" \
| jq . >&2
exit 1
fi
Hook error codes
Invoke code
|
Error code |
Description |
|
400 |
|
|
404 |
|
|
500 |
Function Compute restarts the instance. |
Execute instruction
If the instruction returns a non-zero exit code, the system does not re-execute it and instead returns an error.
Configure lifecycle hooks
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
-
On the function details page, click the Configuration tab. In the Instance Configuration section, click Modify.
-
In the Instance Configuration panel, configure the Initializer hook and set the Initializer timeout.
-
invoke code
Turn on the Initializer hook switch. Set the Initializer timeout to
300seconds. For hook type, select invoke code or execute instruction. After the hook is enabled, Function Compute sends an HTTP POST/initializerequest when an instance starts. Your code must handle this request and return a 200 status code. If a 4xx or 5xx status code is returned, Function Compute returns an error or restarts the instance. -
execute instruction
The console provides two preset shell implementations:
/bin/bashand/bin/sh.Turn on the Initializer hook switch, set the Initializer timeout to 300 seconds, and select execute instruction as the hook type. For the command, select /bin/sh. In the code editor, write a health check script. For example, use
curlto send a POST request tolocalhost:7860/sdapi/v1/txt2imgwith JSON parameters includingprompt,steps,height, andwidth. Usemktempto create a temporary file andtrapto set up cleanup.
-
-
In the Instance Configuration panel, configure the PreStop hook and its timeout, and then click Deploy.
Turn on the PreStop hook switch and set the PreStop timeout to
3seconds.
View instance lifecycle hook logs
Currently, logs generated by execute instruction hooks cannot be written to Function Log.
You can view hook logs by using the Function Logs feature.
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
-
On the function details page, click the Test tab, click Test Function, and then choose .
On the Function Logs tab, you can view the function's invocation logs and Initializer hook logs. The following is an example:
2024-06-26 10:59:23FC Initialize Start RequestId: 529eab23-9b3a-4ffc-88c8-9a686******* 2024-06-26 10:59:23FC Initialize End RequestId: 529eab23-9b3a-4ffc-88c8-9a686******* 2024-06-26 10:59:25FC Invoke Start RequestId: 1-667b840c-15c49df0-b7dc1******* 2024-06-26 10:59:25FC Invoke End RequestId: 1-667b840c-15c49df0-b7dc1*******Since function instances are cached and not immediately destroyed, PreStop hook logs are not available instantly. To quickly trigger the PreStop hook, you can update the function's configuration or code. After the update is complete, check Function Logs again to view the PreStop hook logs. The following is an example:
2024-06-26 11:04:33FC PreStop Start RequestId: c4385899-f071-490e-a8b7-e33c5******* 2024-06-26 11:04:33FC PreStop End RequestId: c4385899-f071-490e-a8b7-e33c5*******