Para preparar o agendador de tarefas assíncrono, precisamos do
postgres e de sua extensão
pg_task . (Forneci links para o meu fork do postgres, porque fiz algumas alterações que ainda não foram inseridas no repositório original. Você também pode usar a imagem
pronta .)
(Existe um erro no PL / pgSQL no PostgreSQL original, devido ao qual meu agendador não funciona corretamente quando ocorre uma exceção não capturada em uma tarefa escrita em PL / pgSQL. Descrevi esse erro
aqui e o corrigi no meu fork
aqui .)
Para instalar o planejador, você não precisa criar uma extensão no (cada) banco de dados. Em vez disso, basta adicioná-lo ao arquivo de configuração
shared_preload_libraries = 'pg_task'
Após reiniciar o PostgreSQL, o planejador criará tabelas de tarefas em todos os bancos de dados em nome dos usuários do banco de dados e nos esquemas padrão para esses usuários.
Se você deseja que o planejador seja executado apenas para bancos de dados específicos, é possível especificá-los no arquivo de configuração
pg_task.database = 'database1,database2'
Se você deseja executar o planejador não a partir de usuários do banco de dados, isso também pode ser definido como
pg_task.database = 'database1:user1,database2:user2'
Se você precisar criar tabelas do agendador que não estejam no esquema padrão para usuários, poderá configurá-lo desta maneira
pg_task_schema.database1 = schema3
Se você também precisar nomear a tabela do agendador de maneira diferente, poderá fazê-lo assim
pg_task_table.database1 = table3
Por padrão, o planejador verifica tarefas a cada 1000 ms, mas isso pode ser alterado da seguinte maneira
pg_task_period.database1 = 100 pg_task_period.database2 = 10
Portanto, o planejador cria (se ainda não foi criado) (um esquema, se necessário) e) uma tabela de tarefas com essas colunas
id BIGSERIAL NOT NULL PRIMARY KEY,
De fato, o planejador inicia vários fluxos de trabalho em segundo plano: um para rastrear alterações no arquivo de configuração e iniciar / parar, se necessário, os outros processos em segundo plano do planejador. E um fluxo de trabalho em segundo plano para cada banco de dados para verificar tarefas agendadas em cada banco de dados e iniciar tarefas, se necessário.
Por exemplo, se queremos concluir a tarefa o mais rápido possível, executamos o comando SQL
INSERT INTO task (request) VALUES ('SELECT now()')
O planejador grava o resultado da tarefa na coluna de resultados em formato de texto. Se, como resultado da execução da tarefa, houver várias colunas, o agendador as adicionará ao cabeçalho junto com os tipos de coluna. Além disso, como resultado da tarefa, pode haver várias linhas, todas elas serão adicionadas à coluna de resultados.
Se queremos concluir uma tarefa, por exemplo, após 5 minutos, escrevemos o tempo planejado na coluna correspondente
INSERT INTO task (dt, request) VALUES (now() + '5 min':INTERVAL, 'SELECT now()')
e se quisermos que a tarefa seja concluída em um horário específico, vamos anotá-la
INSERT INTO task (dt, request) VALUES ('2019-07-01 00:00:00', 'SELECT now()')
Se precisamos que a tarefa seja executada a cada 5 minutos, escrevemos assim
INSERT INTO task (repeat, request) VALUES ('5 min', 'SELECT now()')
se assim for escrever
INSERT INTO task (repeat, request, drift) VALUES ('5 min', 'SELECT now()', false)
a tarefa será repetida 5 minutos após a conclusão da tarefa (e não após o horário agendado, por padrão).
Se uma exceção ocorrer durante a execução de uma tarefa, ela é interceptada e gravada em forma de texto na coluna de resultados, e o estado correspondente é atribuído à tarefa.
Por exemplo
INSERT INTO task (request) VALUES ('SELECT 1/0')
Se for necessário que, para uma fila de tarefas, não sejam executadas mais de 2 tarefas simultaneamente, criamos tarefas pelo comando
INSERT INTO task (queue, max, request) VALUES ('queue', 2, 'SELECT now()')
Suponha que nesta fila tenhamos acumulado muitas tarefas e elas sejam executadas simultaneamente por 2. Se você criar uma tarefa com o comando
INSERT INTO task (queue, max, request) VALUES ('queue', 3, 'SELECT now()')
será executado o mais rápido possível de todas as outras tarefas nesta fila, ou seja, ainda é algo como prioridade