Esta es la primera de una serie de varias partes para aprovechar la Servicio de eventos Couchbase para ejecutar múltiples tareas programadas a intervalos recurrentes específicos en un cron completamente dentro de la base de datos sin necesidad de infraestructura adicional a través de una única función de eventos de uso general.

En esta entrega, nos centraremos en la ejecución de rutinas fijas de usuario, funciones JavaScript definidas dentro de una función de eventos.

En artículos posteriores ampliaremos la cron como Eventing Function para programar y ejecutar sentencias N1QL dinámicas manejadas por la base de datos y finalmente exploraremos la programación de funciones JavaScript dinámicas manejadas por la base de datos.

Fondo

El servicio de eventos de Couchbase proporciona un marco para escribir tus propias rutinas, simples funciones JavaScript, para procesar los cambios en los documentos. Este servicio proporciona toda la infraestructura necesaria para crear funciones escalables y robustas basadas en la nube, permitiéndote centrarte en desarrollar pura lógica de negocio para interactuar casi en tiempo real con los cambios en tus datos. Tus funciones pueden acceder al servicio de datos de Couchbase (KV), al servicio de consultas de Couchbase (N1QL) y a puntos finales REST externos al sistema Couchbase.

Eventing Life Cycle 6.5 I/O

En JSON modelo de datos de Couchbase procede de JavaScriptPor lo tanto, es natural que el servicio de eventos ofrezca la posibilidad de escribir código JavaScript para analizar y manipular documentos JSON en cualquier tipo de evento de cambio, incluyendo inserciones, actualizaciones, fusiones y eliminaciones (denominadas conjuntamente mutaciones).

Las funciones de eventos normalmente le permiten desplegar y ejecutar fragmentos de código personalizados para que reaccionen a miles e incluso millones de mutaciones por segundo en sus documentos. Algunos casos de uso típicos son documentado para desarrollar Funciones Eventing de alta velocidad a escala que respondan a mutaciones de documentos Couchbase.

Eventing Life Cycle 6.5

Este artículo se centrará más bien en un caso de uso de muy baja velocidad del Servicio de Eventos construyendo un crontab distribuido fiable "en base de datos", permitiéndote ejecutar funciones JavaScript que interactúan con servicios Couchbase en un horario periódico regular.

Programación de la lógica empresarial para que se ejecute en una fecha u hora determinadas

Cronque lleva el nombre de "Chronos," la palabra griega para el tiempo es una de las utilidades más útiles en un sistema Linux. En Linux el cron está controlada por un archivo crontab (tabla cron), un archivo de configuración que especifica los comandos del shell que se ejecutarán periódicamente en un horario determinado.

Uno de los inconvenientes cron es que no está diseñado para ser un servicio distribuido; se ejecuta en una sola caja, por lo que presenta un único punto de fallo. Si el sistema está fuera de línea durante varias horas, se pierden todas las tareas programadas.

Sí, hay algunos distribuidos cron como Google's Cloud Service, AWS' Scheduled Tasks, y Azure Functions / Time Triggers. Pero las ofertas de cada proveedor de nube tienen sus propios modismos que no son directamente portables.

Además, es necesario asegurar la metodología de configuración y control, por ejemplo si se controla una cron a través de una API REST sobre HTTP/S, deberá tenerlo en cuenta en su plan de seguridad.

Utilizar el propio Couchbase para ejecutar comandos periódicos

Con una pequeña cantidad de código y planificación, puede aprovechar el servicio Eventing de Couchbase para proporcionar cron para las operaciones o el mantenimiento programados de la base de datos. La integración del programador en la base de datos permite obtener las siguientes ventajas:

  • Portabilidad a través de proveedores Cloud, si reubicas tu cluster de Couchbase tu planificador no se ve afectado.
  • Soporte, si utiliza Couchbase tiene un único proveedor para proporcionarle soporte y otros servicios.
  • Distribuido, no hay un único punto de fallo y todos los servicios de Couchbase admiten réplicas distribuidas.
  • Ejecución garantizada, su tarea se ejecuta incluso después de recuperarse de un fallo de nodo.

Programación de Couchbase, los temporizadores son la salsa secreta

Los temporizadores son construcciones del servicio de eventos de Couchbase mediante las cuales los desarrolladores pueden especificar una rutina (lógica de negocio) que se activará en un momento futuro. Utilizaremos esta funcionalidad para implementar un Couchbase configurable puro. crontab que le permite activar tareas repetitivas como parte de sus flujos de trabajo, tanto si necesita ejecutar una simple consulta N1QL como construir un complejo motor de reglas.

En todos los diseños posteriores limitaremos nuestra cron a una resolución de 15 segundos o más. Tenemos esta limitación porque, aunque los temporizadores se escalan a millones y se garantiza que se disparan y ejecutan, no son precisos como un reloj de pared y actualmente tienen un retardo de estado estacionario limitado a menos de 14 segundos. [1].

