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

Background

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, and Advanced Logs. Log for lifecycle hooks are not displayed in Call Request List.

Method signature

  • Initializer hook

    The Initializer hook is executed after the function instance is started and before the handler runs. Function Compute ensures that the Initializer hook is successfully executed only once in the lifecycle of a function instance. If the initializer hook fails to be executed, an error is returned for the function invocation. When you invoke the function next time, the system creates another function instance to execute the Initializer hook.

  • PreFreeze hook

    The PreFreeze hook is executed before the function instance is frozen.

  • PreStop hook

    The PreStop hook is executed before the function instance is destroyed.

The method signatures for the Initializer hook, the PreFreeze hook, and the PreStop hook are the same in the C# runtime environment. The signatures contain only the Context input parameter and no response parameter. The following sample code provides an example on how to define the Context input parameter:
public void FunctionName(IFcContext context);
You can also set the hook method to a static method. The following sample code provides an example on how to define the static method:
public static void FunctionName(IFcContext context);

Example: StreamRequestHandler

The following sample code provides an example on a simple program that contains the Initializer, PreFreeze, and PreStop hooks:
using System;
using System.IO;
using System.Threading.Tasks;
using Aliyun.Serverless.Core;
using Microsoft.Extensions.Logging;

namespace Example
{
    public class Hello
    {
        public void Initialize(IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("Initialize start");
            logger.LogInformation("Handle initializer: {0}", context.RequestId);
            logger.LogInformation("Initialize end");
        }

        public void PreStop(IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("PreStop start");
            logger.LogInformation("Handle PreStop: {0}", context.RequestId);
            logger.LogInformation("PreStop end");
        }

        public void PreFreeze(IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("PreFreeze start");
            logger.LogInformation("Handle PreFreeze: {0}", context.RequestId);
            logger.LogInformation("PreFreeze end");
        }

        public async Task<Stream> StreamHandler(Stream input, IFcContext context)
        {
            IFcLogger logger = context.Logger;
            logger.LogInformation("Handle request: {0}", context.RequestId);

            MemoryStream copy = new MemoryStream();
            await input.CopyToAsync(copy);
            copy.Seek(0, SeekOrigin.Begin);
            return copy;
        }

        static void Main(string[] args){}
    }
}

Configure lifecycle hooks

Use the Function Compute console

You can configure the lifecycle hooks on the Function Details page in the Function Compute console. For more information, see Configure the PreFreeze hook and the PreStop hook in the Function Compute console. The format of the hook method is the same as that of the request handler. The format is Assembly name::Namespace.Class name::Method name. For more information, see Handler.

Examples
  • The Initializer hook: HelloFcApp::Example.Hello::Initialize
  • The PreFreeze hook: HelloFcApp::Example.Hello::PreFreeze
  • The PreStop hook: HelloFcApp::Example.Hello::PreStop

Use Serverless Devs

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

    Add the initializer and initializationTimeout fields to the function parameter.

  • PreFreeze hook

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

  • PreStop hook

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

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
    actions: # The custom execution logic.
      pre-deploy: # The operation before the deployment.
        - run: mvn package # The command to run.
          path: ./ # The path in which the command runs.
    props: # The property value of the component.
      region: ${vars.region}
      service: ${vars.service}
      function:
        name: dotnet-lifecycle-hook-demo
        description: 'fc example by serverless devs'
        runtime: dotnetcore3.1
        codeUri: ./target
        handler: example.App::handleRequest
        memorySize: 128
        timeout: 60
        initializer: HelloFcApp::Example.Hello::Initialize
        initializationTimeout: 30
        instanceLifecycleConfig:
          preStop:
            Handler: HelloFcApp::Example.Hello::PreStop
            Timeout: 30
          preFreeze:
            Handler: HelloFcApp::Example.Hello::PreFreeze
            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*****