wiki:WF/Jobs

Version 7 (modified by pedroerp, 14 years ago) (diff)

--

Jobs

Jobs são códigos, vinculados a processos, que são agendados para execução. Os Jobs não possuem uma finalidade específica. Entre as possíveis utilizações de Job, podemos sugerir:

  • Envio, no último dia de cada mês e através de e-mail, de um relatório contendo dados produzidos pela execução do processo;
  • Auto-execução, diária, de instâncias que estão paradas há mais de 5 dias;
  • Acesso, a cada 5 minutos, a um banco externo para coleta de dados.

Cada Job corresponde a um arquivo contendo a implementação de uma classe (que estende a classe base dos Jobs).

Propriedades

Nome

O nome do Job. O nome do Job deve ser único em relação aos outros Jobs do mesmo processo. É também esta propriedade que define o nome da classe (e do arquivo) que será gerada para a execução do Job. Para a geração do nome da classe, o nome informado é normalizado. Esta normalização é diferente daquela usada no nome dos processos e atividades. Exemplo de conversão:

Nome: Avaliar Solicitação
Classe: AvaliarSolicitacao
Arquivo: class.job.AvaliarSolicitacao.inc.php

Descrição

A descrição do que o Job faz.

Ativo

Indica se o Job está ativo (checkbox marcada) ou não. Se o Job estiver inativo, ele não será executado, mesmo que esteja agendado.

Data de Início

Indica a data a partir da qual o Job será válido para execução.

Hora da Execução

A hora em que o Job será executado.

Tipo de Data

Os Jobs são bem versáteis quanto à sua repetição. Esta propriedade define que critério utilizar para definir sua repetição. São três as possibilidades:

  • Data Absoluta: ideal para Jobs que possuem um intervalo de execução bem definido. e.g.: executar o Job a partir do dia 07/05/2008 e repetir a cada 3 dias;
  • Dias da Semana: para Jobs que têm sua execução baseada em dias da semana. e.g.: a partir do dia 14/04/2008, executar o Job às segundas, quartas e sextas com repetição a cada duas semanas;
  • Data Relativa do Mês: para Jobs que devem ser executados em relação ao número de dias restantes para o fim do mês. e.g.: executar o Job a cada 6 meses, no último dia do mês.

O intervalo mínimo para execução de Jobs é de 1 minuto (disponível na repetição "Data Absoluta"). Não possui limite de intervalo máximo.

Dependendo do "Tipo de Data" selecionada, outros campos podem surgir:

  • Dias da Semana: são apresentados os dias da semana para que sejam selecionados aqueles em que o Job deve ser executado;
  • Data Relativa do Mês: é necessário informar quando o Job deve ser executado informando a quantidade de dias para o fim do mês.

Repetição do Job

Indica se o Job possi repetição (checkbox marcada) ou não.

Campos de Repetição

São campos onde se informa a periodicidade em que o Job é executado.

Manutenção de Jobs

Criação de Jobs

Basta clicar no botão "Novo" da interface. Ao salvar um Job, automaticamente será criado um arquivo modelo do Job.

Editar um Job

Para editar um Job, basta clicar no ícone que contém uma folha de papel e um lápis.

Se o nome do Job for trocado, o arquivo PHP do Job será renomeado e, a Engine tentará trocar o nome da classe. Caso a troca não seja possível, será enviada um alerta para o desenvolvedor informando que a troca precisa ser feita manualmente.

Remoção do Job

Para remover um Job, basta clicar no ícone de uma circunferência cortada (vermelha) e, confirmar a exclusão.

Ao remover um Job, o arquivo que implementa o Job também é excluído do sistema de arquivos. Além disso, os Logs produzidos pelo Job também são apagados.

Exemplo 1

No exemplo abaixo, buscamos as instâncias que estão paradas na atividade "Avaliar Serviço" há mais de 10 dias e, chamamos a ação "Confirmar". Este Job poderia ser executado diariamente e, assim, evitar o acúmulo de instâncias.

class ForcarAvaliacao extends JobBase
{
	public function run()
	{
		$objclass = &$this->environment['factory']->getInstance('wf_instance');

		/* seleciona as atividades */
		$atividade = $objclass->getActivityInformationByName('Avaliar Serviço');

		/* busca as instâncias abandonadas */
		$instancias = $objclass->getIdleInstances(10, array($atividade['activity_id']));

		$numeroInstancias = 0;
		foreach ($instancias as $instancia)
		{
			/* define as variáveis de request */
			$_REQUEST['action'] = 'Confirmar';

			/* tenta continuar a instância */
			if ($objclass->continueInstance($instancia['wf_activity_id'], $instancia['wf_instance_id']))
				$numeroInstancias++;

			/* podemos limitar a somente 50 instâncias (para não estourar o tempo de execução) */
			if ($numeroInstancias >= 50)
				break;
			/* ou podemos limitar de acordo com a quantidade de tempo disponível.
			 * Neste caso, usaremos apenas 90% do tempo disponível
			 */
			/*
			if (($this->getExecutionTime() / $this->getMaximumExectuionTime()) >= 0.9)
				break;
			*/
		}

		/* grava o log de acordo com o número de instâncias avaliadas */
		if ($numeroInstancias > 0)
			$this->success('Foram continuadas ' . $numeroInstancias . ' instâncias');
		else
			if (count($instancias) > 0)
				$this->fail('Existem ' . count($instancias) . ' instâncias que não puderam ser continuadas.');
			else
				$this->success('Não há instâncias para serem continuadas');
	}
}

