Eventos

Implementação de um agendador por meio do Couchbase Eventing (Parte 1)

Esta é a primeira de uma série de várias partes para aproveitar o Serviço de eventos do Couchbase para executar várias tarefas agendadas em intervalos recorrentes específicos em um cron completamente dentro do banco de dados, sem necessidade de infraestrutura adicional, por meio de uma única Eventing Function de uso geral.

Nesta parte, vamos nos concentrar na execução de rotinas de usuário fixas, funções JavaScript definidas dentro de uma Eventing Function.

Mais adiante, em artigos subsequentes, estenderemos o cron como Eventing Function para agendar e executar instruções N1QL dinâmicas orientadas por banco de dados e, por fim, exploraremos o agendamento de funções JavaScript dinâmicas orientadas por banco de dados.

Histórico

O Couchbase Eventing Service fornece uma estrutura para escrever suas próprias rotinas, funções JavaScript simples, para processar alterações em documentos. Esse serviço fornece toda a infraestrutura necessária para criar funções escalonáveis e robustas baseadas na nuvem, permitindo que você se concentre no desenvolvimento de lógica comercial pura para interagir quase em tempo real com as alterações nos dados. Suas funções podem acessar o serviço de dados do Couchbase (KV), o serviço de consulta do Couchbase (N1QL) e os pontos de extremidade REST externos ao sistema Couchbase.

Eventing Life Cycle 6.5 I/O

O JSON modelo de dados no Couchbase veio de JavaScriptPor isso, é natural que o Eventing Service exponha a capacidade de escrever código JavaScript para analisar e manipular documentos JSON em qualquer tipo de evento de alteração, incluindo inserções, atualizações, mesclagens e exclusões (denominadas mutações).

As Eventing Functions normalmente permitem que você implemente e execute fragmentos de código personalizados que reagem a milhares e até milhões de mutações por segundo em seus documentos. Vários casos de uso típicos são documentado para desenvolver Eventing Functions de alta velocidade e em escala que respondem a mutações de documentos do Couchbase.

Eventing Life Cycle 6.5

Em vez disso, este artigo se concentrará em um caso de uso de velocidade muito baixa do Eventing Service, criando um crontab distribuído confiável "no banco de dados", permitindo que você execute funções JavaScript que interagem com os serviços do Couchbase em uma programação periódica regular.

Agendamento da lógica de negócios para execução em uma data ou hora específica

Cron, com o nome de "CronosA palavra grega "tempo" é um dos utilitários mais úteis em um sistema Linux. No Linux, o cron é acionado por um arquivo crontab (tabela cron), um arquivo de configuração que especifica os comandos do shell a serem executados periodicamente em uma determinada programação.

Uma desvantagem da execução cron é que ele não foi projetado para ser um serviço distribuído; ele é executado em uma única caixa e, portanto, apresenta um único ponto de falha. Se o sistema ficar off-line por várias horas, todas as tarefas agendadas serão perdidas.

Sim, há alguns distribuídos cron implementações como o Cloud Service do Google, as tarefas agendadas do AWS e o Azure Functions / Time Triggers. Mas as ofertas de cada fornecedor de nuvem têm seus próprios idiomas e não são diretamente portáteis.

Além disso, a metodologia de configuração e controle precisa ser protegida, por exemplo, se você controlar um sistema distribuído cron por meio de uma API REST sobre HTTP/S, você precisa levar isso em conta no seu plano de segurança.

Usar o próprio Couchbase para executar comandos periódicos

Com uma pequena quantidade de código e planejamento, você pode aproveitar o serviço Eventing do Couchbase para fornecer cron para suas operações ou manutenções programadas no banco de dados. A criação do agendador no banco de dados permite que você obtenha os seguintes benefícios:

  • Portabilidade entre provedores de nuvem: se você hospedar novamente o cluster do Couchbase, seu agendador não será afetado.
  • Capacidade de suporte: se você utilizar o Couchbase, terá um único fornecedor para fornecer suporte e outros serviços.
  • Distribuído, sem ponto único de falha e todos os serviços do Couchbase suportam réplicas distribuídas.
  • Execução garantida: sua tarefa é executada mesmo após a recuperação de uma falha de nó.

Programação do Couchbase, temporizadores, o molho secreto

Os temporizadores são construções do Couchbase Eventing Service por meio das quais os desenvolvedores podem especificar uma rotina (lógica de negócios) a ser acionada em um momento futuro. Usaremos essa funcionalidade para implementar um serviço puramente configurável do Couchbase crontab que lhe permite acionar tarefas repetitivas como parte de seus fluxos de trabalho, seja para executar uma simples consulta N1QL ou para criar um mecanismo de regras complexo.

Em todos os projetos subsequentes, limitaremos nossa cron implementações em uma resolução de 15 segundos ou mais. Temos essa limitação porque, embora os temporizadores sejam dimensionados para milhões e tenham garantia de disparo e execução, eles não têm precisão de relógio de parede e atualmente têm um atraso de estado estável limitado a menos de 14 segundos [1].

É claro que, se você precisar de um cronograma mais apertado, ou seja, menos de 15 segundos, deverá simplesmente processar a própria mutação na lógica Eventing sem usar uma construção de cronômetro para agendar uma chamada de volta no futuro.

No momento em que este texto foi escrito, a versão atual do Couchbase é a 6.5.1, que duas limitações que precisamos contornar ao criar um cron sistema.

  1. Nas versões 5.5.x, 6.0.x e 6.5.x, uma função que é invocada por um retorno de chamada do temporizador não pode criar um novo temporizador de forma confiável (uma solução alternativa no espaço do usuário pode ser feita por meio de uma segunda função cooperativa).
  2. Nas versões 6.5.x, a criação de temporizadores no futuro (como em uma hora ou mais) em um sistema ocioso pode resultar em um número crescente de operações de balde de metadados que podem, eventualmente, bloquear mutações para uma determinada função de evento (na versão 6.5.X, uma solução alternativa no espaço do usuário pode ser realizada por meio de uma segunda função cooperativa). A gravidade é regida por:
    • O número de vBuckets que mantêm um timer ativo. Portanto, se houver apenas alguns cronômetros no futuro, o problema poderá não ser percebido ou se materializar.  Esse é o caso de apenas algumas programações do cron, mas, para completar, caso você adicione a funcionalidade de data, coloquei uma correção para esse problema no código fornecido neste artigo.
    • Se um timer de Eventing foi disparado recentemente em um vBucket (o que elimina o problema para o vBucket em questão com base em cada função). Portanto, os sistemas com muita atividade de temporizador de curto prazo não terão esse problema, mesmo que os temporizadores estejam programados para um futuro distante.

Felizmente, na versão 6.6.0, os dois problemas ou restrições acima foram eliminados e um agendador pode ser criado em uma única Eventing Function unificada e simples.

Eventing cron update

Pré-requisitos

Neste artigo, usaremos a versão mais recente do GA, ou seja, a versão 6.5.1 do Couchbase (talvez seja necessário fazer algumas alterações nas Eventing Functions descritas para versões anteriores do Couchbase). O exemplo deste artigo será executado com base no conjunto de dados de amostra de viagem fornecido com o servidor Couchbase.

DICA PRO: Somente para usuários avançados, Se você estiver familiarizado com o Couchbase Eventing e também com nossas ferramentas CLI / REST, poderá pular a maior parte deste blog e baixar um arquivo ZIP para configurar e executar rapidamente o sistema de agendamento apresentado abaixo. Clique com o botão direito do mouse no link a seguir e escolha Salvar link como para fazer o download do arquivo  cron_impl_2func_CLI.zip, mova-o para um nó Eventing, extraia o arquivo ZIP e consulte o arquivo README.txt extraído.