Por supuesto, si necesita una programación más ajustada, es decir, menos de 15 segundos, entonces simplemente debe procesar la mutación en sí en la lógica de eventos sin el uso de una construcción de temporizador para programar una llamada de vuelta en el futuro.

En el momento de escribir estas líneas, la versión actual de Couchbase es la 6.5.1 que dos limitaciones con las que debemos trabajar al hacer un robusto cron sistema.

  1. En las versiones 5.5.x, 6.0.x y 6.5.x, una función invocada por una llamada de retorno de un temporizador no puede crear un nuevo temporizador de forma fiable (se puede solucionar mediante una segunda función cooperativa).
  2. En las versiones 6.5.x, la creación de temporizadores en el futuro (como en una hora o más) en un sistema por lo demás inactivo puede dar lugar a un número creciente de operaciones de cubo de metadatos que eventualmente pueden bloquear las mutaciones para una función de Eventing dada (en 6.5.X se puede lograr una solución en el espacio de usuario a través de una segunda función cooperativa). La gravedad se rige por:
    • El número de vBuckets que mantienen un temporizador activo. Por lo tanto, si solo hay unos pocos temporizadores en el futuro, es posible que el problema no se note o no se materialice.  Este es el caso con sólo unos pocos cron horarios, pero para completar en caso de añadir la funcionalidad de la fecha puse en una solución para este problema para el código suministrado en este artículo.
    • Si un temporizador de Eventing se ha disparado recientemente en un vBucket (lo que soluciona el problema para el vBucket en cuestión por función). Por lo tanto, los sistemas con mucha actividad de temporizadores a corto plazo no experimentarán este problema aunque los temporizadores estén programados para un futuro lejano.

Afortunadamente, en la versión 6.6.0 ambos problemas o restricciones se han eliminado y se puede crear un programador en una única y sencilla Función de Eventos unificada.

Eventing cron update

Requisitos previos

En este artículo utilizaremos la última versión de GA, es decir, la versión 6.5.1 de Couchbase (puede que tengas que hacer algunos cambios en las funciones de eventos descritas para versiones anteriores de Couchbase). El ejemplo de este artículo se ejecutará contra el conjunto de datos travel-sample que se entrega con el servidor Couchbase.

CONSEJO PROFESIONAL: Sólo para usuarios avanzados, si estás familiarizado con Couchbase Eventing y también con nuestras herramientas CLI / REST puedes saltarte la mayor parte de este blog y descargar un archivo ZIP para configurar y ejecutar rápidamente el sistema programador que se presenta a continuación. Haz clic con el botón derecho en el siguiente enlace y selecciona Guardar enlace como para descargar el archivo  cron_impl_2func_CLI.zip, muévalo a un nodo Eventing, extraiga el archivo ZIP y consulte el archivo README.txt extraído.

Sin embargo, si usted no está familiarizado con Couchbase o el servicio Eventing por favor camine a través de GET STARTED y un ejemplo Eventing específicamente se refieren a los siguientes:

  • Configure un servidor Couchbase 6.5.1 que funcione según las instrucciones de Comience aquí
  • Asegúrese de que puede ejecutar una consulta N1QL en la base de datos viaje-muestra según las instrucciones de Ejecute su primera consulta N1QL.
  • Comprender cómo desplegar una función básica de Eventing según las instrucciones de la sección Archivo de documentos que también utiliza viaje-muestra conjunto de datos.
  • Asegúrese de tener la viaje-muestra en la vista de cubos de la interfaz de usuario.
  • Asegúrese de que un cubo llamado metadatos en la vista Buckets de la interfaz de usuario debe tener un tamaño mínimo de 200 MB.
  • En la vista Buckets de la interfaz de usuario, cree un bucket llamado crondata con un tamaño mínimo de 200 MB. Para obtener información detallada sobre cómo crear cubos, consulte Crear un cubo.
  • Establecer allow_interbucket_recursion a verdadero para permitir que dos (2) funciones de Eventing modifiquen el mismo documento KV [2].

Implementación #1, programación tipo "cron" codificada.

Para nuestra primera implementación, por ejemplo la Parte 1 de la serie, diseñaremos una estructura de control simple que es simplemente un documento KV JSON y también dos (2) Funciones Eventing que responderán y actuarán sobre la información en la estructura de control.

A continuación se muestra un diseño de un documento JSON, o estructura de control, que nos permitirá tener múltiples "eventos" programados. Cada evento programado tendrá su propio documento de control con una CLAVE única como recurring_event::1, recurring_event::1, ... recurring_event::N. La propia estructura JSON contiene información para "reconstituir la clave", ya que nuestro sistema de programación responderá a los cambios o actualizaciones (mutaciones) de los documentos de control, como alternar el estado "activo" para activar o desactivar la acción o cambiar el campo "verbose" que controla la cantidad y el estilo del registro.

