Dicas de depuração e solução de problemas - AWS Flow Framework para Java

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Dicas de depuração e solução de problemas

Esta seção descreve algumas armadilhas comuns que você pode encontrar ao desenvolver fluxos de trabalho usando AWS Flow Framework para Java. Ela também oferece algumas dicas para ajudá-lo a diagnosticar e depurar problemas.

Erros de compilação

Se estiver usando a opção de construção do tempo de compilação AspectJ é possível que você encontre erros de tempo de compilação para os quais o compilador não é capaz de encontrar as classes do cliente gerado para o seu fluxo de trabalho e suas atividades. A causa provável desses erros de compilação é que o construtor AspectJ ignorou os clientes gerados durante a compilação. É possível corrigir esse problema removendo o recurso AspectJ do projeto e reativando-o. Observe que será necessário fazer isso toda vez que a interface do fluxo de trabalho ou das atividades for alterada. Devido a esse problema, recomendamos que você use a opção de construção do tempo de carregamento. Consulte a seção Configurando o AWS Flow Framework para Java para obter mais detalhes.

Falha de recurso desconhecido

O Amazon SWF retorna uma falha de recurso desconhecido quando você tenta executar uma operação em um recurso que não está disponível. As causas comuns para essa falha são:

  • Você configura um operador com um domínio que não existe. Para corrigir isso, primeiro registre o domínio usando o console do Amazon SWF ou a API de serviço do Amazon SWF.

  • Você tenta criar execução de fluxo de trabalho ou tarefas de atividade dos tipos que não foram registrados. Isso pode acontecer se você tentar criar a execução do fluxo de trabalho antes dos operadores serem executados. Como os operadores registram seus tipos ao serem executados pela primeira vez, é necessário executá-los pelo menos uma vez antes de tentar iniciar as execuções (ou registrar manualmente os tipos usando o Console ou a API de serviço). Observe que assim que os tipos forem registrados, é possível criar execuções mesmo que nenhum operador esteja sendo executado.

  • Um operador tenta concluir uma tarefa que já ultrapassou o tempo limite. Por exemplo, se um funcionário demorar muito para processar uma tarefa e exceder o tempo limite, ele terá uma UnknownResource falha ao tentar concluir ou falhar na tarefa. Os AWS Flow Framework trabalhadores continuarão pesquisando o Amazon SWF e processando tarefas adicionais. No entanto, considere ajustar o tempo limite. Ajustar o limite requer que você registre uma nova versão do tipo de atividade.

Exceções ao chamar get() em uma promessa

Diferente do Java Future, o Promise é uma construção sem bloqueio e chamar get() em uma Promise que ainda não está pronta lançará um exceção em vez de bloquear. A maneira correta de usar um Promise é passá-lo para um método assíncrono (ou uma tarefa) e acessar seu valor no método assíncrono. O AWS Flow Framework for Java garante que um método assíncrono seja chamado somente quando todos os argumentos Promise passados para ele estiverem prontos. Se você acredita que seu código está correto ou se depara com isso ao executar uma das AWS Flow Framework amostras, provavelmente é porque o AspectJ não está configurado corretamente. Para obter detalhes, consulte a seção Configurando o AWS Flow Framework para Java.

Fluxos de trabalho não determinísticos

Conforme descrito na seção Não determinismo, a implementação do seu fluxo de trabalho deve ser determinística. Alguns erros comuns que podem levar ao não determinismo são o uso do clock do sistema, o uso de números aleatórios e a geração de GUIDs. Como essas construções podem retornar valores diferentes em tempos diferentes, o fluxo de controle do seu fluxo de trabalho pode tomar caminhos diferentes a cada vez que for executado (consulte as seções Conceitos básicos do AWS Flow Framework: Execução distribuída e Nos bastidores para obter detalhes). Se a estrutura detecta não determinismo enquanto executa o fluxo de trabalho, uma exceção será lançada.

Problemas devido ao versionamento

Ao implementar uma nova versão do seu fluxo de trabalho ou atividade - por exemplo, ao adicionar um novo recurso - você deve aumentar a versão do tipo usando a anotação apropriada: @Workflow, @Activites ou @Activity. Quando as novas versões do fluxo de trabalho são implantadas, geralmente existirão execuções da versão existente que já estão sendo executadas. Portanto, é necessário garantir que os operadores com a versão adequada do fluxo de trabalho e das atividades obtenham as tarefas. Alcance isso usando um conjunto de lista de tarefas diferentes para cada versão. Por exemplo, anexe o número da versão ao nome da lista de tarefas. Isso garante que as tarefas que pertencem a versões diferentes do fluxo de trabalho e das atividades sejam atribuídas aos operadores adequados.

Solução de problemas e depuração de uma execução de fluxo de trabalho

