Funciones en segundo plano

Usa funciones en segundo plano cuando quieras invocar tu función de Cloud Functions de manera indirecta en respuesta a un evento, como un mensaje en un tema de Pub/Sub, un cambio en un depósito de Cloud Storage o un evento de Firebase.

Para obtener información sobre cómo reintentar funciones en segundo plano, consulta Reintenta las funciones en segundo plano.

Ejemplo de uso

En los siguientes ejemplos, se muestra cómo procesar eventos desde Pub/Sub y Cloud Storage. Para obtener más información sobre el control de eventos de diferentes fuentes, consulta Llama a Cloud Functions.

Ejemplo de Pub/Sub

En este ejemplo, se muestra una función de Cloud Functions activada por eventos de Pub/Sub. Cada vez que se publica un mensaje en un tema de Pub/Sub, se invoca la función y se escribe en el registro un saludo con datos derivados del mensaje.

Node.js

/**
 * Background Cloud Function to be triggered by Pub/Sub.
 * This function is exported by index.js, and executed when
 * the trigger topic receives a message.
 *
 * @param {object} message The Pub/Sub message.
 * @param {object} context The event metadata.
 */
exports.helloPubSub = (message, context) => {
  const name = message.data
    ? Buffer.from(message.data, 'base64').toString()
    : 'World';

  console.log(`Hello, ${name}!`);
};

Python

def hello_pubsub(event, context):
    """Background Cloud Function to be triggered by Pub/Sub.
    Args:
         event (dict):  The dictionary with data specific to this type of
         event. The `data` field contains the PubsubMessage message. The
         `attributes` field will contain custom attributes if there are any.
         context (google.cloud.functions.Context): The Cloud Functions event
         metadata. The `event_id` field contains the Pub/Sub message ID. The
         `timestamp` field contains the publish time.
    """
    import base64

    print("""This Function was triggered by messageId {} published at {}
    """.format(context.event_id, context.timestamp))

    if 'data' in event:
        name = base64.b64decode(event['data']).decode('utf-8')
    else:
        name = 'World'
    print('Hello {}!'.format(name))

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"log"
)

// PubSubMessage is the payload of a Pub/Sub event.
type PubSubMessage struct {
	Data []byte `json:"data"`
}

// HelloPubSub consumes a Pub/Sub message.
func HelloPubSub(ctx context.Context, m PubSubMessage) error {
	name := string(m.Data) // Automatically decoded from base64.
	if name == "" {
		name = "World"
	}
	log.Printf("Hello, %s!", name)
	return nil
}

Java


import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import functions.eventpojos.PubSubMessage;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.logging.Level;
import java.util.logging.Logger;

public class HelloPubSub implements BackgroundFunction<PubSubMessage> {
  private static final Logger logger = Logger.getLogger(HelloPubSub.class.getName());

  @Override
  public void accept(PubSubMessage message, Context context) {
    String name = "world";
    if (message != null && message.getData() != null) {
      name = new String(
          Base64.getDecoder().decode(message.getData().getBytes(StandardCharsets.UTF_8)),
          StandardCharsets.UTF_8);
    }
    logger.info(String.format("Hello %s!", name));
    return;
  }
}

Para obtener más información sobre la implementación de funciones de Cloud Functions activadas por eventos de Pub/Sub, consulta Instructivo de Pub/Sub y Activadores de Pub/Sub.

Ejemplo de Cloud Storage

En este ejemplo, se muestra una función de Cloud Functions activada por eventos de Cloud Storage. Cada vez que se crea un objeto en un depósito de Cloud Storage, se invoca la función y se escribe un mensaje sobre el cambio en el registro.

Node.js

/**
 * Generic background Cloud Function to be triggered by Cloud Storage.
 *
 * @param {object} file The Cloud Storage file metadata.
 * @param {object} context The event metadata.
 */
exports.helloGCS = (file, context) => {
  console.log(`  Event: ${context.eventId}`);
  console.log(`  Event Type: ${context.eventType}`);
  console.log(`  Bucket: ${file.bucket}`);
  console.log(`  File: ${file.name}`);
  console.log(`  Metageneration: ${file.metageneration}`);
  console.log(`  Created: ${file.timeCreated}`);
  console.log(`  Updated: ${file.updated}`);
};

Python