A continuación se muestra un ejemplo de documento de control con CLAVE evento_recurrente::1 que ejecutará la función JavaScript doCronActionA a las 14:54 (14:30) todos los días.

Registro de control JSON Descripción
{
   "type": "recurring_event", La CLAVE será <>::<>.
   "id":1,
   "hora":14, La hora del día 0-23, *, *2X, *4X para activar
   "min":54, El minuto en la hora 0-59, *, *2X, *4X para activar
   "acción": "doCronActionA", Función JavaScript que se ejecutará cuando se active el temporizador
   "activo":true, Bandera para activar o desactivar este horario
   "verbose": { [OPCIONAL] control de registro
      "user_func":2, Nivel de registro para la lógica de acción : 0=ninguno, etc. etc.
      "programador":3 Nivel de registro para la lógica cron : 0=ninguno, etc. etc.
   },
   "dinámico": { control y estadísticas del sistema [DINÁMICO
      "estado": "brazo", "armar"|"rearmar"|"pendiente" cualquier valor != "pendiente" iniciar una programación
      "next_sched": 0, Número de segundos transcurridos desde la época hasta el siguiente horario deseado
      "prev_sched": 0, Número de segundos transcurridos desde la fecha de la programación anterior
      "prev_etime": 0, Número de segundos transcurridos desde la época para el tiempo de ejecución real del programa anterior
      "prev_delay": 0, Número de segundos que el temporizador se ha retrasado con respecto a la programación
      "prev_atime": 0 Número de segundos que ha tardado el usuario 'acción'
   }
}

Como Linux tradicional crontab puede establecer la hora y el minuto en números enteros legales, y también puede establecer hora a "*" para procesar todas las horas o ajuste min a "*" para procesar todos los minutos.

Aunque no apoyaremos la crontab sintaxis admitimos dos configuraciones no estándar, a saber, si fijar ambos hora y min a "*4X" ejecutaremos y rearmaremos cuatro (4) veces por minuto y si los configuras ambos a "*2X" ejecutaremos y rearmaremos dos (2) veces por minuto. A continuación se muestra una tabla de horarios soportados con su descripción:

hora min Los valores pueden ser números o cadenas
13 32 Corre a las 13:32 (o 13:32)
* 15 Se ejecuta cada hora a los 15 minutos
8 12 Corre una vez al día a las 8:32 (o 8:32 am)
* * Ejecutar una vez por minuto
*2X *2X Se ejecuta dos veces por minuto - requiere que tanto la hora como el minuto estén ajustados a "*2X".
*4X *4X Funciona cuatro veces por minuto - requiere que la hora y el minuto estén ajustados a "*2X".

Eventualmente utilizaremos el Query Workbench para insertar el cron documentos de control, todos los cuales deben tener una CLAVE única de evento_recurrente::# a una hora de ejecución programada de 14:54 ( 2:54 pm), para la acción doCronActionA, podríamos utilizar la siguiente sentencia N1QL.

No te preocupes por ejecutar ninguna sentencia N1QL en este momento, realizaremos las sentencias N1QL más tarde después de haber construido y desplegado nuestra Función de Eventos.

Puede crear un registro (o registros) de control en el cubo viaje-muestray luego listarlo, armarlo, desarmarlo, ajustar el horario que sigue, cambiar el nivel de verbosidad para el registro, o borrarlo de la siguiente manera:

Acción Declaración N1QL
Crear un calendario INSERTAR EN viaje-muestra (CLAVE,VALOR) VALORES (
"recurring_event::1", {
"type": "recurring_event",
"id":1,
"hora": "14″,
"min": "54″,
"acción": "doCronActionA",
"activo":true
}
);
Crear un índice para consultar datos sin especificar claves CREAR un índice primario sobre crondata ;
Mostrar todos los horarios ordenados por id SELECT * FROM crondata WHERE type="recurring_event" order by id ;
Mostrar horario específico SELECT * FROM crondata WHERE type="recurring_event" AND id=1 ;
Armar o activar ACTUALIZACIÓN crondata SET active = true WHERE type="recurring_event" AND id=1 ;
Desarmar o desactivar ACTUALIZACIÓN crondata SET active = false WHERE type="recurring_event" AND id=1 ;
Ajustar el tiempo de activación ACTUALIZACIÓN crondata SET hora = 11, min = 30 WHERE type="recurring_event" AND id=1 ;
Ajustar el registro de la "acción ACTUALIZACIÓN crondata SET verbose.user_data = 0 WHERE type="recurring_event" AND id=1 ;
Ajustar el registro de la lógica del programador ACTUALIZACIÓN crondata SET verbose.scheduler = 0 WHERE type="recurring_event" AND id=1 ;
Borrar el horario DELETE FROM crondata WHERE type="recurring_event" AND id=1 ;

Supongamos que tenemos cuatro (4) horarios activos, la ejecución de la primera sentencia N1QL, por encima de la lista de todos ellos, por ejemplo.

Devolvería algo como la siguiente salida (vista de tabla en el Query Workbench):

activo acción hora id min programador tipo usuario_func
verdadero "doCronActionA" 14 1 54 1 "evento_recurrente" 2
verdadero "doCronActionB" * 2 * 1 "evento_recurrente" 1
verdadero "doCronActionC" *2X 3 *2X 4 "evento_recurrente" 4
verdadero "doCronActionD" * 4 0 0 "evento_recurrente" 1

En la tabla anterior tenemos cuatro acciones: la primera se ejecuta una vez al día, la segunda cada minuto, la tercera cada 30 segundos y la cuarta cada hora. En una próxima entrega de esta serie añadiremos la función "día de la semana".

El objeto anidado "verbose"si no se suministra será por defecto { "user_func":1, "scheduler":1 } indicando un nivel de registro bajo o escueto para la función de acción y también para la lógica de programación. Un valor de 0 suprimirá todos los mensajes de registro, es decir, doCronActionD, mientras que valores mayores serán más verbosos, es decir, como se define en doCronActionC.

El objeto anidado "dinámico" si normalmente nunca se suministra y será por defecto { "state": "arm", "next_sched": 0, "prev_sched": 0, "prev_etime": 0, "prev_delay": 0, "prev_atime": 0 } este es un bloc de notas para la programación lógica de eventos en ejecución y también proporciona estadísticas útiles sobre los tiempos de ejecución, por lo que debe ser tratado como de sólo lectura.

En este punto tenemos un diseño de control de alto nivel, pero necesitamos lógica para procesar nuestras estructuras de control, aquí es donde el Servicio de Eventos de Couchbase, específicamente una Función de Eventos entra en juego.

Funciones del concurso

Este diseño requiere dos (2) funciones de Eventing: una función JavaScript principal "cron_impl_2func_651" y una pequeña función JavaScript de ayuda "cron_impl_2func_651_help". Discutiremos cada sección de las funciones JavaScript que comprende la implementación inicial combinada de código JavaScript de casi 610 líneas (con aproximadamente 44% de las líneas son comentarios y espacios en blanco)

No te preocupes por hacer un cortar y pegar en este momentoComo más tarde voy a proporcionar un enlace para descargar (para la importación) las dos funciones de eventos necesarios y todos los ajustes necesarios en dos archivos llamados "cron_impl_2func_651.json" "cron_impl_2func_651_help.json" y también si lo prefiere las dos funciones unificadas completo que se puede cortar y pegar directamente.

Nuestra función principal de eventos "cron_impl_2func_651" estará compuesta por nueve (9) funciones JavaScript

  • Tres (3) funciones de lógica empresarial (dos de las cuales están vacías).
    • doCronActionA(doc) - una acción de usuario de ejemplo N1QL a ejecutar
    • doCronActionB(doc) - un intérprete de comandos de acción de usuario vacío para experimentos
    • doCronActionC(doc) - un intérprete de comandos de acción de usuario vacío para experimentos
  • Un (1) punto de entrada para concursos completos.
    • OnUpdate(doc, meta) - el punto de entrada estándar de Eventing para Inserciones o Actualizaciones
  • Uno (1) cron analizador sintáctico para generar la siguiente programación.
    • getNextRecurringDate(hour_str, min_str) - lógica cron para encontrar la siguiente Fecha programada
  • Tres (3) funciones de apoyo para comprobar que la lógica de negocio existe o formatear resultados.
    • verifyFunctionExistsViaEval(curDoc, id) - asegurarse de que tenemos una función que ejecutar
    • toNumericFixed(number, precision) - formatea un flotante a un estilo compacto
    • toLocalISOTime(d) - formatea una fecha a un estilo compacto
  • Una (1) función callback cuando se ejecutan los temporizadores.
    • Callback(doc) - una función de devolución de llamada para temporizadores programados

Nuestra función de ayuda para eventos "cron_impl_2func_651_help" estará compuesta por una (1) función JavaScript

  • Un (1) punto de entrada para concursos completos.
    • OnUpdate(doc, meta) - el punto de entrada estándar de Eventing para Inserciones o Actualizaciones

En las secciones siguientes recorreremos cada una de las funciones JavaScript anteriores.

Necesitamos una función JavaScript, por ejemplo, la lógica de negocio para ejecutar en un horario periódico.

Lo primero que queremos es una rutina o función que contenga nuestra lógica de negocio que ejecutaremos basándonos en nuestras reglas crontab. Llamaremos al método JavaScript doCronActionA(doc)sin embargo, puede llamarse como se quiera, por ejemplo doPeriodicLedgerBalance(doc), los únicos requisitos para nuestras funciones de "acción" que implementan nuestra lógica de negocio programada son los siguientes:

  • Tiene un parámetro: doc, un documento de control como el descrito anteriormente de type="recurring_event".
  • El nombre real de JavaScript coincide con el campo "acción" del documento de control.
  • Devuelve verdadero sobre el éxito y falso sobre el fracaso
  • Utiliza doc.verbose.user_func para controlar el registro si 0 es silencioso, si 1 emite una sola línea, si 2 emite cualquier información de registro que se necesite para depurar la función, etc. etc..

Escribiremos nuestra función doCronActionA(doc)para ejecutar una consulta N1QL incrustada ) para combinar los recuentos de líneas aéreas por país y, a continuación, crear un único documento KV con los datos calculados.