No entanto, se você não estiver familiarizado com o Couchbase ou com o serviço Eventing, consulte o GET STARTED e um exemplo de Eventing, especificamente o seguinte:

  • Configure um servidor Couchbase 6.5.1 funcional de acordo com as instruções em Comece aqui!
  • Certifique-se de que você pode executar uma consulta N1QL no amostra de viagem de acordo com as instruções em Execute sua primeira consulta N1QL.
  • Entenda como implantar uma função básica de Eventing de acordo com as instruções do Arquivamento de documentos que também usa o amostra de viagem conjunto de dados.
  • Certifique-se de que você tenha o amostra de viagem na visualização de Compartimentos da interface do usuário.
  • Certifique-se de que você tenha um balde chamado metadados na visualização Buckets da interface do usuário, ele deve ter o tamanho mínimo de 200 MB.
  • Na visualização Buckets da interface do usuário, crie um bucket chamado dados cadastrais com o tamanho mínimo de 200 MB. Para obter etapas detalhadas sobre como criar buckets, consulte Criar um balde.
  • Conjunto allow_interbucket_recursion para verdadeiro a fim de permitir que duas (2) funções de Eventing alterem o mesmo documento KV [2].

Implementação #1, programação do tipo "cron" com código rígido

Para nossa primeira implementação, por exemplo, a Parte 1 da série, projetaremos uma estrutura de controle simples que é apenas um documento KV JSON e também duas (2) Eventing Functions que responderão e agirão de acordo com as informações da estrutura de controle.

Abaixo está um projeto de um documento JSON, ou estrutura de controle, que nos permitirá ter vários "eventos" agendados. Cada evento agendado terá seu próprio documento de controle com uma CHAVE exclusiva, como recurring_event::1, recurring_event::1, ... recurring_event::N. A própria estrutura JSON contém informações para "reconstituir a chave", pois nosso sistema de agendamento responderá a alterações ou atualizações (mutações) nos documentos de controle, como alternar o estado "ativo" para ativar ou desativar a ação ou alterar o campo "verbose", que controla a quantidade e o estilo do registro.

A seguir, um exemplo de documento de controle com KEY evento_recorrente::1 que executará a função JavaScript doCronActionA às 14:54 (2:30 pm) todos os dias.

Registro de controle JSON Descrição
{
   "type": "recurring_event", A CHAVE será <>::<>
   "id":1,
   "hour":14, A hora do dia 0-23, *, *2X, *4X para acionar
   "min":54, O minuto na hora 0-59, *, *2X, *4X para acionar
   "action": "doCronActionA", Função JavaScript a ser executada quando o cronômetro for acionado
   "active":true, Sinalizador para ativar ou desativar essa programação
   "verbose": { Controle de registro [OPCIONAL
      "user_func":2, Nível de registro para a lógica de ação: 0=nenhum, etc. etc.
      "scheduler":3 Nível de registro para a lógica cron: 0=nenhum, etc. etc.
   },
   "dynamic": { [DYNAMIC] controle e estatísticas do sistema
      "estado": "braço", "arm"|"rearm"|"pending" qualquer valor != "pending" inicia uma programação
      "next_sched": 0, Número de segundos desde a época até a próxima programação desejada
      "prev_sched": 0, Número de segundos desde a época para a programação anterior
      "prev_etime": 0, Número de segundos desde a época para a hora de execução real da programação anterior
      "prev_delay": 0, Número de segundos em que o cronômetro foi atrasado em relação à programação
      "prev_atime": 0 Número de segundos usados pelo usuário 'action'
   }
}

Como o Linux tradicional crontab você pode definir hour e min como números inteiros legais, e também pode definir hora para "*" para processar todas as horas ou definir min para "*" para processar todos os minutos.

Embora não apoiemos o crontab sintaxe, oferecemos suporte a duas configurações não padrão, como segue, se você definir ambos hora e min se você definir ambos como "*4X", executaremos e rearmaremos quatro (4) vezes por minuto e, se você definir ambos como "*2X", executaremos e rearmaremos duas (2) vezes por minuto. Abaixo está uma tabela de programações compatíveis com a descrição:

hora min Os valores podem ser números ou cadeias de caracteres
13 32 Corra às 13:32 (ou 13:32)
* 15 Executar a cada hora aos 15 minutos
8 12 Corra uma vez por dia às 8:32 (ou 8:32 da manhã)
* * Executar uma vez por minuto
*2X *2X Funciona duas vezes por minuto - requer que a hora e o minuto estejam definidos como "*2X"
*4X *4X Funciona quatro vezes por minuto - requer que a hora e o minuto estejam definidos como "*2X"

Eventualmente, usaremos o Query Workbench para inserir o cron documentos de controle, todos os quais devem ter uma CHAVE exclusiva de evento_recorrente::# para um horário de execução programado de 14:54 (14:54), para a ação doCronActionA, poderíamos usar a seguinte instrução N1QL.

Não se preocupe em executar nenhum comando N1QL neste momento, executaremos as instruções N1QL mais tarde, depois que tivermos criado e implementado nossa Eventing Function.

É possível criar um registro de controle (ou registros) no bucket amostra de viageme, em seguida, liste-o, arme-o, desarme-o, ajuste a programação que ele segue, altere o nível de verbosidade do registro em log ou exclua-o da seguinte forma:

Ação Declaração N1QL
Criar uma programação INSERT INTO amostra de viagem (KEY,VALUE) VALORES (
"recurring_event::1", {
"type": "recurring_event",
"id":1,
"hour": "14″,
"min": "54″,
"action": "doCronActionA",
"active":true
}
);
Criar um índice para consultar dados sem especificar chaves CREATE primary INDEX on dados cadastrais ;
Mostrar todas as programações ordenadas por id SELECT * FROM dados cadastrais WHERE type="recurring_event" order by id ;
Mostrar programação específica SELECT * FROM dados cadastrais WHERE type="recurring_event" AND id=1 ;
Armar ou definir ativo ATUALIZAÇÃO dados cadastrais SET active = true WHERE type="recurring_event" AND id=1 ;
Desarmar ou definir como inativo ATUALIZAÇÃO dados cadastrais SET active = false WHERE type="recurring_event" AND id=1 ;
Ajuste do tempo de disparo ATUALIZAÇÃO dados cadastrais SET hour = 11, min = 30 WHERE type="recurring_event" AND id=1 ;
Ajustar o registro da "ação" ATUALIZAÇÃO dados cadastrais SET verbose.user_data = 0 WHERE type="recurring_event" AND id=1 ;
Ajustar o registro da lógica do agendador ATUALIZAÇÃO dados cadastrais SET verbose.scheduler = 0 WHERE type="recurring_event" AND id=1 ;
Excluir a programação DELETE FROM dados cadastrais WHERE type="recurring_event" AND id=1 ;

Suponha que tenhamos quatro (4) programações ativas. A execução do primeiro comando N1QL acima listará todas elas, por exemplo

Retornaria algo como o seguinte resultado (exibição de tabela no Query Workbench):

ativo ação hora id min programador tipo user_func
verdadeiro "doCronActionA" 14 1 54 1 "recurring_event" (evento recorrente) 2
verdadeiro "doCronActionB" * 2 * 1 "recurring_event" (evento recorrente) 1
verdadeiro "doCronActionC" *2X 3 *2X 4 "recurring_event" (evento recorrente) 4
verdadeiro "doCronActionD" * 4 0 0 "recurring_event" (evento recorrente) 1

Na tabela acima, temos quatro ações: a primeira é executada uma vez por dia, a segunda é executada a cada minuto, a terceira a cada 30 segundos e a quarta é executada uma vez por hora. Em uma próxima edição desta série, adicionaremos o recurso "dia da semana".

O objeto aninhado do registro de controle JSON "detalhado", se não for fornecido, terá como padrão { "user_func":1, "scheduler":1 } indicando um nível de registro baixo ou conciso para a função de ação e também para a lógica de agendamento. Um valor de 0 suprimirá todas as mensagens de registro, ou seja, doCronActionD, enquanto valores maiores serão mais detalhados, ou seja, conforme definido em doCronActionC.

O objeto aninhado do registro de controle JSON "dinâmico" se normalmente nunca for fornecido e terá como padrão {"state": "arm", "next_sched": 0, "prev_sched": 0, "prev_etime": 0, "prev_delay": 0, "prev_atime": 0 } esse é um bloco de rascunho para a programação lógica de Eventing em execução e também fornece estatísticas úteis sobre os tempos de execução, portanto, deve ser tratado como somente leitura.

Neste ponto, temos um projeto de controle de alto nível, mas precisamos de lógica para processar nossas estruturas de controle. É aqui que o Eventing Service do Couchbase, especificamente uma Eventing Function, entra em ação.

As funções de eventos

Esse projeto requer duas (2) funções de eventos: uma função JavaScript principal "cron_impl_2func_651" e uma pequena função JavaScript auxiliar "cron_impl_2func_651_help". Discutiremos cada seção das funções JavaScript que compõem o código JavaScript combinado da implementação inicial, com quase 610 linhas (sendo que cerca de 44% das linhas são comentários e espaços em branco)

Não se preocupe em recortar e colar agoraSe você preferir, poderá usar o link para baixar (para importação) as duas Eventing Functions necessárias e todas as configurações necessárias em dois arquivos denominados "cron_impl_2func_651.json" "cron_impl_2func_651_help.json" e também, se preferir, as duas funções unificadas completas que podem ser recortadas e coladas diretamente.

Nossa função de evento principal "cron_impl_2func_651" será composta de nove (9) funções JavaScript

  • Três (3) funções de lógica comercial (duas das quais estão vazias).
    • doCronActionA(doc) - um exemplo de ação de usuário N1QL a ser executado
    • doCronActionB(doc) - um shell de ação do usuário vazio para experimentos
    • doCronActionC(doc) - um shell de ação do usuário vazio para experimentos
  • Um (1) ponto de entrada para Eventing.
    • OnUpdate(doc, meta) - o ponto de entrada padrão do Eventing para inserções ou atualizações
  • Um (1) cron analisador de sintaxe para gerar a próxima programação.
    • getNextRecurringDate(hour_str, min_str) - lógica do cron para encontrar a próxima data agendada
  • Três (3) funções de suporte para verificar se a lógica comercial existe ou formatar resultados.
    • verifyFunctionExistsViaEval(curDoc, id) - certifique-se de que temos uma função para executar
    • toNumericFixed(number, precision) - formata um float em um estilo compacto
    • toLocalISOTime(d) - formata uma data em um estilo compacto
  • Uma (1) função de retorno de chamada quando os cronômetros são executados.
    • Callback(doc) - uma função de retorno de chamada para cronômetros programados

Nossa Helper Eventing Function "cron_impl_2func_651_help" será composta por uma (1) função JavaScript

  • Um (1) ponto de entrada para Eventing.
    • OnUpdate(doc, meta) - o ponto de entrada padrão do Eventing para inserções ou atualizações

Nas seções seguintes, examinaremos cada uma das funções JavaScript acima.

Precisamos de uma função JavaScript, por exemplo, a lógica comercial a ser executada em uma programação periódica.

A primeira coisa que queremos é uma rotina ou função que tenha nossa lógica de negócios que será executada com base em nossas regras do crontab. Chamaremos o método JavaScript doCronActionA(doc)no entanto, ele pode ser chamado de qualquer coisa, por exemplo doPeriodicLedgerBalance(doc), Os únicos requisitos para nossas funções de "ação" que implementam nossa lógica comercial programada são os seguintes:

  • Tem um parâmetro: doc, um documento de controle, conforme descrito acima, do tipo="recurring_event".
  • O nome real do JavaScript corresponde ao campo "action" no documento de controle.
  • Devoluções verdadeiro sobre sucesso e falso em caso de falha
  • Utiliza doc.verbose.user_func para controlar o registro; se 0, ele é silencioso; se 1, ele emite uma única linha; se 2, ele emite qualquer informação de registro necessária para depurar a função etc. etc.

Escreveremos nossa função doCronActionA(doc)para executar uma consulta N1QL incorporada) para combinar contagens de companhias aéreas por país e, em seguida, criar um único documento KV de dados calculados.