A primeira etapa na solução de problemas de execução de um fluxo de trabalho é usar o console do Amazon SWF para examinar o histórico do fluxo de trabalho. O histórico do fluxo de trabalho é um registro completo e confiável de todos os eventos que alteraram o estado de execução da execução do fluxo de trabalho. Esse histórico é mantido pelo Amazon SWF e é de grande valia para o diagnóstico de problemas. O console do Amazon SWF permite pesquisar execuções de fluxo de trabalho e detalhar eventos individuais do histórico.

AWS Flow Framework fornece uma WorkflowReplayer classe que você pode usar para reproduzir a execução de um fluxo de trabalho localmente e depurá-la. Usando essa classe, você pode depurar execuções de fluxo de trabalho fechadas e em execução. O WorkflowReplayer conta com o histórico armazenado no Amazon SWF para executar a reprodução. Você pode apontá-lo para a execução de um fluxo de trabalho na sua conta do Amazon SWF ou fornecer a ele os eventos do histórico (por exemplo, você pode recuperar o histórico do Amazon SWF e serializá-lo localmente para uso posterior). Ao repetir uma execução do fluxo de trabalho usando o WorkflowReplayer, não há impacto sobre a execução do fluxo de trabalho em andamento em sua conta. A repetição é feita totalmente no cliente. Depure o fluxo de trabalho, crie pontos de interrupção e analise o código usando suas ferramentas de depuração como sempre. Se você estiver usando o Eclipse, considere adicionar filtros de etapas aos AWS Flow Framework pacotes de filtro.

Por exemplo, o trecho de código a seguir pode ser usado para repetir uma execução de fluxo de trabalho:

String workflowId = "testWorkflow"; String runId = "<run id>"; Class<HelloWorldImpl> workflowImplementationType = HelloWorldImpl.class; WorkflowExecution workflowExecution = new WorkflowExecution(); workflowExecution.setWorkflowId(workflowId); workflowExecution.setRunId(runId); WorkflowReplayer<HelloWorldImpl> replayer = new WorkflowReplayer<HelloWorldImpl>( swfService, domain, workflowExecution, workflowImplementationType); System.out.println("Beginning workflow replay for " + workflowExecution); Object workflow = replayer.loadWorkflow(); System.out.println("Workflow implementation object:"); System.out.println(workflow); System.out.println("Done workflow replay for " + workflowExecution);

AWS Flow Framework também permite que você obtenha um despejo assíncrono da execução do seu fluxo de trabalho. Essa thread dump fornece as pilhas de chamada de todas as tarefas assíncronas abertas. Essa informação pode ser útil para determinar quais tarefas na execução estão pendentes e possivelmente travadas. Por exemplo: .

String workflowId = "testWorkflow"; String runId = "<run id>"; Class<HelloWorldImpl> workflowImplementationType = HelloWorldImpl.class; WorkflowExecution workflowExecution = new WorkflowExecution(); workflowExecution.setWorkflowId(workflowId); workflowExecution.setRunId(runId); WorkflowReplayer<HelloWorldImpl> replayer = new WorkflowReplayer<HelloWorldImpl>( swfService, domain, workflowExecution, workflowImplementationType); try { String flowThreadDump = replayer.getAsynchronousThreadDumpAsString(); System.out.println("Workflow asynchronous thread dump:"); System.out.println(flowThreadDump); } catch (WorkflowException e) { System.out.println("No asynchronous thread dump available as workflow has failed: " + e); }

Tarefas perdidas

Às vezes você pode desativar operadores e iniciar novos em uma sucessão rápida apenas para descobrir que as tarefas são entregues aos operadores antigos. Isso pode acontece devido a condições de corrida no sistema, que é distribuído entre diversos processos. O problema também pode aparecer ao executar testes de unidade em um ciclo apertado. Interromper um teste no Eclipse pode causar isso pois os manipuladores do desligamentos podem não ser chamados.

Para garantir que o problema existe devido ao fato dos operadores antigos obterem tarefas, observe o histórico do fluxo de trabalho para determinar qual processo recebeu a tarefa que deveria ser recebida pelo novo operador. Por exemplo, o evento DecisionTaskStarted no histórico contém a identidade do operador de fluxo de trabalho que recebeu a tarefa. O ID usado pelo Flow Framework está no formato: {processId}@{host name}. Por exemplo, a seguir estão os detalhes do evento DecisionTaskStarted no console do Amazon SWF para uma execução de amostra:

Data do evento

Segunda-feira 20 de fevereiro 11:52:40 GMT-800 2012

Identidade

2276@ip-0A6C1DF5

ID do evento programado

33

Para evitar essa situação, use listas de tarefas diferentes para cada teste. Além disso, considere adicionar um atraso entre o desligamento de operadores antigos e o início de novos.