En mi sistema de prueba un pequeño nodo único noMDS (ejecutando todos los servicios de Couchbase) el N1QL anterior tarda unos 20 ms. (para mayor claridad fingir que es supercomplejo tarda 10 segundos en completarse).

La idea aquí es que el documento KV final calculado y resumido pueda ser cargado rápidamente por 100K (o un millón) de mutaciones Eventing por segundo sin la sobrecarga adicional de comunicación con los nodos del servicio de Consulta y de procesar sentencias N1QL en cada mutación.

Debería ser obvio que el objetivo de esta lógica de negocio en particular, doCronActionA(doc)es crear una caché semiestática que se actualice periódicamente según un calendario.

Todo lo que estamos haciendo realmente (y es bastante rápido) es obtener un recuento de aerolíneas por país a partir del conjunto de documentos de la muestra de viajes. A medida que usamos N1QL construimos un documento y eventualmente lo escribimos en KV como un documento resumido. El punto clave a destacar aquí es que no queremos repetir el mismo trabajo para millones de mutaciones cada uno, sobre todo porque algunos cálculos podrían tomar 10 segundos de tiempo de cálculo del servicio de consulta cada vez que iniciamos una consulta N1QL incrustada desde una función Eventing.

A continuación mostramos la función JavaScript que queremos que se ejecute una vez al día (o quizás una vez cada hora, etc.). Observa que el nombre de la función coincide con el nombre del campo de acción de la estructura de control. Para más detalles sobre la terminología de Eventing y las construcciones del lenguaje, consulta los documentos y ejemplos de Couchbase en Servicio de Eventing: Fundamentos.