Em meu sistema de teste, um pequeno nó único nãoMDS (executando todos os serviços do Couchbase), o N1QL acima leva cerca de 20 ms. (para fins de clareza, fingir que é supercomplexo leva 10 segundos para ser concluído).

A ideia aqui é que o documento KV final calculado e resumido possa ser carregado rapidamente por 100 mil (ou um milhão) de mutações Eventing por segundo sem a sobrecarga adicional de comunicação com os nós do serviço Query e do processamento de instruções N1QL em cada mutação.

Deve ser óbvio que o objetivo dessa lógica comercial específica, doCronActionA(doc)O objetivo do cache semi-estático é criar um cache semi-estático que seja atualizado periodicamente em um cronograma.

Tudo o que estamos realmente fazendo (e é bastante rápido) é obter uma contagem de companhias aéreas por país a partir do conjunto de documentos de amostra de viagem. À medida que usamos o N1QL, criamos um documento e, por fim, o escrevemos no KV como um documento resumido. O ponto principal a ser destacado aqui é que não queremos repetir o mesmo trabalho para milhões de mutações cada, especialmente porque alguns cálculos podem levar 10 segundos de tempo de computação do serviço de consulta cada vez que iniciamos uma consulta N1QL incorporada a partir de uma função Eventing.

Abaixo, mostramos a função JavaScript que queremos executar uma vez por dia (ou talvez uma vez por hora, etc.). Observe que o nome da função corresponde ao nome no campo de ação da estrutura de controle. Para obter mais detalhes sobre a terminologia de Eventing e as construções de linguagem, consulte os documentos e exemplos do Couchbase em Serviço de eventos: Fundamentos.

A função acima simplesmente 1) consulta o bucket de amostra de viagens para extrair dados; nesse caso, a contagem de companhias aéreas para cada país; 2) cria um novo documento KV e uma nova chave e os grava no bucket de amostra de viagens para uso posterior.

Além disso, como parte deste exemplo, criamos um registro que responde a uma configuração de verbosidade numérica que a) registra uma única linha se o documento de controle tiver um valor para doc.verbose.user_func == 1 ou b) emite mais informações se o valor de doc.verbose.user_func >= 2.

Essa é uma estrutura genérica que pode executar um (1) cron ação ou até mesmo mil (1000) de cron ações. Por isso, forneci dois shells de função "vazios" adicionais - como já foi dito, eles poderiam ter qualquer nome.

e

Essas funções acima, doCronActionB e doCronActionC, são triviais, pois simplesmente registram informações no log do aplicativo Eventing da função Eventing. Consulte Funções de registro em log para obter mais detalhes. É claro que você precisa de um documento de controle do tipo = "recurring_event" com active = true e uma ação como action = "doCronActionB" para realmente ativá-los e executá-los.

Precisamos de um ponto de entrada ou manipulador de eventos

A partir da versão 6.5, dois pontos de entrada ou manipuladores são compatíveis com o Eventing Service OnUpdate(doc, meta) e OnDelete(meta) estamos interessados apenas no OnUpdate(doc,meta) para este exemplo.

O OnUpdate(doc,meta) é chamado quando qualquer documento no bucket de origem é criado ou modificado (mutado) e filtra imediatamente os documentos que não interessam. [3]

A chave aqui é que o cron A lógica do nosso manipulador só se preocupa com os documentos que têm doc.type de "recurring_event" e também um doc.active de true. Além disso, neste exemplo, criamos um rastreamento para o cron lógica de manutenção que só é registrada no log do aplicativo se o documento de controle tiver um valor para doc.verbose >= 3.

Se você executar apenas algumas programações, poderá desativar o trabalho no espaço do usuário ou "Correção para operações de balde de crescimento 6.5.X" comentando quatro linhas de código no bloco OnUpdate acima para "cron_impl_2func_651" da seguinte forma:

Precisamos de código para contornar possíveis operações de aumento de balde para a versão 6.5.X

A partir da versão 6.5.X, precisamos de um "Correção para operações de balde de crescimento 6.5.X", o que acontece em sistemas ociosos com muitos cronômetros programados para o futuro. Esse código garante que um timer de Eventing tenha sido disparado recentemente em um vBucket (o que elimina o problema do vBucket em questão com base em cada função).

 Precisamos de um utilitário para calcular o próximo horário na programação

A próxima função getNextRecurringDate(hour, min) determinará um horário para executar a ação, conforme definido como parte de nossa programação. Essa não é uma implementação completa de cronEm vez disso, ele contém os principais recursos padrão para execução uma vez por dia, uma vez por hora, uma vez por minuto. Ele também contém uma sintaxe não padrão para permitir a execução duas vezes por minuto ou quatro vezes por minuto.

Conforme descrito anteriormente, a função getNextRecurringDate(hour, min) permite o seguinte (a tabela está duplicada abaixo), sendo que os dois últimos não são padrão.[4]

hora min Os valores podem ser números ou cadeias de caracteres
13 32 Corra às 13:32 (ou 13:32)
* 15 Executar a cada hora aos 15 minutos
8 12 Corra uma vez por dia às 8:32 (ou 8:32 da manhã)
* * Executar uma vez por minuto
*2X *2X Funciona duas vezes por minuto - requer que a hora e o minuto estejam definidos como "*2X"
*4X *4X Funciona quatro vezes por minuto - requer que a hora e o minuto estejam definidos como "*2X"

Abaixo está uma implementação da lógica necessária para determinar o próximo momento para acionar um temporizador Eventing em nossa agenda, caso a lógica do usuário em nosso primeiro exemplo doCronActionA(doc) não for concluído em tempo hábil, por exemplo, excesso de tempo real, a próxima quantidade da programação será selecionada. Observe os temporizadores e suas funções principais. Portanto, se uma Eventing Function tiver um tempo limite de execução padrão de 60 segundos, se necessário, essa configuração poderá ser ajustada ou aumentada.

Precisamos de alguns pequenos serviços públicos

A função utilitária comum que simplesmente verifica se nosso JavaScript existe é usada por ambos OnUpdate(doc,meta), mostrado acima, e o cronômetro Callback(doc), mostrado mais tarde. Abaixo está verifyFunctionExistsViaEval(curDoc, id) que recebe dois argumentos: um documento de controle JSON e a KEY para esse documento.

Isso nos permite saber imediatamente, na implantação, se houve um problema com uma incompatibilidade de nomes entre o documento de registro de controle JSON e o nome real da função de lógica comercial no código JavaScript.

Observe que, se houver uma tentativa de executar uma função inexistente, o usuário final receberá um aviso no log do aplicativo cron_impl_2func_651.log  para corrigir o problema.

2020-04-22T16:20:38.725-07:00 [INFO] "Avisar/Desabilitar (Sem Ação e Sem Rearmamento), porque a 'ação' necessária de doCronMyNewFunction(doc) não existe, o id é" "recurring_event::1"

Essa correção pode ser feita por meio de uma pausa/retomada que adiciona a função e, em seguida, ajusta o documento de controle com o ID ou KEY especificado (por meio de uma alternância ativa para falso e depois para verdadeiro) ou ajusta o documento de controle para apontar para uma função existente em seu manipulador.

Em seguida, o utilitário toNumericFixed(number, precision) permite apenas uma formatação compacta e agradável de floats para nossas mensagens de registro.

Por fim, o utilitário toLocalISOTime(d) permite apenas uma boa formatação compacta de datas para nossas mensagens de registro.

Precisamos de uma chamada de retorno do temporizador para executar a lógica do usuário e rearmar o temporizador

A função JavaScript final em "cron_impl_2func_651" é o retorno de chamada do Timer, que é chamado quando o timer programado é acionado. A função de retorno de chamada deve ser uma função de nível superior que recebe um único argumento, o contexto.

Nesse caso, em nosso manipulador OnUpdate, fizemos referência a uma função JavaScript de Callback(doc) com um contexto de doc (nosso documento de controle do agendador ativo de type="recurring_event")

Na versão 6.6, podemos criar outro cronômetro dentro de um cronômetro, mas em todas as versões anteriores precisaremos acionar uma mutação para uma função "auxiliar" (evitamos cuidadosamente a recursão infinita). Na versão 6.6, a função auxiliar não é necessária e a lógica foi substancialmente simplificada.

Precisamos de uma função auxiliar para acionar uma nova mutação

Como antes da versão 6.6 (que ainda não foi lançada) não é possível criar um temporizador a partir de um retorno de chamada de um temporizador em execução, precisamos de uma segunda Eventing Function (juntamente com "allow_interbucket_recursion":true) para acionar uma mutação de modo que possamos gerar todos os nossos temporizadores no ponto de entrada OnUpdate(doc,meta) da Eventing Function principal. Fazemos isso da seguinte forma:

  1. cron_impl_2func_651 OnUpdate(doc,meta) recebe uma mutação, programa um cronômetro
  2. cron_impl_2func_651 Após um determinado período de tempo, quando o cronômetro amadurece, o Callback(doc) A rotina é executada, primeiro executa a ação do usuário desejada e, em seguida, cria uma mutação #1 no documento de controle (que não é vista pela função de criação para evitar recursão)
  3. cron_impl_2func_651_help OnUpdate(doc,meta) recebe uma mutação, faz outra mutação #2 no documento de controle, o que aciona 1. acima em um ciclo sem fim.

Observe que, na versão 6.6 do Couchbase, não precisamos de uma função auxiliar, pois é permitido criar um timer de dentro de um timer em execução. Isso simplifica muito a lógica necessária para criar um cron sistema[2].

A única função JavaScript em "cron_impl_2func_651_help" OnUpdate(doc,meta) é mostrado abaixo.

A função auxiliar precisa de alguns utilitários

Esses utilitários fornecem um Correção para operações de balde de crescimento 6.5.X assegurando que um temporizador Eventing seja acionado em cada vBucket em tempo hábil.

Agora, vamos implementar as duas Eventing Functions

Revisamos muitos códigos e o design do agendador inicial, agora é hora de ver tudo funcionando em conjunto.

Lembre-se de que, neste exemplo, há três compartimentos amostra de viagem (um conjunto de dados padrão de amostra), metadados(o bucket de metadados é um bloco de notas para Eventing e pode ser compartilhado com outras funções de Eventing) e, por fim, o dados cadastrais (que contém nossas programações cron). O amostra de viagem tem um tamanho de 100 MB e os outros dois baldes metadados e dados cadastrais devem ter um tamanho de 200 MB e já existir de acordo com as instruções em "Pré-requisitos".

  • Verifique a configuração atual do seu bucket acessando o Console da Web do Couchbase > Buckets página:Eventing cron update

Para implementar a função Eventing "cron_impl_2func_651", você pode seguir um destes dois métodos:

  • Complexidade básica, Método #1 Download/Importação
  • Complexidade média, método #2 Adicionar função manualmente, recortar e colar JavaScript

Método #1 Download/Importação

Importar a primeira função "cron_impl_2func_651"

Faça o download da primeira Eventing Function com todas as configurações necessárias, clique com o botão direito do mouse no link a seguir e selecione Salvar link como para fazer o download do arquivo cron_impl_2func_651.json em seu sistema de arquivos local.

Do Console da Web do Couchbase > Eventos página, clique em IMPORTAÇÃO, navegue até o arquivo cron_impl_2func_651.json, selecione-o e abra-o. A ADICIONAR FUNÇÃO é exibida.

