This topic describes how to implement lifecycle hooks for function instances in the Go runtime environment.

Background information

After you configure a lifecycle hook for a function instance, Function Compute invokes the hook when a related lifecycle event for the instance occurs. The following lifecycle hooks can be configured for a function instance: Initializer, PreFreeze, and PreStop. For more information, see Function instance lifecycle.

The billing rules for the lifecycle hooks of function instances are the same as those for common invocation requests. However, the execution logs can be queried only in Function Logs, Instance Logs, or Advanced Logs. The logs for lifecycle hooks are not displayed in Call Request List. For more information, see View the logs of instance lifecycle hooks..

Important If you want to use PreFreeze and PreStop hooks, upgrade fc-runtime-go-sdk to v0.1.0 or later.

Hook method signature

  • An Initializer hook is executed after a function instance is started and before a handler runs. Function Compute ensures that an Initializer hook is successfully invoked only once in the lifecycle of a function instance. For example, if an Initializer hook fails to be invoked, the system retries the Initializer hook until the Initializer hook is successfully invoked, and then runs your handler. Make sure that the Initializer hook is correctly configured when it is repeatedly invoked.
  • A PreFreeze hook is executed before a function instance is frozen.
  • A PreStop hook is executed before a function instance is destroyed.
The method signatures for Initializer hooks, PreFreeze hooks, and PreStop hooks are the same. The signatures contain only the Context input parameter and no response parameter. Syntax:
function(ctx context.Context)

Implement hook methods

You must implement the lifecycle hook methods in the code and use the corresponding functions for registration. The following code shows how to register the hook methods:
// Register the Initializer hook method.
fc.RegisterInitializerFunction(initialize)
// Register the PreStop hook method.
fc.RegisterPreStopFunction(preStop)
// Register the PreFreeze hook method.
fc.RegisterPreFreezeFunction(preFreeze)
Sample program:
package main

import (
    "context"
    "log"

    "github.com/aliyun/fc-runtime-go-sdk/fc"
    "github.com/aliyun/fc-runtime-go-sdk/fccontext"
)

func HandleRequest(ctx context.Context) (string, error) {
    return "hello world!", nil
}

func preStop(ctx context.Context) {
    log.Print("this is preStop handler")
    fctx, _ := fccontext.FromContext(ctx)
    fctx.GetLogger().Infof("context: %#v\n", fctx)
}

func preFreeze(ctx context.Context) {
    log.Print("this is preFreeze handler")
    fctx, _ := fccontext.FromContext(ctx)
    fctx.GetLogger().Infof("context: %#v\n", fctx)
}

func initialize(ctx context.Context) {
    log.Print("this is initialize handler")
    fctx, _ := fccontext.FromContext(ctx)
    fctx.GetLogger().Infof("context: %#v\n", fctx)
}

func main() {
    fc.RegisterInitializerFunction(initialize)
    fc.RegisterPreStopFunction(preStop)
    fc.RegisterPreFreezeFunction(preFreeze)
    fc.Start(HandleRequest)
}                
Description
  • func initialize(ctx context.Context): the Initializer hook method. The ctx context.Context parameter provides the context information when the function is executed. For more information, see Context.
  • func preStop(ctx context.Context): the PreStop hook method. The ctx context.Context parameter provides the context information when the function is executed. For more information, see Context.
  • func preFreeze(ctx context.Context): the PreFreeze hook method. The ctx context.Context parameter provides the context information when the function is executed. For more information, see Context.
  • func main(): the entry point for function code in FC. A Go program must contain the main function. You can add fc.Start(HandleRequest) to your code to specify the method to execute the handler, and add fc.RegisterInitializerFunction(initialize) to register the Initializer hook method. Register the PreStop and PreFreeze hook methods in the similar way.
    Important
    • The preceding sample code applies only to event handlers. If you use an HTTP handler, replace fc.Start(HandleRequest) in the code with fc.StartHttp(HandleRequest).
    • The lifecycle hook method must be registered before fc.Start(HandleRequest) or fc.StartHttp(HandleRequest). Otherwise, the registration fails.

Configure lifecycle hooks

Use the Function Compute console

You can configure the Initializer Hook, PreFreeze Hook, and PreStop Hook parameters on the Function Details page in the Function Compute console.FC Example:

db-go-lifecycle

For more information, see Function instance lifecycle.

Use Serverless Devs

Use Serverless Devs