La función anterior simplemente 1) consulta el cubo de muestras de viajes para extraer datos, en este caso el recuento de aerolíneas para cada país, 2) crea un nuevo documento KV y una nueva clave y lo escribe en el cubo de muestras de viajes para su uso posterior.

Además, como parte de este ejemplo hemos construido un registro que responde a un ajuste numérico de verbosidad que a) registra una sola línea si el documento de control tiene un valor para doc.verbose.user_func == 1 o b) emite más información si el valor de doc.verbose.user_func >= 2.

Se trata de un marco genérico que puede ejecutar una (1) cron acción o incluso mil (1000) de cron acciones. Como tal, he proporcionado dos funciones adicionales "vacías" - como se señaló antes, podrían haber sido nombradas de cualquier manera.

y

Estas funciones doCronActionB y doCronActionC son triviales, ya que simplemente registran información en el registro de la aplicación de eventos de la función de eventos. Consulte Funciones de registro para más detalles. Por supuesto, necesita un documento de control de type="recurring_event" con active=true y una acción como action = "doCronActionB" para habilitarlos y ejecutarlos realmente.

Necesitamos un punto de entrada o manejador de eventos

A partir de la versión 6.5, el servicio de eventos admite dos puntos de entrada o controladores OnUpdate(doc, meta) y OnDelete(meta) sólo nos interesa el OnUpdate(doc,meta) para este ejemplo.

En OnUpdate(doc,meta) es llamado cuando se crea o modifica (muta) cualquier documento del bucket de origen y filtra inmediatamente los documentos que no interesan. [3]

La clave aquí es que el cron en nuestro manejador sólo se preocupa por los documentos que tienen doc.type de "recurring_event y también un doc.active de true. Además, en este ejemplo hemos creado un rastreo para el método cron lógica de mantenimiento que sólo se registra en el registro de la aplicación si el documento de control tiene un valor para doc.verbose >= 3.

Si sólo ejecuta unas pocas programaciones, puede desactivar el trabajo en el espacio de usuario o "arreglo para 6.5.X cubo creciente ops" comentando cuatro líneas de código en el bloque OnUpdate anterior para "cron_impl_2func_651" como sigue:

Necesitamos código para solucionar posibles operaciones de crecimiento de cubos para 6.5.X

A partir de la versión 6.5.X necesitamos un "arreglo para 6.5.X cubo creciente ops"que ocurre en sistemas inactivos con muchos temporizadores programados en el futuro. Este código garantiza que un temporizador de Eventing se ha disparado recientemente en un vBucket (lo que soluciona el problema para el vBucket dado en función de cada función).

 Necesitamos una utilidad para calcular la siguiente hora en el horario