No ADICIONAR FUNÇÃO para elementos individuais da função, forneça as informações abaixo. Observe o arquivo JSON cron_impl_2func_651.json pré-configurará todas as configurações corretamente para este exemplo:

  • Para o Balde de origem verifique se ele está definido como dados cadastrais.
  • Para o Balde de metadados verifique se ele está definido como metadados.
  • Verifique se cron_impl_2func_651 é o nome da função que você está criando no Nome da função caixa de texto.
  • [Etapa opcional] Digite o texto Um agendador do tipo cron - parte 1, no Descrição caixa de texto.
  • Para o Configurações use os valores padrão.
  • Para o Amarrações verifique se existem dois vínculos.
  • Para a vinculação, o "bucket alias" especifica cron_bkt como o "nome de alias" do bucket e selecione
    dados cadastrais como o bucket associado, e o modo deve ser "leitura e gravação".
  • Para a vinculação, o "bucket alias" especifica ts_bkt como o "nome de alias" do bucket e selecione
    amostra de viagem como o bucket associado, e o modo deve ser "leitura e gravação".
  • Suas configurações na caixa de diálogo devem ser parecidas com as seguintes:
    Eventing cron update
  • Depois de verificar todas as informações necessárias na caixa de diálogo ADD FUNCTION, clique em Next: Add Code (Adicionar código). O código cron_impl_2func_651 é exibida (com o código JavaScript pré-carregado).
    Eventing cron update
  • Para retornar à tela Eventing, clique no botão '< voltar para Eventing' (abaixo do editor) ou clique no link Eventos guia.

Importar a segunda função "cron_impl_2func_651_help"

Faça o download da segunda Eventing Function com todas as configurações necessárias, clique com o botão direito do mouse no link a seguir e selecione Salvar link como para fazer o download do arquivo cron_impl_2func_651_help.json em seu sistema de arquivos local.

Do Console da Web do Couchbase > Eventos página, clique em IMPORTAÇÃO, navegue até o arquivo cron_impl_2func_651_help.json, selecione-o e abra-o. A ADICIONAR FUNÇÃO é exibida.

No ADICIONAR FUNÇÃO para elementos individuais da função, forneça as informações abaixo. Observe o arquivo JSON cron_impl_2func_651_help.json pré-configurará todas as configurações corretamente para este exemplo:

  • Para o Balde de origem verifique se ele está definido como dados cadastrais.
  • Para o Balde de metadados verifique se ele está definido como metadados.
  • Verifique se cron_impl_2func_651_help é o nome da função que você está criando no Nome da função caixa de texto.
  • [Etapa opcional] Digite o texto Um auxiliar de agendamento do tipo cron - parte 1, no Descrição caixa de texto.
  • Para o Configurações use os valores padrão.
  • Para o Amarrações verifique se existe apenas uma ligação.
  • Para a vinculação, o "bucket alias" especifica cron_bkt como o "nome de alias" do bucket e selecione
    dados cadastrais como o bucket associado, e o modo deve ser "leitura e gravação".
  • Suas configurações na caixa de diálogo devem ser parecidas com as seguintes:
    Eventing cron update
  • Depois de verificar todas as informações necessárias na caixa de diálogo ADD FUNCTION, clique em Next: Add Code (Adicionar código). O código cron_impl_2func_651_help é exibida (com o código JavaScript pré-carregado).
    Eventing cron update
  • Para retornar à tela Eventing, clique no botão '< voltar para Eventing' (abaixo do editor) ou clique no link Eventos guia.

Método #2 Adicionar manualmente a função, recortar e colar JavaScript

Criar manualmente "cron_impl_2func_651"

Para adicionar a primeira função Eventing da lista Console da Web do Couchbase > Eventos página, clique em ADICIONAR FUNÇÃOpara adicionar uma nova função. A função ADICIONAR FUNÇÃO é exibida.

No ADICIONAR FUNÇÃO para elementos de função individuais, forneça as informações abaixo:

  • Para o Balde de origem definido como dados cadastrais.
  • Para o Balde de metadados definido como metadados.
  • Fazer cron_impl_2func_651 é o nome da função que você está criando no Nome da função caixa de texto.
  • [Etapa opcional] Digite o texto Um agendador do tipo cron - parte 1, no Descrição caixa de texto.
  • Para o Configurações use os valores padrão.
  • Para o Amarrações crie dois vínculos:
  • Para a vinculação, o "bucket alias" especifica cron_bkt como o "nome de alias" do bucket e selecione
    dados cadastrais como o bucket associado, e o modo deve ser "leitura e gravação".
  • Para a vinculação, o "bucket alias" especifica ts_bkt como o "nome de alias" do bucket e selecione
    amostra de viagem como o bucket associado, e o modo deve ser "leitura e gravação".
  • Depois de definir suas configurações, sua caixa de diálogo deverá ter a seguinte aparência:
    Eventing cron update
  • Depois de fornecer todas as informações necessárias no formulário ADICIONAR FUNÇÃO clique em Próximo: Adicionar código. O cron_impl_2func_651 é exibida. A caixa de diálogo cron_impl_2func_651 contém inicialmente um bloco de código de espaço reservado. Você substituirá seu cron_impl_2func_651 nesse bloco.Eventing cron update
  • Copie o código-fonte JavaScript da Eventing Function a seguir (618 linhas) e cole-o no bloco de código de espaço reservado de cron_impl_2func_651
  • Após a colagem, a tela é exibida como mostrado abaixo:Eventing cron update
  • Clique em Salvar.
  • Para retornar à tela Eventing, clique no botão '< voltar para Eventing' (abaixo do editor) ou clique no link Eventos

Criar manualmente "cron_impl_2func_651_help"

Para adicionar a segunda função Eventing do Console da Web do Couchbase > Eventos página, clique em ADICIONAR FUNÇÃOpara adicionar uma nova função. A função ADICIONAR FUNÇÃO é exibida.

No ADICIONAR FUNÇÃO para elementos de função individuais, forneça as informações abaixo:

  • Para o Balde de origem definido como dados cadastrais.
  • Para o Balde de metadados definido como metadados.
  • Fazer cron_impl_2func_651_help é o nome da função que você está criando no Nome da função caixa de texto.
  • [Etapa opcional] Digite o texto Um auxiliar de agendamento do tipo cron - parte 1, no Descrição caixa de texto.
  • Para o Configurações use os valores padrão.
  • Para o Amarrações crie uma ligação:
  • Para a vinculação, o "bucket alias" especifica cron_bkt como o "nome de alias" do bucket e selecione
    dados cadastrais como o bucket associado, e o modo deve ser "leitura e gravação".
  • Depois de definir suas configurações, sua caixa de diálogo deverá ter a seguinte aparência:
    Eventing cron update
  • Depois de fornecer todas as informações necessárias no formulário ADICIONAR FUNÇÃO clique em Próximo: Adicionar código. O cron_impl_2func_651_help é exibida. A caixa de diálogo cron_impl_2func_651_help contém inicialmente um bloco de código de espaço reservado. Você substituirá seu cron_impl_2func_651_help nesse bloco.Eventing cron update
  • Copie o seguinte código-fonte JavaScript da Eventing Function (187 linhas) e cole-o no bloco de código de espaço reservado de cron_impl_2func_651_help
  • Após a colagem, a tela é exibida como mostrado abaixo:Eventing cron update
  • Clique em Salvar.
  • Para retornar à tela Eventing, clique no botão '< voltar para Eventing' (abaixo do editor) ou clique no link Eventos

Implementar as duas funções

Agora, estamos prontos para iniciar as funções de Eventing. A partir do Console da Web do Couchbase > Eventos tela:

  • Clique no nome da função cron_impl_2func_651_help para expandir e expor os controles de função.Eventing cron update
  • Clique em Implementar.
  • No Confirmar a função de implantação selecione "A partir de agora" na opção Limite de alimentação.

Vamos começar com a outra função Eventing. A partir do Console da Web do Couchbase > Eventos tela:

  • Clique no nome da função cron_impl_2func_651 para expandir e expor os controles de função.Eventing cron update
  • Clique em Implementar.
  • No Confirmar a função de implantação selecione "A partir de agora" na opção Limite de alimentação.

