All Products
Search
Document Center

Function Compute:Lifecycle hooks for function instances

Last Updated:Dec 02, 2024

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

Background

After you implement and configure a lifecycle hook for function instances, Function Compute calls the hook when the corresponding instance lifecycle event occurs. The C# runtime supports Initializer and PreStop hooks. 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.

Hook method signature

  • Initializer hooks

    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 executed only once in the lifecycle of a function instance. If your 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.

  • PreStop hooks

    A PreStop hook is executed before a function instance is destroyed.

The method signatures of Initializer and PreStop hooks in the C# runtime are the same. Only the context input parameter is contained and no response parameters are returned. The following code snippet provides an example:

public void FunctionName(IFcContext context);

You can also set the hook method to a static method. The following code snippet provides an example:

public static void FunctionName(IFcContext context);

Example: StreamRequestHandler

The following sample code shows a simple program that contains an Initializer hook and PreStop hook.

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 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 lifecycle hooks in the Function Compute console. For more information, see Configure instance lifecycles. The format of a hook is the same as the format of a handler, which follows the Assembly name::Namespace.Class name::Method name format. For more information, see Handlers.

Examples:

  • Initializer hook: HelloFcApp::Example.Hello::Initialize

  • PreStop hook: HelloFcApp::Example.Hello::PreStop

Use Serverless Devs

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

  • Initializer hook

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

  • PreStop hook

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

Sample code:

# ------------------------------------
# Official manual: https://manual.serverless-devs.com/user-guide/aliyun/#fc3
# Tips: https://manual.serverless-devs.com/user-guide/tips/
# If you have any questions, join the DingTalk group 33947367 for technical support.
# ------------------------------------
edition: 3.0.0
name: hello-world-app
access: "default"

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

resources:
  hello_world:
    component: fc3 
    actions:       
      pre-${regex('deploy|local')}: 
        - run: dotnet publish -c Release -o ./target
          path: ./HelloWorldApp
    props:
      region: ${vars.region}              
      functionName: "start-dotnetcore-p6jp"
      description: 'hello world by serverless devs'
      runtime: "dotnetcore3.1"
      code: ./HelloWorldApp/target/
      handler: HelloWorldApp::Example.Hello::StreamHandler
      memorySize: 128
      timeout: 10
      instanceLifecycleConfig:      # The extension function
        initializer:                # The Initializer hook
          handler: HelloFcApp::Example.Hello::Initialize
          timeout: 60     
        preStop:                    # The PreStop hook
          handler: HelloFcApp::Example.Hello::PreStop  # The handler
          timeout: 60               # The timeout period    
      # triggers:
      #   - triggerName: httpTrigger # The trigger name
      #     triggerType: http # The trigger type
      #     description: 'xxxx'
      #     qualifier: LATEST # The function version
      #     triggerConfig:
      #       authType: anonymous # The authentication type. Valid values: anonymous and function.
      #       disableURLInternet: false # Specifies whether to disable access to the URL over the Internet.
      #       methods: # The access methods supported by the HTTP trigger. Valid values: GET, POST, PUT, DELETE, and HEAD.
      #         - GET
      #         - POST

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