Saltar al contenido principal

Ejecutar una función

Objetivo​

Que algo ocurra sin que nadie guarde un registro: un recordatorio que se envía cada noche, un lote de registros que se ordena cada hora, un trabajo largo que se inicia a mano y se deja terminar. Y poder leer después exactamente qué hizo cada ejecución.

Por qué existe​

Todo lo demás que hacen los scripts de una solución empieza con el guardado de alguien: un paso de complemento se ejecuta dentro de una escritura, una API personalizada cuando otro sistema la llama. Pero cierto trabajo no pertenece a ninguna escritura: depende de una hora, o de un lote demasiado grande para que alguien espere.

Una función es un script de BS Lang que el servicio de funciones ejecuta por sí mismo, en su propio proceso y durante el tiempo que usted permita. Es un componente de su solución, como un formulario o un script: se escribe en Dev y viaja a Test y Production en el paquete de la solución.

Antes de empezar​

  • Una solución, con un editor.
  • Las tablas que su función leerá y escribirá.
  • Si llama a un servicio externo o envía correo, la variable de entorno que lo nombra — consulte Llamar a un servicio externo desde un script.

Pasos​

  1. Abra su solución, seleccione Funciones en la barra lateral y luego Nuevo.
  2. En la pestaña Script, escriba lo que hace la función. Puede leer y escribir registros y archivos, llamar a servicios externos e importar sus scripts de solución con import, lo mismo que un paso de complemento. El ojo al final de la barra de pestañas enumera todo lo que puede llamar.
  3. En la pestaña Configuración, dele un nombre para mostrar. El nombre lógico se rellena solo.
  4. Decida cuándo se ejecuta. Cualquier función puede ejecutarse a mano. Para que además se ejecute sola, marque Se ejecuta según una programación y elija un intervalo: cada 15 minutos, cada 6 horas, cada día. En una programación diaria puede fijar una hora y su zona horaria.
  5. Fije la duración máxima: cuánto puede durar una ejecución antes de detenerse. Por defecto son 15 minutos; como máximo, un día.
  6. Seleccione Guardar. Un script que no se puede analizar se rechaza ahora, con la línea que falla.
  7. Seleccione Ejecutar ahora. Se abre la pestaña Ejecuciones y sigue la ejecución: En cola, En ejecución y cómo terminó. Seleccione la ejecución para leer su registro.

Escribir un registro​

Nadie mira mientras una función se ejecuta, así que su registro es la forma de saber qué hizo.

var due = queryRecords('par_membership', 'par_reminder_state', 'due');
log('Reminders due: ' + toJson(due.length()));

for (var i: int = 0; i < due.length(); i++) {
updateRecord('par_membership', due[i].id, { par_reminder_state: 'sent' });
log(due[i]);
}
  • El texto se escribe tal cual, un número como usted lo escribiría y un registro o lista como JSON: log(due[i]) muestra el registro completo tal como lo vio la ejecución.
  • La pestaña Ejecuciones muestra las líneas mientras la ejecución sigue en marcha, con unos segundos de retraso.
  • Una ejecución conserva como máximo 5000 líneas; la última conservada dice que el registro está lleno.
  • Conservar líneas de registro, en la pestaña Configuración, desactiva el registro. log sigue funcionando y no conserva nada, así que nunca tendrá que editar el script para silenciarlo ni para volver a activarlo.

Terminar una ejecución a propósito​

stop('reason') termina la ejecución ahí, como un éxito que explica por qué:

if (due.length() == 0) {
stop('Nobody is due a reminder tonight.');
}

El resultado de la ejecución muestra esa frase. No es un fallo, y la lista no lo muestra como tal.

Iniciar una función desde un script​

Una función no necesita un reloj. Una Custom API, un paso de plugin u otra función puede iniciarla con startFunction, pasarle una entrada y recibir el identificador de la ejecución al instante: el trabajo ocurre después, en el servicio Functions. Así se responde en un momento a una solicitud que necesita una hora de trabajo.

// A Custom API: POST reports { "period": "2026-10" }
var run = startFunction('par_sales_report', { period: getInput('period') });
setStatus(202);
setOutput('run', run);
// The function
var asked = functionInput();
// … the long work …
setResult({ period: asked.period, total: total });
// A second Custom API: GET reports/runs/{run}
var run = functionRun(getInput('run'));
if (run == null) { setStatus(404); } else { setOutput('status', run.status); setOutput('report', run.result); }
  • startFunction(name, input) devuelve el identificador de la ejecución. La entrada —un registro, una lista, un valor o null— es lo que la función lee con functionInput(). Una ejecución iniciada por su programación o por Run now no tiene entrada y lee null.
  • setResult(value) es lo que la ejecución devuelve. Solo se conserva el último valor, y solo si la ejecución termina bien. Manténgalo pequeño —un resumen o la clave de un archivo—, porque se lee cada vez que alguien pregunta cómo va la ejecución.
  • functionRun(id) devuelve { id, function, status, outcome, result, queuedAt, startedAt, finishedAt }, o null si no existe esa ejecución.
  • Desde un paso de plugin, la ejecución se inicia dentro de la escritura: si la escritura se rechaza, la ejecución nunca empieza.
  • Las ejecuciones que inicia un script no están limitadas a una a la vez. Dos personas que piden a la vez obtienen dos ejecuciones. La regla de una a la vez es para la programación y Run now.
  • En la pestaña Runs, una ejecución así indica Cómo empezó: Un script, y al seleccionarla se ven su Entrada y su Resultado encima del registro.
  • Si la función no existe o está desactivada, startFunction detiene el script con el motivo, de modo que nunca se le dice al llamante que empezó un trabajo que no empezó.