Exemplo 2

Neste exemplo mostrarmos como criar uma instância automaticamente à partir de um Job. A criação da instância é realizada através do seguinte método.

final public function createNewInstance($startActivityId, $instanceName=false, $properties=false, $user=false)

Onde:

  • startActivityId: ID da atividade Start que criará a instância;
  • instanceName: Identificador da instância no processo;
  • properties: Array de propriedades da instância; e
  • user: uidNumber do dono da instância, que se omitido, será um usuário padrão do Job.

O código fonte abaixo apresenta na prática como uma instância pode ser criada em um Job.

class CriarInstancia extends JobBase
{
	public function run()
	{
		// Cria objeto $role para pegar o código da atividade start, no caso Abrir OS
		$role = &$this->environment['factory']->getInstance('wf_role');
		$activityId = $role->getActivityIdByName('Abrir OS');

		// Instância não necessita de identificador
		$name = false;

		// seta o array de propriedades da instância
		$properties = array ('_servico_id' => 5
				     , '_roteamento' => 'end'
			      );

		// Cria a instância e grava mensagens de sucesso ou falha no log de execução do Job.
		if ($this->createNewInstance($activityId, $name, $properties)){
			$this->success('Instância criada');
		} else {
			$this->fail('Não foi possível criar a instância.');
		}
	}
}

Logs

O Log é o resultado de cada execução de um Job. Sua listagem pode ser acessada através do ícone de um documento contendo ítens.

O Log pode indicar quatro resultados: desconhecido, erro, falha e sucesso. Veja a figura abaixo:

Explicando, de cima para baixo:

  • Erro - ocorre quando o Job possui algum erro em seu código. O erro é salvo no log;
  • Falha - ocorre em dois casos: (1) o executor de Job encontra algum problema que impede sua execução (e.g. não estende a classe JobBase, não possuí implementado o método run, etc.); (2) o desenvolvedor chamou o método fail da classe JobBase;
  • Sucesso - ocorre quando o usuário chama o método success da classe JobBase;
  • Desconhecido - quando não ocorrem erros ou falhas detectáveis pelo executar ou gerenciador de Jobs e, o desenvolvedor não fez nenhuma chamada a success ou fail.

Caso haja mais de uma chamada aos métodos success e/ou fail, será gravado em forma de Log somente a última chamada.

Execução de Jobs para Teste

Na interface de administração de Jobs, é possível executar um Job para testar seu funcionamento. Para isto, basta clicar no ícone da engrenagem (azul).

Após a execução de um Job (acionada a partir da interface), são exibidas até três informações:

  • Mensagens: informações sobre a execução do processo (e.g. tempo de execução, etc.);
  • Saída Default: strings enviadas para a saída padrão. Normalmente enviadas por echo, print, print_r, etc.;
  • Saída de Erro: erros capturados durante a execução do Job.

Veja, por exemplo, a tela de execução de um Job e o código do Job que a produziu:

class MeuSegundoJob extends JobBase
{
	public function run()
	{
		/* enviado antes do erro. Vai para a saída padrão */
		echo "minha saída\nantes do erro";

		/* código que vai causar erro */
		funcaoInexistente();
	}
}

Durante a execução de um Job, o atributo testMode possui o valor true (este atributo é disponível na própria classe do Job é poe ser acessado através de $this->testMode). Isto é feito para que, caso seja necessário, o código possa se comportar de maneira diferente se estiver sendo executado para testes ou para valer.

Considerações

Os Jobs foram introduzidos na versão 1.7.00.000 do Workflow.

Os Jobs possuem um tempo máximo de execução de 15 minutos. Se passarem deste tempo, serão finalizados. A classe base dos Jobs provê métodos que permitem ao desenvolvedor saber a quanto tempo o seu Job está executando e, tomar providências para que encerre sua execução antes do tempo limite ser atingido.

Para que os Jobs sejam executados, é necessário incluir a seguinte entrada no Crontab (executando o comando: crontab -e) do usuário do PHP (em sistemas Debian, seria o www-data):

* * * * * cd /var/www/expresso/workflow/inc; php5 -q /var/www/expresso/workflow/inc/class.JobScheduler.inc.php

Até o momento, a edição de Jobs não pode ser feita via Web (como é possível com o código dos processos). Sendo assim, é necessário editá-los manualmente. Os arquivos de Job encontram-se em:

/home/expressolivre/workflow/Nome_Processo_XX/code/jobs/

Attachments