def hello_gcs(event, context):
    """Background Cloud Function to be triggered by Cloud Storage.
       This generic function logs relevant data when a file is changed.

    Args:
        event (dict):  The dictionary with data specific to this type of event.
                       The `data` field contains a description of the event in
                       the Cloud Storage `object` format described here:
                       https://cloud.google.com/storage/docs/json_api/v1/objects#resource
        context (google.cloud.functions.Context): Metadata of triggering event.
    Returns:
        None; the output is written to Stackdriver Logging
    """

    print('Event ID: {}'.format(context.event_id))
    print('Event type: {}'.format(context.event_type))
    print('Bucket: {}'.format(event['bucket']))
    print('File: {}'.format(event['name']))
    print('Metageneration: {}'.format(event['metageneration']))
    print('Created: {}'.format(event['timeCreated']))
    print('Updated: {}'.format(event['updated']))

Go


// Package helloworld provides a set of Cloud Functions samples.
package helloworld

import (
	"context"
	"fmt"
	"log"
	"time"

	"cloud.google.com/go/functions/metadata"
)

// GCSEvent is the payload of a GCS event.
type GCSEvent struct {
	Kind                    string                 `json:"kind"`
	ID                      string                 `json:"id"`
	SelfLink                string                 `json:"selfLink"`
	Name                    string                 `json:"name"`
	Bucket                  string                 `json:"bucket"`
	Generation              string                 `json:"generation"`
	Metageneration          string                 `json:"metageneration"`
	ContentType             string                 `json:"contentType"`
	TimeCreated             time.Time              `json:"timeCreated"`
	Updated                 time.Time              `json:"updated"`
	TemporaryHold           bool                   `json:"temporaryHold"`
	EventBasedHold          bool                   `json:"eventBasedHold"`
	RetentionExpirationTime time.Time              `json:"retentionExpirationTime"`
	StorageClass            string                 `json:"storageClass"`
	TimeStorageClassUpdated time.Time              `json:"timeStorageClassUpdated"`
	Size                    string                 `json:"size"`
	MD5Hash                 string                 `json:"md5Hash"`
	MediaLink               string                 `json:"mediaLink"`
	ContentEncoding         string                 `json:"contentEncoding"`
	ContentDisposition      string                 `json:"contentDisposition"`
	CacheControl            string                 `json:"cacheControl"`
	Metadata                map[string]interface{} `json:"metadata"`
	CRC32C                  string                 `json:"crc32c"`
	ComponentCount          int                    `json:"componentCount"`
	Etag                    string                 `json:"etag"`
	CustomerEncryption      struct {
		EncryptionAlgorithm string `json:"encryptionAlgorithm"`
		KeySha256           string `json:"keySha256"`
	}
	KMSKeyName    string `json:"kmsKeyName"`
	ResourceState string `json:"resourceState"`
}

// HelloGCS consumes a GCS event.
func HelloGCS(ctx context.Context, e GCSEvent) error {
	meta, err := metadata.FromContext(ctx)
	if err != nil {
		return fmt.Errorf("metadata.FromContext: %v", err)
	}
	log.Printf("Event ID: %v\n", meta.EventID)
	log.Printf("Event type: %v\n", meta.EventType)
	log.Printf("Bucket: %v\n", e.Bucket)
	log.Printf("File: %v\n", e.Name)
	log.Printf("Metageneration: %v\n", e.Metageneration)
	log.Printf("Created: %v\n", e.TimeCreated)
	log.Printf("Updated: %v\n", e.Updated)
	return nil
}

Java

import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import functions.eventpojos.GcsEvent;
import java.util.logging.Logger;

public class HelloGcs implements BackgroundFunction<GcsEvent> {
  private static final Logger logger = Logger.getLogger(HelloGcs.class.getName());

  @Override
  public void accept(GcsEvent event, Context context) {
    logger.info("Event: " + context.eventId());
    logger.info("Event Type: " + context.eventType());
    logger.info("Bucket: " + event.getBucket());
    logger.info("File: " + event.getName());
    logger.info("Metageneration: " + event.getMetageneration());
    logger.info("Created: " + event.getTimeCreated());
    logger.info("Updated: " + event.getUpdated());
  }
}

Para obtener más información sobre cómo implementar funciones de Cloud Functions activadas por eventos de Cloud Storage, consulta Activadores de Cloud Storage y el Instructivo de Cloud Storage.

Parámetros de las funciones

Las funciones en segundo plano reciben argumentos que poseen datos asociados con el evento que activó la ejecución de la función. A continuación se describen los parámetros de este tipo de funciones:

Node.js

En los entornos de ejecución de Node.js, tu función recibe los argumentos (data, context, callback):

Propiedad Descripción Tipo
data El objeto de datos para el evento. Su tipo depende del evento. Objeto
context El objeto de contexto del evento. Objeto
context.eventId Un ID único para el evento. Por ejemplo: "70172329041928". String
context.timestamp La fecha/hora en la que se creó este evento. Por ejemplo: "2018-04-09T07:56:12.975Z". String (ISO 8601)
context.eventType El tipo de evento. Por ejemplo: "google.pubsub.topic.publish". String
context.resource El recurso que emitió el evento. Objeto
callback

Una devolución de llamada para indicar que la ejecución de la función se completó. Sigue la convención de “errback” que interpreta el primer argumento como un error.


callback();                    // Success
callback(null, 'Success!');    // Success
callback(1);                   // Error
callback(new Error('Failed')); // Error
Función

Python

En el entorno de ejecución de Python, tu función recibe los argumentos (data, context):

Propiedad Descripción Tipo
data Un diccionario que contiene los datos de un evento. Su formato depende del evento. Objeto de Cloud Storage o PubsubMessage
context El objeto de contexto del evento. Contexto
context.event_id Un ID único para el evento. Por ejemplo: "70172329041928". String
context.timestamp La fecha/hora en la que se creó este evento. Por ejemplo: "2018-04-09T07:56:12.975Z". String (ISO 8601)
context.event_type El tipo de evento. Por ejemplo: "google.pubsub.topic.publish". String
context.resource El recurso que emitió el evento. String

Go

En el entorno de ejecución de Go, tu función recibe los argumentos (ctx, Event):

Propiedad Descripción Tipo
ctx Un valor context.Context que transporta metadatos sobre el evento. Puedes recuperar los metadatos mediante el paquete cloud.google.com/go/functions/metadata. context.Context
Event

Un struct, cuyo tipo defines tú, en el que se deserializará la carga útil del evento en json.Unmarshal(). La carga útil del evento depende del activador para el cual se registró la función.

La definición de struct que proporciones en tu código debe corresponder a la estructura del tipo de evento. La estructura para cada evento se documenta en la página del activador del evento correspondiente.

Ten en cuenta que tu struct no es necesario para definir todos los campos contenidos en la carga útil. Quizás solo debes usar ciertos campos en tu función, en cuyo caso solo necesitas definir esos campos en tu struct. También puedes cambiar el nombre del campo (por ejemplo, cuando el nombre del campo JSON contiene un guion bajo) con etiquetas JSON en ese campo.

struct definido por el usuario

Java

En el entorno de ejecución de Java, tu función recibe los parámetros (event, context). Existen los siguientes dos tipos de funciones en segundo plano, BackgroundFunction<T> y RawBackgroundFunction:

Propiedad Descripción Tipo
event La carga útil del evento. El contenido de la carga útil depende del activador para el que se registró la función.

En el caso de BackgroundFunction<T>, el tipo de este parámetro es T, que es una clase definida por el usuario. La carga útil JSON del evento se deserializa en una instancia de esta clase con Gson.fromJson.

En el caso de RawBackgroundFunction, el tipo de este parámetro es String y corresponde a la carga útil JSON del evento.
Definida por el usuario o String
context Es un objeto Context de solo lectura que contiene metadatos sobre el evento. Context

Los datos del evento dependen del activador para el que se registró la función, por ejemplo, Pub/Sub o Cloud Storage. En el caso de funciones que se activaron de forma directa a través del comando gcloud functions call, los datos del evento contienen el mensaje que enviaste directamente.

Finaliza funciones en segundo plano

Si una función crea tareas en segundo plano (como subprocesos, promesas, devoluciones de llamada o procesos del sistema), debes finalizar o resolver estas tareas antes de regresar de tu función. Es posible que no se completen las tareas que no se finalicen antes de regresar de una ejecución en particular y causen un comportamiento indefinido.

Los entornos de ejecución de Node.js permiten que tus funciones proporcionen referencias a tareas en curso y pidan a Cloud Functions que las espere. Puede hacerlo de una de las siguientes maneras:

  • Muestra un Promise que se resuelve una vez que se complete la función.
  • Invoca el argumento callback en una función de devolución de llamada cuando finalice.

Próximos pasos