

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á.

# Contexto de execução
<a name="executioncontext"></a>

**Topics**
+ [Contexto de decisão](#executioncontext.decision)
+ [Contexto de execução de atividades](#activitycontext)

A estrutura fornece um contexto de ambiente às implementações de fluxo de trabalho e de atividades. Esse contexto é específico à tarefa que está sendo processada e fornece alguns utilitários que você pode usar em sua implementação. Um objeto de contexto é criado sempre que uma tarefa nova é processada pelo operador.

## Contexto de decisão
<a name="executioncontext.decision"></a>

Quando uma tarefa de decisão é executada, a estrutura fornece o contexto para a implementação do fluxo de trabalho por meio da classe `DecisionContext`. `DecisionContext` fornece informações sensíveis ao contexto, como ID de execução de fluxo de trabalho e funcionalidade de relógio e temporizador.

### Acesso DecisionContext na implementação do fluxo de trabalho
<a name="executioncontext.decision.access"></a>

Você pode acessar o `DecisionContext` em sua implementação de fluxo de trabalho usando a classe `DecisionContextProviderImpl`. Como alternativa, você pode injetar o contexto em um campo ou em uma propriedade de sua implementação de fluxo de trabalho usando Spring conforme mostrado na seção Injeção de capacidade de teste e dependência.

```
DecisionContextProvider contextProvider
    = new DecisionContextProviderImpl();
DecisionContext context = contextProvider.getDecisionContext();
```

### Criação de um relógio e de um temporizador
<a name="executioncontext.decision.timer"></a>

O `DecisionContext` contém uma propriedade do tipo `WorkflowClock` que fornece a funcionalidade de temporizador e de relógio. Como a lógica do fluxo de trabalho precisa ser determinística, você não deve usar diretamente o relógio do sistema na implementação do fluxo de trabalho. O método `currentTimeMills` no `WorkflowClock` retorna a hora de início do evento da decisão que está sendo processada. Isso garante que você obtenha o mesmo valor de tempo durante a reprodução, portanto, tornando a lógica do seu fluxo de trabalho determinista.

O `WorkflowClock` também tem um método `createTimer` que retorna um objeto de `Promise` que se torna pronto depois do intervalo especificado. Você pode usar esse valor como um parâmetro para outros métodos assíncronos para atrasar sua execução no período especificado. Dessa forma, você pode programar com eficiência uma atividade ou um método assíncrono para ser executado posteriormente.

O exemplo na lista a seguir demonstra como chamar periodicamente uma atividade.

```
@Workflow
@WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 60,
               defaultTaskStartToCloseTimeoutSeconds = 10)
public interface PeriodicWorkflow {

    @Execute(version = "1.0")
    void periodicWorkflow();
}

@Activities(version = "1.0")
@ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300,
                             defaultTaskStartToCloseTimeoutSeconds = 3600)
public interface PeriodicActivity {
    void activity1();
}

public class PeriodicWorkflowImpl implements PeriodicWorkflow {

    private DecisionContextProvider contextProvider
         = new DecisionContextProviderImpl();

    private WorkflowClock clock
         = contextProvider.getDecisionContext().getWorkflowClock();

    @Override
    public void periodicWorkflow() {
        callPeriodicActivity(0);
    }

    @Asynchronous
    private void callPeriodicActivity(int count,
                                      Promise<?>... waitFor) {
        if (count == 100) {
            return;
        }
        PeriodicActivityClient client = new PeriodicActivityClientImpl();
        // call activity
        Promise<Void> activityCompletion = client.activity1();

        Promise<Void> timer = clock.createTimer(3600);

        // Repeat the activity either after 1 hour or after previous activity run
        // if it takes longer than 1 hour
        callPeriodicActivity(count + 1, timer, activityCompletion);
    }
}


public class PeriodicActivityImpl implements PeriodicActivity
{
@Override
   public void activity1() {
      ...
      }
}
```

Na lista acima, o método assíncrono `callPeriodicActivity` chama `activity1` e cria um temporizador usando o `AsyncDecisionContext` atual. Ele passa o `Promise` retornado como um argumento para uma chamada recursiva a si próprio. Essa chamada recursiva espera até que o temporizador seja disparado (uma hora neste exemplo) antes de executar.

## Contexto de execução de atividades
<a name="activitycontext"></a>

Assim como a `DecisionContext` fornece informações de contexto quando uma tarefa de decisão está sendo processada, a `ActivityExecutionContext` fornece informações de contexto semelhantes quando uma tarefa de atividade está sendo processada. Esse contexto está disponível para o código de atividade por meio da classe `ActivityExecutionContextProviderImpl`.

```
ActivityExecutionContextProvider provider
    = new ActivityExecutionContextProviderImpl();
ActivityExecutionContext aec = provider.getActivityExecutionContext();
```

Usando a `ActivityExecutionContext`, você pode executar o seguinte:

### Pulsação de uma atividade de longa execução
<a name="activitycontext.heartbeat"></a>

Se a atividade estiver em execução há muito tempo, ela deverá informar periodicamente seu progresso ao Amazon SWF para que ele saiba que a tarefa ainda está progredindo. Na ausência dessa pulsação, a tarefa poderá esgotar o tempo limite se um tempo limite de pulsação da tarefa tiver sido definido no registro do tipo da atividade ou durante a programação da atividade. Para enviar uma pulsação, você pode usar o método `recordActivityHeartbeat` na `ActivityExecutionContext`. A pulsação também fornece um mecanismo para cancelar atividades em andamento. Consulte a seção [Tratamento de erros](errorhandling.md) para obter mais detalhes e um exemplo.

### Obtenção de detalhes da tarefa de atividade
<a name="activitycontext.details"></a>

Se desejar, você pode obter todos os detalhes da tarefa de atividade que foram passados pelo Amazon SWF quando o executor obteve a tarefa. Isso inclui informações sobre as entradas para a tarefa, o tipo da tarefa, o token da tarefa etc. Se você quiser implementar uma atividade que seja concluída manualmente, por exemplo, por uma ação humana, deverá usar o `ActivityExecutionContext` para recuperar o token da tarefa e passá-lo para o processo que acabará por concluir a tarefa da atividade. Consulte a seção em [Conclusão manual de atividades](activityimpl.md#activityimpl.complete) para obter mais detalhes.

### Obter o objeto do cliente Amazon SWF que está sendo usado pelo executor
<a name="activitycontext.client"></a>

O objeto do cliente Amazon SWF que está sendo usado pelo executor pode ser recuperado chamando o método `getService` em `ActivityExecutionContext`. Isso é útil se você quiser fazer uma chamada direta para o serviço Amazon SWF.