This topic describes how to implement lifecycle hooks for function instances in the Java 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. The Java runtime environment supports all the preceding hooks. For more information, see Function instance lifecycle.

The billing rules for the 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, 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..

Method signature

Initializer hook 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. If your Initializer hook fails to be executed, the system retries the Initializer hook until the Initializer hook is successfully executed, and then runs your handler. Make sure that the Initializer hook is correctly configured when it is repeatedly invoked.

The Initializer hook consists of the context input parameter and can be invoked in the same manner as an event handler.

To use an Initializer hook, the FunctionInitializer operation must be inherited and the initialize method in the operation must be implemented. The following sample code provides an example on how to define the FunctionInitializer operation:
package com.aliyun.fc.runtime;

import java.io.IOException;

/**
 * This is the interface for the initialization operation
 */
public interface FunctionInitializer {

    /**
     * The interface to handle a function compute initialize request
     *
     * @param context The function compute initialize environment context object.
     * @throws IOException IOException during I/O handling
     */
    void initialize(Context context) throws IOException;
}

PreStop hook signature

A PreStop hook is executed before a function instance is destroyed. To use a PreStop hook, the PreStopHandler operation must be inherited and the preStop method in the operation must be implemented. The following sample code provides an example on how to define the PreStopHandler operation:
package com.aliyun.fc.runtime;

import java.io.IOException;

/**
 * This is the interface for the preStop operation
 */
public interface PreStopHandler {

    /**
     * The interface to handle a function compute preStop request
     *
     * @param context The function compute preStop environment context object.
     * @throws IOException IOException during I/O handling
     */
    void preStop(Context context) throws IOException;
}

PreFreeze hook signature

A PreFreeze hook is executed before a function instance is frozen. To use the PreFreeze hook, the PreFreezeHandler operation must be inherited and the preFreeze method in the operation must be implemented. The following sample code provides an example on how to define the PreFreezeHandler operation:
package com.aliyun.fc.runtime;

import java.io.IOException;

/**
 * This is the interface for the preFreeze operation
 */
public interface PreFreezeHandler {

    /**
     * The interface to handle a function compute preFreeze request
     *
     * @param context The function compute preFreeze environment context object.
     * @throws IOException IOException during I/O handling
     */
    void preFreeze(Context context) throws IOException;
}

Example: StreamRequestHandler

package example;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import com.aliyun.fc.runtime.FunctionInitializer;
import com.aliyun.fc.runtime.PreFreezeHandler;
import com.aliyun.fc.runtime.PreStopHandler;

public class App implements StreamRequestHandler, FunctionInitializer, PreFreezeHandler, PreStopHandler {
    @Override
    public void initialize(Context context) throws IOException {
        context.getLogger().info("initialize start ...");
    }

    @Override
    public void handleRequest(
            InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        context.getLogger().info("handlerRequest ...");
        outputStream.write(new String("hello world\n").getBytes());
    }

    @Override
    public void preFreeze(Context context) throws IOException {
        context.getLogger().info("preFreeze start ...");
    }

    @Override
    public void preStop(Context context) throws IOException {
        context.getLogger().info("preStop start ...");
    }
}

Configure lifecycle hooks

Use the Function Compute console

You can configure the lifecycle hooks on the Function Details page in the Function Compute console. The format of a hook is [Package name].[Class name]::[Method name]. Example:db_java_lifecycle
  • If you set Initializer Hook to example.App::initialize, the initialize method in the App.java file of the example is implemented.
  • If you set PreFreeze Hook to example.App::preFreeze, the preFreeze method in the App.java file of the example package is implemented.
  • If you set PreStop Hook to example.App::preStop, the preStop method in the App.java file of the example package is implemented.

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.
  • 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.

Sample code:

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

vars: # The global variable.
  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: java8-lifecycle-hook-demo
        description: 'fc example by serverless devs'
        runtime: java8
        codeUri: ./target
        handler: example.App::handleRequest
        memorySize: 128
        timeout: 60
        initializationTimeout: 60
        initializer: example.App::initialize
        instanceLifecycleConfig:
          preFreeze:
            handler: example.App::preFreeze
            timeout: 30
          preStop:
            handler: example.App::preStop
            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

  • For information about the sample programs on Initializer and PreStop hooks that are provided by Function Compute, see java11-mysql.

    This example shows how to use an Initializer hook to obtain database configurations from the environment variables and create MySQL connections, and how to use a PreStop hook to close MySQL connections in the Java runtime environment.