Configurar um cron tarefa a ser executada quatro (4) vezes por minuto

Neste ponto, nossa função Eventing está aguardando uma mutação especificamente em qualquer documento do tipo="recurring_event" que tenha um campo active=true.

Do Console da Web do Couchbase > Consulta usaremos o N1QL para criar uma nova tarefa agendada no bucket "travel-sample":

  • Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultas
  • Clique em Executar
    Eventing cron update

Ativar nosso primeiro cron tarefa

O documento de controle que fizemos anteriormente não foi ativado porque especificamos "active":false; além disso, o cronograma acima será executado apenas uma vez por hora, mas queremos testar as coisas e vê-las funcionar em um futuro próximo.

Primeiro, precisamos de um índice para poder manipular nossos documentos de controle no N1QL; isso só precisa ser feito uma vez

  • Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultas

Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultasAgora, ativaremos a tarefa, mas ajustaremos a programação de repetição para cada 15 segundos para ver exatamente como o sistema está se comportando. Fazemos isso modificando o documento de controle com KEY recurring_event::1

  • Clique em Executar
    Eventing cron update

Usamos a sintaxe não padrão de ="*4X" para agendar um item recorrente quatro vezes por minuto e podemos ver nossa função de trabalho doCronActionA executando e também a lógica de manutenção para agendar a função por meio de instruções de registro, pois definimos verbose=3.

O agendador agora está sendo executado quatro vezes por minuto. É possível ver a atividade nas estatísticas e nos arquivos de log do aplicativo para as Eventing Functions cron_impl_2func_651 e cron_impl_2func_651_help.

  • Acesse o Console da Web do Couchbase > Painel você verá uma explosão de atividade a cada 15 segundos:Eventing cron update
  • Acesse o Console da Web do Couchbase > Eventos e clique no botão Registro link do implantado cron_impl_2func_651 Função de registro de eventos. Essa caixa de diálogo Registro de funções lista as instruções de registro em ordem inversa (itens mais recentes primeiro). A saída inicial deve ser semelhante à seguinte:
    2020-05-20T18:34:33.340-07:00 [INFO] "OnUpdate B recurring_event::1 recurring timer was created, timer_id 570927555481258455388"
    2020-05-20T18:34:33.340-07:00 [INFO] "OnUpdate A recurring_event::1 rcv mutation (initial or rearm) schedule timer at 2020-05-20T18:34:45.000"
    2020-05-20T18:34:33.233-07:00 [INFO] "doCronActionA upsert to KV with KEY cron_cache::airlines_by_country cachedoc " {"type": "cron_cache", "id": "airlines_by_country", "date": "2020-05-21T01:34:33.232Z", "data":{"United States":127, "United Kingdom":39, "France":21}}
    2020-05-20T18:34:33.233-07:00 [INFO] "A ação Callback R recurring_event::1 levou 0,013 seg., retornou true"
    2020-05-20T18:34:33.233-07:00 [INFO] "Callback C recurring_event::1 curDoc" {"action": "doCronActionA", "active":true, "hour": "*4X", "id":1, "min": "*4X", "type": "recurring_event", "verbose":{"scheduler":3, "user_func":2}, "dynamic":{"state": "pending", "next_sched":1590024885, "prev_sched":1590024870, "prev_etime":1590024873, "prev_delay":3.218,”prev_atime”:0.013}}
    2020-05-20T18:34:33.233-07:00 [INFO] "Callback B recurring_event::1 sched 1590024870, actual 1590024873, delay 3.218, took 0.013"
    2020-05-20T18:34:33.233-07:00 [INFO] "Callback A recurring_event::1 gen mutation #1 to doc to force schedule rearm at 2020-05-20T18:34:45.000"
    2020-05-20T18:34:33.232-07:00 [INFO] "doCronActionA N1QL idx 2, country France cnt 21"
    2020-05-20T18:34:33.232-07:00 [INFO] "doCronActionA N1QL idx 1, country United Kingdom cnt 39"
    2020-05-20T18:34:33.232-07:00 [INFO] "doCronActionA N1QL idx 0, country United States cnt 127"
    2020-05-20T18:34:33.220-07:00 [INFO] "doCronActionA ação do usuário controlada por recurring_event::1"
    2020-05-20T18:34:19.340-07:00 [INFO] "OnUpdate B recurring_event::1 recurring timer was created, timer_id 381384185845112994486"
    2020-05-20T18:34:19.340-07:00 [INFO] "OnUpdate A recurring_event::1 rcv mutation (initial or rearm) schedule timer at 2020-05-20T18:34:30.000"

    A linha mais antiga na parte inferior é a mutação que iniciou a programação (ou rearmou a programação), por exemplo, a mensagem OnUpdate, e vemos as duas primeiras execuções completas da lógica comercial que codificamos em doCronActionA

  • Também haverá algumas mensagens relacionadas ao "Correção para operações de balde de crescimento 6.5.X", mas isso será registrado em cron_impl_2func_651_help você verá mensagens como as seguintes a cada 30 segundos:
    2020-05-20T18:34::49.185-07:00 [INFO] "Seeding one doc to each vBucket in primary_bucket alias (took 221 mililis)"

Vamos ajustar a frequência e a verbosidade dessa tarefa específica. Usaremos o padrão cron sintaxe de '*' para ambos hora e min para obter uma programação recorrente de uma vez por minuto, 4 vezes mais lenta do que a frequência atualmente em execução. Além disso, reduziremos o nível de verbosidade da lógica do agendador para zero e a função do usuário para 1, para que vejamos apenas uma mensagem por invocação.

Do Console da Web do Couchbase > Consulta usaremos o N1QL para criar uma nova tarefa agendada no bucket "travel-sample":

  • Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultas
  • Clique em Executar

Após 2 ou 3 minutos de acesso, o Console da Web do Couchbase > Eventos e clique no botão Registro link do implantado cron_impl_2func_651 Função de eventos.

  • O cronograma recorrente agora é de um minuto e muito menos detalhado. Apenas uma mensagem ou linha de registro é emitida para cada execução de função (mais uma vez na ordem inversa de tempo).
    2020-05-20T18:43:04.231-07:00 [INFO] "doCronActionA ação do usuário controlada por recurring_event::1"
    2020-05-20T18:42:08.233-07:00 [INFO] "doCronActionA ação do usuário controlada por recurring_event::1"

    Apenas uma mensagem ou linha de log é emitida para cada execução de função de usuário programada, ou seja doCronActionA (mais uma vez na ordem inversa do tempo).

Vamos dar uma olhada no trabalho que está sendo realizado

Esse código fornece uma estrutura prática para executar qualquer função JavaScript em um cronograma recorrente e nossa função doCronActionA está fazendo upserting (inserção ou atualização) de um documento KV de cache calculado uma vez por minuto.

Para verificar os resultados da função de eventos implementada, acesse o Console da Web do Couchbase > Buckets e clique no link Documents (Documentos) da página amostra de viagem balde.

  • Na caixa de texto "N1QL WHERE" após o texto a seguir.
  • Clique em Recuperar documentos
    Agora você deve ver um documento, um documento de cache cron_cache::airlines_by_country que está sendo atualizado uma vez por minuto pela função agendada doCronActionA.
    Eventing cron update
  • Clique na identificação "cron_cache::airlines_by_country", você verá o documento em cache que está sendo atualizado pela lógica comercial do doCronActionA.
    Eventing cron update
    Espere um minuto e edite o documento novamente e você verá o campo "data" sendo atualizado. É claro que os dados de origem estão "estáticos" no momento, portanto, as contagens permanecerão as mesmas.

Vejamos o documento de controle

Esse código fornece uma estrutura para manter algumas estatísticas sobre cada programação em execução.