La siguiente función getNextRecurringDate(hour, min) determinará una hora para ejecutar la acción definida como parte de nuestra programación. Esto no es una implementación completa de cronEn lugar de ello, contiene las características estándar clave para ejecutarse una vez al día, una vez por hora y una vez por minuto. También contiene alguna sintaxis no estándar para proporcionar la capacidad de ejecutar dos veces por minuto o cuatro veces por minuto.

Como se ha descrito anteriormente, la función getNextRecurringDate(hora, min) permite lo siguiente (la tabla se duplica a continuación), siendo las dos últimas no estándar.[4]

hora min Los valores pueden ser números o cadenas
13 32 Corre a las 13:32 (o 13:32)
* 15 Se ejecuta cada hora a los 15 minutos
8 12 Corre una vez al día a las 8:32 (o 8:32 am)
* * Ejecutar una vez por minuto
*2X *2X Se ejecuta dos veces por minuto - requiere que tanto la hora como el minuto estén ajustados a "*2X".
*4X *4X Funciona cuatro veces por minuto - requiere que la hora y el minuto estén ajustados a "*2X".

A continuación se muestra una implementación de la lógica necesaria para determinar la próxima vez que debe activarse un temporizador de Eventing en nuestro programa, en el caso de que la lógica de usuario de nuestro primer ejemplo doCronActionA(doc) no se completa a tiempo, por ejemplo, si se sobrepasa el tiempo real, se seleccionará el siguiente cuanto de la programación. Tenga en cuenta tanto los Temporizadores como sus Funciones Padre. Así, si una Función de Eventos tiene un tiempo de espera de ejecución por defecto de 60 segundos, si es necesario esta configuración puede ser ajustada o aumentada.

Necesitamos algunas pequeñas utilidades

La función de utilidad común que simplemente comprueba si nuestro JavaScript existe utilizado por ambos OnUpdate(doc,meta), mostrado arriba, y el temporizador Devolución de llamada(doc), que se muestra más adelante. A continuación verifyFunctionExistsViaEval(curDoc, id) que recibe dos argumentos: un documento de control JSON y la CLAVE de dicho documento.

Esto nos permite saber inmediatamente, en el despliegue, si hubo un problema con una falta de coincidencia de nombres entre el documento de registro de control JSON y el nombre real de la función de lógica de negocio en el código JavaScript.

Tenga en cuenta que si se intenta ejecutar una función inexistente, el usuario final recibirá una advertencia en el registro de la aplicación. cron_impl_2func_651.log  para corregir el problema.

2020-04-22T16:20:38.725-07:00 [INFO] "Advertir/Desactivar (Sin Acción y Sin Rearmar), porque la 'acción' requerida de doCronMyNewFunction(doc) no existe, id es" "recurring_event::1"

Esta corrección se puede hacer a través de una Pausa/Reanudar añadiendo la función y luego ajustando el documento de control con el id especificado o CLAVE (a través de un toggle activo a falso y luego verdadero) -o- ajustando el documento de control para apuntar a una función existente en su manejador.

A continuación, la utilidad toNumericFixed(número, precisión) sólo permite un bonito formato compacto de flotantes para nuestros mensajes de registro.

Por último, la utilidad toLocalISOTime(d) sólo permite un formato compacto de fechas para nuestros mensajes de registro.

Necesitamos una llamada de retorno del temporizador para ejecutar la lógica de usuario y volver a activar el temporizador

La última función JavaScript de "cron_impl_2func_651" es la llamada de retorno del temporizador, a la que se llama cuando se activa el temporizador programado. La función de devolución de llamada debe ser una función de nivel superior que reciba un único argumento, el contexto.

En este caso en nuestro manejador OnUpdate referenciamos una función JavaScript de Devolución de llamada(doc) con un contexto de doc (nuestro documento de control del planificador activo de type="recurring_event")

En la versión 6.6 podemos crear otro temporizador dentro de un temporizador pero para todas las versiones anteriores necesitaremos lanzar una mutación a una función "helper" (evitamos cuidadosamente la recursión infinita). En la 6.6 la función helper no es necesaria y la lógica se ha simplificado sustancialmente.

Necesitamos una función de ayuda para desencadenar una nueva mutación

Dado que antes de la versión 6.6 (que aún no se ha publicado) no se puede crear un temporizador desde la llamada de retorno de un temporizador en ejecución, necesitamos una segunda función de eventos (junto con "allow_interbucket_recursion":true) para activar una mutación de forma que podamos generar todos nuestros temporizadores en el punto de entrada OnUpdate(doc,meta) de la función de eventos principal. Hacemos esto de la siguiente manera:

  1. cron_impl_2func_651 OnUpdate(doc,meta) recibe una mutación, programa un temporizador
  2. cron_impl_2func_651 Después de una cantidad de tiempo cuando el temporizador madura el Devolución de llamada(doc) se ejecuta la rutina, primero ejecuta la acción de usuario deseada y luego crea una mutación #1 en el documento de control (que no es vista por la Función creadora para evitar la recursividad)
  3. cron_impl_2func_651_help OnUpdate(doc,meta) recibe una mutación, hace otra mutación #2 en el documento de control esto desencadena 1. anterior en un ciclo sin fin.

