All Products
Search
Document Center

Function Compute:Lifecycle hooks for function instances

Last Updated:Aug 08, 2024

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

Background

After you configure a lifecycle hook for a function instance, Function Compute invokes the hook when a corresponding lifecycle event occurs. Initializer hooks and PreStop hooks are involved in the lifecycles of Go functions. For more information, see Configure instance lifecycles.

The billing rules for lifecycle hooks of function instances are the same as the billing rules for common invocation requests. However, the execution logs can be queried only in Function Logs, Real-time Logs, and Advanced Logs. The logs for lifecycle hooks are not displayed in the invocation request list. For more information, see View the logs of instance lifecycle hooks.

Important

To use the PreStop hook, update the version of fc-runtime-go-sdk to V0.1.0 or later.

Method signature

  • The Initializer hook is invoked after a function instance is started and before a handler is run. Function Compute ensures that the Initializer hook is successfully invoked only once in the lifecycle of a function instance. If the Initializer hook fails to be invoked, the system retries the Initializer hook until the Initializer hook is successfully invoked before the handler is run. To make sure that the Initializer hook can be repeatedly retried, configure the Initializer hook properly.

  • The PreStop hook is invoked before a function instance is destroyed.

The method signature of an Initializer hook is the same as that of a PreStop hook. Both hooks have only the Context input parameter, and no value is returned. Syntax:

function(ctx context.Context)

Implement lifecycle hooks

You must implement lifecycle hooks in the code and use the corresponding methods for registration. The following sample code provides examples on how to register lifecycle hooks:

// Register the Initializer hook.
fc.RegisterInitializerFunction(initialize)
// Register the PreStop hook.
fc.RegisterPreStopFunction(preStop)

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 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.Start(HandleRequest)
}                

Description

  • func initialize(ctx context.Context): the Initializer hook. The ctx context.Context parameter specifies the context information to be used when the hook is invoked. For more information, see Context.

  • func preStop(ctx context.Context): the PreStop hook. The ctx context.Context parameter specifies the context information to be used when the hook is invoked. For more information, see Context.

  • func main(): the entry point for running function code in FC. A Go program must contain the main method. You can add fc.Start(HandleRequest) to your code to specify the method used to run the handler, and add fc.RegisterInitializerFunction(initialize) to register the Initializer hook. Then, register the PreStop hook in a similar way.

    Important

    A lifecycle hook must be registered before fc.Start(HandleRequest) or fc.StartHttp(HandleRequest) is run. Otherwise, the registration fails.

Configure lifecycle hooks

Use the Function Compute console

You can configure the Initializer hook and PreStop hook of a function in the Function Compute console. Example:

db-go-lifecycle

For more information, see Configure instance lifecycles.

Use Serverless Devs

If you use Serverless Devs to configure lifecycle hooks, you must add the Initializer hook and PreStop hook configurations to the s.yaml file.

  • Configure the Initializer hook

    Add the initializer and initializationTimeout fields to the function configurations.

  • Configure the PreStop hook

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

Important

The handler field must be configured as a non-empty string. When the default value "true" is used in the s.yaml file, it must be enclosed in double quotation marks.

Sample code:

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

vars: # The global variables.
  region: cn-hangzhou # The region.

resources:
  helloworld: # The name of the service or module.
    component: fc3 # The name of the component.
    props: #  The properties of the component.
      region: ${vars.region} # The region.
      functionName: "golang-lifecycle-hook-demo"
      description: 'this is golang lifecycle'
      runtime: "go1"
      code: ./
      handler: main
      memorySize: 128
      timeout: 60
      instanceLifecycleConfig:                       # The extension function.
        preStop:                                     # The PreStop hook.
          handler: preStop # The function handler.
          timeout: 60 # The timeout period.
        initializer:
          handler: initialize
          timeout: 60

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

View the logs of instance lifecycle hooks

You can view the logs for lifecycle hook in Logs.

  1. Log on to the Function Compute console. In the left-side navigation pane, click Functions.

  2. In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.

  3. On the function details page, click the Test Function tab, click Test Function, and then choose Logs > Function Logs.

    On the Logs tab, you can view function invocation logs and Initializer logs. Example:

    2024-03-04 17:57:28FC Initialize Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
    2024-03-04 17:57:282024-03-04 09:57:28.192 1-65e59b07-1520da26-bf73bbb91b69 [info] initializer
    2024-03-04 17:57:28FC Initialize End RequestId: 1-65e59b07-1520da26-bf73bbb91b69
    2024-03-04 17:57:28FC Invoke Start RequestId: 1-65e59b07-1520da26-bf73bbb91b69
    2024-03-04 17:57:28FC Invoke End RequestId: 1-65e59b07-1520da26-bf73bbb91b69

    Each function instance is cached for a period of time and not immediately destroyed, you cannot view logs for PreStop hooks right away. To quickly trigger a 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. The following sample code shows an example:

    2024-03-04 18:33:26FC PreStop Start RequestId: 93c93603-9fbe-4576-9458-193c8b213031
    2024-03-04 18:33:262024-03-04 10:33:26.077 93c93603-9fbe-4576-9458-193c8b213031 [info] preStop
    2024-03-04 18:33:26FC PreStop End RequestId: 93c93603-9fbe-4576-9458-193c8b213031

Sample program

Function Compute provides a sample program for invoking the Initializer hook. The sample program provides an example on how to use the Initializer hook in the Go runtime to initialize a MySQL connection pool. In the sample program, a MySQL database is configured by using the environment variables of a function. For more information, see the s.yaml file. The Initializer hook is used to obtain the configurations of the MySQL database from environment variables, create a MySQL connection pool, and then test the connectivity.

For more information, visit go-initializer-mysql.