Para verificar as estatísticas da função de eventos implementada, acesse a seção Console da Web do Couchbase > Buckets e clique no link Documents (Documentos) da página dados cadastrais balde.

  • Na caixa de texto "N1QL WHERE" após o texto a seguir.
  • Clique em Recuperar documentos
    Agora você deve ver um documento de controle recurring_event::1 que está acionando a função agendada doCronActionA.Eventing cron update
  • Clique na identificação "evento_recorrente::1", você verá o documento de controle que está sendo atualizado pela lógica do agendador com algumas estatísticas na dinâmica do objeto JSON.
    Eventing cron update
    A parte "dinâmica" do documento que é adicionada automaticamente mantém algumas estatísticas de depuração:
  • prev_sched: é o carimbo de data/hora UNIX anterior da agenda que foi executada pela última vez
  • prev_etime: é o registro de data e hora real do UNIX quando a agenda foi executada pela última vez
  • prev_delay: é o atraso do prev_sched para o prev_etime
  • prev_atime: é o tempo necessário para executar essa ação, ou seja, para executar doCronActionA.
  • next_sched: é a próxima execução programada para essa ação

Essas estatísticas mantidas no subobjeto dinâmico JSON para cada agendamento são úteis para determinar se o seu sistema de agendamento está saudável e se a ação que está sendo executada está sendo concluída em tempo hábil.

Verifique se o cache é atualizado nas alterações de dados

Todo o objetivo do doCronActionA é executar o trabalho em um horário programado ou próximo a ele e atualizar um documento de cache com a CHAVE "cron_cache::airlines_by_country".

Vamos fazer algumas validações no Query Monitor para verificar se nosso cache está sendo atualizado: 1) examinando o documento do cache, 2) excluindo algumas companhias aéreas do conjunto de documentos de amostra de viagem e 3) verificando se o documento do cache é atualizado pela função doCronActionA.

Do Console da Web do Couchbase > Consulta usaremos o N1QL para visualizar e manipular os dados no bucket "travel-sample":

  • Recorte e cole a seguinte instrução N1QL no arquivo
  • Editor de consultas
  • Clique em Executar
    Na exibição JSON do Query Workbench, você deverá ver:
  • Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultas
  • Clique em Executar
    Na exibição JSON do Query Workbench, você deverá ver (acabamos de excluir alguns dados)
  • Aguarde um pouco mais de um minuto
  • Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultas
  • Clique em Executar
    Na exibição JSON do Query Workbench, você verá que quatro (4) linhas aéreas não estão mais presentes

Iniciar uma segunda tarefa agendada

Esse código fornece uma estrutura prática para a execução de 1 a N funções JavaScript em programações recorrentes.

Permitiremos que a função doCronActionA continuarão a ser executados em um cronograma de um minuto, mas agora habilitaremos doCronActionB em um cronograma de 30 segundos (duas vezes por minuto). Essa função é um shell vazio e registrará apenas que foi invocada.

Do Console da Web do Couchbase > Consulta usaremos o N1QL para exibir e manipular dados na página 'dados cadastrais' balde:

  • Recorte e cole a seguinte instrução N1QL no arquivo Editor de consultas

  • Clique em Executar

Nesse momento, você está executando duas (2) tarefas diferentes, cada uma delas em duas (2) programações diferentes para verificar. Aguarde de dois a três minutos e inspecione os arquivos de registro novamente

  • Acesse o Console da Web do Couchbase > Eventos e clique no botão Registro link do implantado cron_impl_2func_651 Função de eventos.
    Apenas uma mensagem ou linha de registro é emitida para cada execução de função (mais uma vez na ordem inversa de tempo). Vemos que doCronActionA dispara uma vez por minuto enquanto doCronActionB dispara duas vezes mais, por exemplo, uma vez a cada 30 segundos.

    2020-05-20T19:16:05.259-07:00 [INFO] "doCronActionA ação do usuário controlada por recurring_event::1"
    2020-05-20T19:16:05.255-07:00 [INFO] "Ação do usuário doCronActionB controlada por recurring_event::2"
    2020-05-20T19:15:37.253-07:00 [INFO] "Ação do usuário doCronActionB controlada por recurring_event::2"
    2020-05-20T19:15:09.250-07:00 [INFO] "doCronActionA ação do usuário controlada por recurring_event::1"
    2020-05-20T19:15:09.249-07:00 [INFO] "Ação do usuário doCronActionB controlada por recurring_event::2"
    2020-05-20T19:14:34.255-07:00 [INFO] "Ação do usuário doCronActionB controlada por recurring_event::2"

[OPCIONAL] Pausa / Editar JavaScript / Retomar

Basicamente, terminamos esta parte; sinta-se à vontade para experimentar e modificar as coisas e fazer experimentos, por exemplo:

Do Console da Web do Couchbase > Eventos tela:

  • Clique no nome da função cron_impl_2func_651 para expandir e expor os controles de função.
  • Clique em Pausa.
  • No Confirmar a função de pausa selecione "Função de pausa".
  • Clique em "Editar JavaScript"
  • Se estiver se sentindo confiante, modifique o doCronActionB para executar algumas operações de KV ou integrar-se ao cURL.
    Se você quiser apenas ver uma alteração, adicione algo simples à função e tente algo como o seguinte:
  • Clique em Salvar.
  • Para retornar à tela Eventing, clique no botão '< voltar para Eventing' (abaixo do editor) ou clique no link Eventos
  • Clique em Currículo.
  • No Confirmar função de retomada selecione "Retomar a função".
  • Aguarde cerca de um minuto e a função cron_impl_2func_651 para implementar
  • Clique no botão Registro link do implantado cron_impl_2func_651 Função de eventos.
    2020-05-20T19:20:41.343-07:00 [INFO] "esta é a minha lógica, a = 1 +7 = 8"
    2020-05-20T19:20:41.343-07:00 [INFO] "Ação do usuário doCronActionB controlada por recurring_event::2"

Limpeza

A limpeza envolve o cancelamento da implantação e a exclusão da função e, em seguida, a remoção dos dois buckets que você criou. Isso conclui o exemplo.

Remover funções

Do Console da Web do Couchbase > Eventos tela:

  • Clique no nome da função cron_impl_2func_651 para expandir e expor os controles de função.
  • Clique em Desimplantação.
  • No Confirmar a função de cancelar a implantação selecione "Função Undeploy".
  • Aguarde a função cron_impl_2func_651 para cancelar a implantação.
  • Clique em Excluir.
  • No Confirmar a função de exclusão selecione "Excluir função".

Do Console da Web do Couchbase > Eventos tela:

  • Clique no nome da função cron_impl_2func_651_help para expandir e expor os controles de função.
  • Clique em Desimplantação.
  • No Confirmar a função de cancelar a implantação selecione "Função Undeploy".
  • Aguarde a função cron_impl_2func_651_help para cancelar a implantação.
  • Clique em Excluir.
  • No Confirmar a função de exclusão selecione "Excluir função".

Remover baldes

Próximo: "Solte os baldes".metadados' 'dados cadastrais', e 'amostra de viagem' (eles sempre podem ser recriados).

Do Console da Web do Couchbase > Buckets e clique no link Documents (Documentos) da página amostra de viagem balde.

  • Clique em no nome do balde "metadados" para expandir e expor os controles
  • Clique em Excluir
  • No Confirmar Excluir compartimento selecione "Excluir balde".
  • Clique em no nome do balde "dados cadastrais" para expandir e expor os controles
  • Clique em Excluir
  • No Confirmar Excluir compartimento selecione "Excluir balde".
  • Clique em no nome do balde "amostra de viagem" para expandir e expor os controles
  • Clique em Excluir
  • No Confirmar Excluir compartimento selecione "Excluir balde".

Considerações finais

Espero que você tenha achado este passo a passo educativo e que tenha adquirido mais conhecimento sobre o Couchbase Eventing Service como um todo.

Anteriormente, observei que o Eventing foi projetado para processar mutações de alta velocidade (em milhões por segundo) a partir do fluxo DCP do bucket de origem associado à função. Essa função ou agendador de eventos só precisa reagir a alterações mínimas nos documentos do agendador.