Nota, en la versión 6.6 de Couchbase no necesitamos una función de ayuda en absoluto porque se te permite crear un temporizador desde dentro de un temporizador en ejecución. Esto simplifica enormemente la lógica necesaria para hacer un cron sistema[2].

La única función JavaScript en "cron_impl_2func_651_help" OnUpdate(doc,meta) se muestra a continuación.

La función helper necesita algunas utilidades

Estas utilidades proporcionan un arreglo para 6.5.X cubo creciente ops asegurándose de que se dispara un temporizador de eventos en cada vBucket en el momento oportuno.

Ahora vamos a desplegar las dos Funciones Eventing

Hemos revisado mucho código y el diseño del planificador inicial, ahora es el momento de ver cómo funciona todo junto.

Recuerde que en este ejemplo hay tres cubos muestra-viaje (un ejemplo de conjunto de datos por defecto), metadatos(el cubo de metadatos es un bloc de notas para Eventing y puede compartirse con otras funciones de Eventing) y, por último, la función crondata (que contiene nuestros cronogramas). La dirección viaje-muestra tiene un tamaño de 100 MB y los otros dos cubos metadatos y crondata deben tener un tamaño de 200 MB y existir ya según las instrucciones de "Requisitos previos".

  • Verifique la configuración actual de su cubo accediendo a la página Consola Web de Couchbase > Cubos página:Eventing cron update

Para desplegar la función Eventing "cron_impl_2func_651"puede seguir uno de estos dos métodos:

  • Complejidad básica, Método #1 Descargar/Importar
  • Complejidad media, Método #2 Añadir función manualmente, Cortar y pegar JavaScript

Método #1 Descargar/Importar

Importar la 1ª función "cron_impl_2func_651"

Descargue la primera función Eventing con todos los ajustes necesarios, haga clic con el botón derecho del ratón en el siguiente enlace y seleccione Guardar enlace como para descargar el archivo cron_impl_2func_651.json en tu sistema de archivos local.

Desde el Consola Web de Couchbase > Eventos haga clic en IMPORTARnavega hasta el archivo cron_impl_2func_651.jsonselecciónelo y ábralo. La página AÑADIR FUNCIÓN aparece el cuadro de diálogo.

En el AÑADIR FUNCIÓN para cada uno de los elementos de la función, facilite la siguiente información. Tenga en cuenta el archivo JSON cron_impl_2func_651.json preconfigurará todos los ajustes correctamente para este ejemplo:

  • Para el Cubo de origen y compruebe que está en crondata.
  • Para el Cubo de metadatos y compruebe que está en metadatos.
  • Compruebe que cron_impl_2func_651 es el nombre de la función que está creando en el campo Nombre de la función cuadro de texto.
  • [Paso opcional] Introduzca el texto Un programador cron parte 1en el Descripción cuadro de texto.
  • Para el Ajustes utilice los valores por defecto.
  • Para el Fijaciones verifique que existen dos enlaces.
  • Para la vinculación, el "alias de cubo", especifica cron_bkt como "nombre alias" del cubo, y seleccione
    crondata como cubo asociado, y el modo debe ser "lectura y escritura".
  • Para la vinculación, el "alias de cubo", especifica ts_bkt como "nombre alias" del cubo, y seleccione
    viaje-muestra como cubo asociado, y el modo debe ser "lectura y escritura".
  • La configuración en el cuadro de diálogo debe ser como la siguiente:
    Eventing cron update
  • Después de verificar toda la información requerida en el cuadro de diálogo AÑADIR FUNCIÓN, haga clic en Siguiente: Añadir Código. Aparecerá la página cron_impl_2func_651 (con el código JavaScript precargado).
    Eventing cron update
  • Para volver a la pantalla de Eventos, pulse el botón '< volver a Concurso completo(debajo del editor) o haga clic en el enlace Eventos ficha.

Importar la 2ª Función "cron_impl_2func_651_help"

Descargue la segunda función Eventing con todos los ajustes necesarios, haga clic con el botón derecho del ratón en el siguiente enlace y seleccione Guardar enlace como para descargar el archivo cron_impl_2func_651_help.json en tu sistema de archivos local.

Desde el Consola Web de Couchbase > Eventos haga clic en IMPORTARnavega hasta el archivo cron_impl_2func_651_help.jsonselecciónelo y ábralo. La página AÑADIR FUNCIÓN aparece el cuadro de diálogo.