Recibir aviso cuando termina​

Quien llama y prefiere no seguir preguntando puede recibir un aviso. startFunctionWithCallback es startFunction con un argumento más: el nombre de una variable de entorno que contiene la dirección a la que avisar. Cuando la ejecución termina —como sea que termine—, su resultado se envía allí una vez.

// A Custom API: POST totals
var run = startFunctionWithCallback('par_invoice_totals', null, 'par_totals_done');
setStatus(202);
setOutput('run', run);

Lo que llega:

{ "run": "…", "function": "par_invoice_totals", "status": "Succeeded",
"outcome": null, "result": { "invoices": 3, "total": 165.5 }, "finishedAt": "…" }
  • Nunca una URL en el script. El tercer argumento nombra una variable de entorno, igual que callService; un administrador decide a dónde apunta en cada entorno. Un nombre que la solución no declara detiene el script antes de que empiece nada.
  • Se envía una vez y no se reintenta. En la pestaña Ejecuciones, al seleccionar la ejecución se ve su Aviso al terminar y en qué quedó: Delivered (HTTP 200), el estado con que respondió el servicio, o por qué no se pudo llamar. Quien lo perdió aún puede leer la ejecución con functionRun.
  • El estado de la ejecución no depende de ello. Una ejecución que hizo su trabajo termina bien aunque el servicio al que debía avisar esté caído.

Escribir un archivo​

Una función puede escribir en el almacenamiento de objetos con las mismas llamadas que usa una Custom API — putFile, putFileAs, getFile, listFiles y deleteFile —, aunque nadie haya iniciado sesión mientras se ejecuta.

var key = 'orders/' + today() + '.csv';
putFileAs('par-order-exports', key, csv, 'text/csv');
setResult({ bucket: 'par-order-exports', key: key, rows: orders.length() });
  • El archivo va al almacenamiento de su organización y cuenta contra su cuota de almacenamiento. Una escritura que superaría la cuota hace fallar la ejecución.
  • En Administración → Almacenamiento el archivo figura como subido por function:<name>: lo escribió la función, no quien pulsó Ejecutar ahora.
  • Así una función devuelve algo más que un resumen: escriba los datos en un archivo y ponga su clave en el resultado.
  • Nada borra los archivos antiguos por usted. Una función que escribe uno cada noche debería borrar los que ya no necesita, como hace el ejemplo functions-nightly-export-to-storage.

Cómo termina una ejecución​

EstadoQué pasó
CorrectaEl script terminó o se detuvo con stop(...)
FallidaEl script lanzó un error, se rechazó una escritura, superó su duración máxima o el servicio se detuvo durante la ejecución. El resultado dice cuál
CanceladaAlguien pulsó Cancelar ejecución

Una ejecución fallida nunca se repite por usted. Una función puede tardar mucho, y repetir veintinueve minutos de trabajo sin que lo sepa sería peor que detenerse. Lea por qué falló, corrija lo necesario y pulse Ejecutar ahora.

Comprobar que funcionó​

  • La ejecución está Correcta y su registro dice lo que esperaba.
  • Abra un registro que la función cambió y mire su historial de auditoría: el cambio figura como hecho por la función, no por una persona. Una función se ejecuta como la plataforma, sin nadie detrás.
  • En una función programada, Próxima ejecución en la pestaña Configuración es la próxima vez que se ejecutará sola.

Conviene saber​

  • Una ejecución cada vez. Mientras una está en cola o en ejecución, «Ejecutar ahora» se rechaza y una programación que vence se omite hasta la siguiente. Una pasada nocturna que se alargó nunca empieza dos veces sobre los mismos registros.
  • «Ejecutar ahora» ejecuta lo guardado y no está disponible con cambios sin guardar.
  • Desactivada es desactivada. Una función desactivada no se ejecuta según su programación ni a mano.
  • Cambiar el script no mueve la programación; cambiar la programación sí.
  • Cancelar ejecución detiene un script en pocos segundos, incluso un bucle que no toca ningún registro.
  • Cada función conserva sus 200 ejecuciones más recientes.

Solución de problemas​

SíntomaCausa probableSolución
Ejecutar ahora está atenuadoCambios sin guardar, o la función está desactivadaGuarde; actívela
Esa función ya se está ejecutandoHay una ejecución en cola o en marchaEspere, o selecciónela y Cancelar ejecución
Fallida: Stopped after … minutesSuperó su duración máximaAumente la duración máxima, o haga que cada ejecución haga menos
Fallida porque el servicio se detuvo durante ellaEl servicio se reinicióVuelva a ejecutarla
El registro está vacíoConservar líneas de registro está desactivado, o el script no llama a logActívelo; añada log(...)
La ejecución falló: There is not enough storage leftLa cuota de almacenamiento de la organización está agotadaBorre los archivos que ya no necesite o mejore el plan
La ejecución falló: Object storage is not configured for the Functions serviceLa instalación no dio al servicio de funciones la configuración de almacenamientoConsulte a su administrador

Véase también​