You can use Serverless Devs to configure lifecycle hooks. In this case, you must add the Initializer hook, PreFreeze hook, and PreStop hook to the s.yaml file.
  • Configure the Initializer hook

    Add the initializer and initializationTimeout fields to the function parameter.

  • Configure the PreFreeze hook

    Add the instanceLifecycleConfig.preFreeze field, including handler and timeout, to the function parameter.

  • Configure the PreStop hook

    Add the instanceLifecycleConfig.preStop field, including handler and timeout, to the function parameter.

Important The handler field must be configured as a non-empty string. When you use the default value "true" in the s.yaml file, the double quotation marks cannot be removed.

Sample code:

edition: 1.0.0
name: hello-world  #  The name of the project.
access: default    #  The alias of the key.

vars: # The global variables.
  region: cn-shanghai # The ID of the region.
  service:
    name: fc-example
    description: 'fc example by serverless devs'

services:
  helloworld: # The name of the service or module.
    component: fc
    props: # The property value of the component.
      region: ${vars.region}
      service: ${vars.service}
      function:
        name: golang-lifecycle-hook-demo
        description: 'fc example by serverless devs'
        runtime: go1
        codeUri: ./target
        handler: main
        memorySize: 128
        timeout: 60
        initializationTimeout: 60
        initializer: "true"
        instanceLifecycleConfig:
          preFreeze:
            handler: "true"
            timeout: 30
          preStop:
            handler: "true"
            timeout: 30

For more information about the YAML syntax of Serverless Devs, see Serverless Devs commands.

View the logs of instance lifecycle hooks.

You can view the logs for lifecycle hook in Function Logs.

  1. Log on to the Function Compute console. In the left-side navigation pane, click Services & Functions.
  2. In the top navigation bar, select a region. On the Services page, click the desired service.
  3. On the Functions page, click the name of the desired function. On the Function Details page that appears, click the Test Function tab.
  4. On the Test Function tab, click Test Function. Choose Logs > Function Logs.
    On the Function Logs tab, you can view the invocation logs, and the logs for the Initializer hooks and PreFreeze hooks of the function. Example:
    2022-10-09 19:26:17 FunctionCompute dotnetcore3.1 runtime inited.
    2022-10-09 19:26:17 FC Initialize Start RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Initialize start
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Handle initializer: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Initialize end
    2022-10-09 19:26:17 FC Initialize End RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 FC Invoke Start RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Handle request: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 FC Invoke End RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 FC PreFreeze Start RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] PreFreeze start
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] Handle PreFreeze: 793ad2f1-9826-4d9a-90d9-5bf39e******
    2022-10-09 19:26:17 2022-10-09 19:26:17 793ad2f1-9826-4d9a-90d9-5bf39e****** [INFO] PreFreeze end
    2022-10-09 19:26:17 FC PreFreeze End RequestId: 793ad2f1-9826-4d9a-90d9-5bf39e******
    Each function instance is cached for a period of time and not destroyed immediately, you cannot view the logs for PreStop hooks right away. To quickly trigger the PreStop hook, you can update the function configurations or function code. After the update is complete, you can view the logs for PreStop hooks in Function Logs. Example:
    2022-10-09 19:32:17 FC PreStop Start RequestId: 03be685c-378b-4736-8b08-a67c1d*****
    2022-10-09 19:32:17 2022-10-09 19:32:17 03be685c-378b-4736-8b08-a67c1d***** [INFO] PreStop start
    2022-10-09 19:32:17 2022-10-09 19:32:17 03be685c-378b-4736-8b08-a67c1d***** [INFO] Handle PreStop: 03be685c-378b-4736-8b08-a67c1d*****
    2022-10-09 19:32:17 2022-10-09 19:32:17 03be685c-378b-4736-8b08-a67c1d***** [INFO] PreStop end
    2022-10-09 19:32:17 FC PreStop End RequestId: 03be685c-378b-4736-8b08-a67c1d*****

Sample programs

Function Compute provides the sample program for invoking the Initializer hook. The sample program provides an example on how to use the Initializer hook in the Go runtime environment to initialize a MySQL connection pool. In the sample program, the MySQL database is configured by using an environment variable of the function. For more information, see the s.yaml file. The Initializer hook obtains the database configuration based on the environment variable, creates a MySQL connection pool, and then tests the connectivity.

For more information, see go-initializer-mysql.