En el AÑADIR FUNCIÓN para cada uno de los elementos de la función, facilite la siguiente información. Tenga en cuenta el archivo JSON cron_impl_2func_651_help.json preconfigurará todos los ajustes correctamente para este ejemplo:

  • Para el Cubo de origen y compruebe que está en crondata.
  • Para el Cubo de metadatos y compruebe que está en metadatos.
  • Compruebe que cron_impl_2func_651_help es el nombre de la función que está creando en el campo Nombre de la función cuadro de texto.
  • [Paso opcional] Introduzca el texto Un ayudante cron como programador parte 1en el Descripción cuadro de texto.
  • Para el Ajustes utilice los valores por defecto.
  • Para el Fijaciones verifique que sólo existe un enlace.
  • Para la vinculación, el "alias de cubo", especifica cron_bkt como "nombre alias" del cubo, y seleccione
    crondata como cubo asociado, y el modo debe ser "lectura y escritura".
  • La configuración en el cuadro de diálogo debe ser como la siguiente:
    Eventing cron update
  • Después de verificar toda la información requerida en el cuadro de diálogo AÑADIR FUNCIÓN, haga clic en Siguiente: Añadir Código. Aparecerá la página cron_impl_2func_651_help (con el código JavaScript precargado).
    Eventing cron update
  • Para volver a la pantalla de Eventos, pulse el botón '< volver a Concurso completo(debajo del editor) o haga clic en el enlace Eventos ficha.

Método #2 Añadir función manualmente, cortar y pegar JavaScript

Crear manualmente "cron_impl_2func_651"

Para añadir la primera función de Eventing desde Consola Web de Couchbase > Eventos haga clic en AÑADIR FUNCIÓNpara añadir una nueva función. La dirección AÑADIR FUNCIÓN aparece el cuadro de diálogo.

En el AÑADIR FUNCIÓN para cada elemento de la función, facilite la siguiente información:

  • Para el Cubo de origen seleccione crondata.
  • Para el Cubo de metadatos seleccione metadatos.
  • Visite cron_impl_2func_651 es el nombre de la función que está creando en el campo Nombre de la función cuadro de texto.
  • [Paso opcional] Introduzca el texto Un programador cron parte 1en el Descripción cuadro de texto.
  • Para el Ajustes utilice los valores por defecto.
  • Para el Fijaciones crear dos enlaces:
  • Para la vinculación, el "alias de cubo", especifica cron_bkt como "nombre alias" del cubo, y seleccione
    crondata como cubo asociado, y el modo debe ser "lectura y escritura".
  • Para la vinculación, el "alias de cubo", especifica ts_bkt como "nombre alias" del cubo, y seleccione
    viaje-muestra como cubo asociado, y el modo debe ser "lectura y escritura".
  • Una vez configurados los ajustes, el cuadro de diálogo debería tener este aspecto:
    Eventing cron update
  • Tras facilitar toda la información requerida en el AÑADIR FUNCIÓN pulse Siguiente Añadir código. En cron_impl_2func_651 aparece el cuadro de diálogo. La página cron_impl_2func_651 contiene inicialmente un bloque de código. Usted sustituirá su cron_impl_2func_651 en este bloque.Eventing cron update
  • Copie el siguiente código fuente JavaScript de Eventing Function (618 líneas) y péguelo en el bloque de código del marcador de posición de cron_impl_2func_651
  • Después de pegar, aparece la pantalla que se muestra a continuación:Eventing cron update
  • Haga clic en Guardar.
  • Para volver a la pantalla de Eventos, pulse el botón '< volver a Concurso completo(debajo del editor) o haga clic en el enlace Eventos

Crear manualmente "cron_impl_2func_651_help"

Para añadir la segunda función de Eventing desde Consola Web de Couchbase > Eventos haga clic en AÑADIR FUNCIÓNpara añadir una nueva función. La dirección AÑADIR FUNCIÓN aparece el cuadro de diálogo.

En el AÑADIR FUNCIÓN para cada elemento de la función, facilite la siguiente información:

  • Para el Cubo de origen seleccione crondata.
  • Para el Cubo de metadatos seleccione metadatos.
  • Visite cron_impl_2func_651_help es el nombre de la función que está creando en el campo Nombre de la función cuadro de texto.
  • [Paso opcional] Introduzca el texto Un ayudante cron como programador parte 1en el Descripción cuadro de texto.
  • Para el Ajustes utilice los valores por defecto.
  • Para el Fijaciones crear un enlace:
  • Para la vinculación, el "alias de cubo", especifica cron_bkt como "nombre alias" del cubo, y seleccione
    crondata como cubo asociado, y el modo debe ser "lectura y escritura".
  • Una vez configurados los ajustes, el cuadro de diálogo debería tener este aspecto:
    Eventing cron update
  • Tras facilitar toda la información requerida en el AÑADIR FUNCIÓN pulse Siguiente Añadir código. En cron_impl_2func_651_help aparece el cuadro de diálogo. La página cron_impl_2func_651_help contiene inicialmente un bloque de código. Usted sustituirá su cron_impl_2func_651_help en este bloque.Eventing cron update
  • Copie el siguiente código fuente JavaScript de Eventing Function (187 líneas) y péguelo en el bloque de código del marcador de posición de cron_impl_2func_651_help