Iniciei 5.000 programações com esse código inalterado apenas adicionando documentos de controle. Cheguei a executar 120.000 programações a cada minuto apenas para testar essa implementação (sim, 120.000 é uma quantidade absurda de programações independentes). cron programações a serem executadas). Além disso, coloquei 120.000 sc3hedules 2 dias no futuro para garantir que não tivéssemos problemas de recursos degenerados.

Sendo forçado a usar duas Evening Functions para criar o sistema de agendamento, a função principal cron_impl_2func_651 e um ajudante simples cron_impl_2func_651_help não foi tão elegante quanto eu esperava. Além disso, ter de contornar um vazamento de opções de balde disparando um cronômetro em cada vBucket foi, no mínimo, decepcionante. Felizmente, devido a esse esforço, foram implementadas mudanças e, na próxima versão 6.6.0, poderei criar um agendador mais limpo usando uma única Evening Function. Os principais aprimoramentos na versão 6.6 são: 1) a capacidade de gerar um novo cronômetro a partir de uma chamada de retorno de cronômetro; 2) a capacidade de cancelar ou substituir um cronômetro existente por referência; e 3) a eliminação do uso crescente de recursos em sistemas ociosos com cronômetros agendados no futuro.

Utilizei um balde autônomo 'dados cadastrais' para manter o cronograma ou os documentos de controle (não considero o uso de 'metadados', pois é um bloco de notas do sistema necessário para a Eventing e reservado para a própria Eventing) para oferecer a maior flexibilidade na manipulação de dados em outros blocos. Se eu tivesse colocado os documentos de controle em outro compartimento, não seria capaz de realizar operações N1QL nesse compartimento (já que ele é um compartimento de origem para a função Eventing) e estaria limitado apenas a operações KV para manipular dados no compartimento colocado.

Eu o desafio a experimentar outros casos de uso do cron e também a pensar em outras maneiras de aproveitar um serviço de agendamento:

  • Verificação de uma contagem de itens em um grande conjunto de dados durante "horários fora de pico" e realização de limpeza incremental
  • Realização de enriquecimento programado de documentos via N1QL.
  • Recalcular carteiras de ações em um cronograma regular.
  • Gerenciando TTL ou tempos de expiração via N1QL em uma programação recorrente, consulte Como gerenciar documentos TTL (Time-To-Live) com o Couchbase N1QL.
  • Integrando com pontos de extremidade REST externos em um cronograma repetitivo, consulte Usando cURL com o Eventing Service: Atualização.
  • Atualize o JavaScript de cron_impl_2func_651 para adicionar um novo campo "prev_astatus" ao objeto dinâmico JSON para salvar o sinalizador de resultado verdadeiro/falso retornado da ação do usuário executada anteriormente.

Atualizações

Este blog foi atualizado em 24 de julho de 2020 para adicionar uma solução alternativa para as versões 6.5.x que têm um número crescente de operações de balde de metadados que podem eventualmente bloquear mutações para uma determinada função Eventing ao criar temporizadores no futuro (como em uma hora ou mais) em um sistema ocioso.

Próximas etapas

Em algumas semanas "Implementação de um agendador robusto e portátil do tipo cron por meio do Couchbase Eventing (Parte 2)" será lançado, no qual exploraremos a execução de uma sequência de instruções N1QL dinâmicas orientadas pelo banco de dados sem a necessidade de editar a Eventing Function ou de definir um script de "ação" codificado dentro da Eventing Function.

Recursos

Referências

Gostaríamos muito de saber se você gostou dos recursos da versão 6.5 e como ela beneficiará seus negócios daqui para frente. Compartilhe seu feedback nos comentários ou na seção Couchbase fórum

Notas de rodapé

[1] A implementação do timer no Eventing Service foi projetada para lidar com um grande número de timers distribuídos na casa dos milhões em alta velocidade. Um único nó Eventing pode lidar com mais de 100 mil temporizadores por segundo e a única promessa é executar os temporizadores o mais rápido possível, ou seja, sem perda de temporizadores. Considere que o intervalo de varredura atual é de sete (7) segundos para coletar os temporizadores que estão prontos para disparar e, portanto, você deve esperar alguns atrasos. Para obter mais detalhes sobre o agendamento de temporizadores, consulte Temporizadores: Precisão do relógio de parede na documentação do Couchbase.

[2] Por meio de ajustes allow_interbucket_recursion para verdadeiro você está removendo as proteções que foram colocadas no servidor Couchbase para proteger contra a lógica de Eventing acidental, que pode iniciar loops recursivos infinitos. Não há nada de errado nisso, mas é fácil cometer um erro ao aproveitar a recursão. Nas versões 6.6 do Couchbase, o ajuste da lógica Eventing pode ser reduzido de duas (2) Eventing Functions para uma (1) Eventing Function simplificada, sem a necessidade de ajustar o allow_interbucket_recursion configuração.

[3] Existem duas grandes limitações. Primeiro, se um documento for modificado várias vezes em um curto período, as chamadas poderão ser agrupadas em um único evento devido à deduplicação. Segundo, não é possível discernir entre as operações de criação e atualização. Para as propostas de um cron nenhuma das limitações apresenta um problema.

[4] Por que eu não implementei a semântica exata do crontab? Eu poderia ter implementado, mas a quantidade de código é excessiva. https://github.com/kelektiv/node-cron juntamente com suas dependências de moment e moment-timezone (todos pacotes muito grandes). O getNextRecurringDate(hour_str, min_str) pode não ser tão flexível, mas é simples e abrange nosso caso de uso.

Compartilhe este artigo
Receba atualizações do blog do Couchbase em sua caixa de entrada
Esse campo é obrigatório.

Autor

Postado por Jon Strabala, gerente principal de produtos da Couchbase

Jon Strabala é gerente de produto principal, responsável pelo Couchbase Eventing Service. Antes de ingressar na Couchbase, ele passou mais de 20 anos criando produtos de software em vários domínios, começando com EDA no setor aeroespacial e depois fazendo a transição para a criação de software corporativo com foco no que hoje é chamado de "IoT" e "dados em escala". Jon trabalhou em várias pequenas empresas de consultoria de software até abrir e gerenciar sua própria empresa. Ele tem ampla experiência em NoSQL/NewSQL, tanto na contribuição quanto na comercialização de novas tecnologias, como bitmaps compactados e armazenamentos de colunas. Jon é bacharel em engenharia elétrica e mestre em engenharia da computação, ambos pela Universidade do Sul da Califórnia, e tem MBA pela Universidade da Califórnia em Irvine.

3 Comentários

  1. Estou muito interessado nas atualizações da versão 6.6.x para usar uma única função! Adoro essa implementação para um agendador do tipo cron.

    1. Acabei de perceber que isso está disponível no GitHub! Vou dar uma olhada nisso! Recomendo atualizar esta postagem do blog com o link :) Obrigado!

      1. Jon Strabala, gerente principal de produtos da Couchbase janeiro 13, 2021 em 9:25 am

        Oi Alex,

        Em breve, atualizarei o "agendador do tipo cron" com uma versão 6.6.0 e uma versão 6.6.1 (usando acessores avançados de bucket).

        No entanto, provavelmente em um blog posterior (Parte 2), mas farei um link cruzado entre eles. Fico feliz que tenha encontrado meu protótipo 6.6.0 no GitHub.

Deixe um comentário

Pronto para começar a usar o Couchbase Capella?

Iniciar a construção

Confira nosso portal do desenvolvedor para explorar o NoSQL, procurar recursos e começar a usar os tutoriais.

Use o Capella gratuitamente

Comece a trabalhar com o Couchbase em apenas alguns cliques. O Capella DBaaS é a maneira mais fácil e rápida de começar.

Entre em contato

Deseja saber mais sobre as ofertas do Couchbase? Deixe-nos ajudar.