Applicazione HelloWorldWorkflowAsync - AWS Flow Framework per Java

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Applicazione HelloWorldWorkflowAsync

A volte, è preferibile avere un flusso di lavoro che esegue determinati task localmente anziché utilizzare un'attività. Tuttavia, i task di flusso di lavoro spesso comportano l'elaborazione dei valori rappresentati dagli oggetti Promise<T>. Se passi un oggetto Promise<T> a un metodo di flusso di lavoro sincrono, il metodo viene eseguito immediatamente ma non può accedere al valore dell'oggetto Promise<T> fino a che l'oggetto non è pronto. In realtà, sarebbe possibile eseguire il polling di Promise<T>.isReady fino a che non restituisce true, ma questa soluzione non è efficace e potrebbe comportare il blocco del metodo per un lungo periodo di tempo. Un miglior approccio consiste nell'utilizzare un metodo asincrono.

Un metodo asincrono viene implementato molto come un metodo standard, spesso come membro della classe di implementazione del flusso di lavoro, ed viene eseguito nel contesto dell'implementazione del flusso di lavoro. Per designarlo come metodo asincrono, è necessario applicare un'annotazione @Asynchronous, la quale indica al framework di considerarlo come un'attività.

  • Quando un'implementazione di flusso di lavoro chiama un metodo asincrono, restituisce immediatamente un risultato. I metodi asincroni in genere restituiscono un oggetto Promise<T> che diventa pronto al completamento del metodo.

  • Se a un metodo asincrono passi uno o più oggetti Promise<T>, ritarda l'esecuzione fino a che tutti gli oggetti di input sono pronti. Un metodo asincrono può quindi accedere ai relativi valori Promise<T> di input senza rischiare un'eccezione.

Nota

A causa del modo in cui ilAWS Flow Frameworkper Java esegue il flusso di lavoro, i metodi asincroni sono in genere eseguiti più volte. È quindi consigliabile utilizzarli per task rapidi con sovraccarico ridotto. Per eseguire task di lunga durata, come calcoli voluminosi, è consigliabile utilizzare le attività. Per dettagli, consulta AWS Flow FrameworkConcetti di base: Esecuzione distribuita.

Questo argomento è una panoramica di HelloWorldWorkflowAsync, una versione modificata di HelloWorldWorkflow che sostituisce una delle attività con un metodo asincrono. Per implementare l'applicazione, crea una copia del pacchetto helloWorld.HelloWorldWorkflow nella directory del progetto e denominala helloWorld.HelloWorldWorkflowAsync.

Nota

Questo argomento si basa sui concetti e sui file presentati negli argomenti Applicazione HelloWorld e HelloWorldWorkflow Applicazione. Approfondisci il file e concetti presentati in tali argomenti prima di continuare.

Nelle sezioni seguenti viene descritto come modificare il codice HelloWorldWorkflow originale per utilizzare un metodo asincrono.

Implementazione di attività di HelloWorldWorkflowAsync

HelloWorldWorkflowAsync implementa la relativa interfaccia di lavoratore di attività in GreeterActivities, come segue:

import com.amazonaws.services.simpleworkflow.flow.annotations.Activities; import com.amazonaws.services.simpleworkflow.flow.annotations.ActivityRegistrationOptions; @Activities(version="2.0") @ActivityRegistrationOptions(defaultTaskScheduleToStartTimeoutSeconds = 300, defaultTaskStartToCloseTimeoutSeconds = 10) public interface GreeterActivities { public String getName(); public void say(String what); }

Questa interfaccia è simile a quella utilizzata da HelloWorldWorkflow, con le seguenti eccezioni:

  • Omette l'attività getGreeting; quel task è ora gestito da un metodo asincrono.

  • Il numero di versione è impostato su 2.0. Dopo aver registrato un'interfaccia di attività con Amazon SWF, non puoi modificarla a meno che non modifichi il numero di versione.

Le altre implementazioni di metodo di attività sono identiche a HelloWorldWorkflow. Elimina semplicemente getGreeting da GreeterActivitiesImpl.

Implementazione di flusso di lavoro di HelloWorldWorkflowAsync

HelloWorldWorkflowAsync definisce l'interfaccia di flusso di lavoro come segue:

import com.amazonaws.services.simpleworkflow.flow.annotations.Execute; import com.amazonaws.services.simpleworkflow.flow.annotations.Workflow; import com.amazonaws.services.simpleworkflow.flow.annotations.WorkflowRegistrationOptions; @Workflow @WorkflowRegistrationOptions(defaultExecutionStartToCloseTimeoutSeconds = 3600) public interface GreeterWorkflow { @Execute(version = "2.0") public void greet(); }

L'interfaccia è identica a HelloWorldWorkflow, ad eccezione di un nuovo numero di versione. Come per le attività, se intendi modificare un flusso di lavoro registrato, devi modificarne la versione.

HelloWorldWorkflowAsync implementa il flusso di lavoro come segue:

import com.amazonaws.services.simpleworkflow.flow.annotations.Asynchronous; import com.amazonaws.services.simpleworkflow.flow.core.Promise; public class GreeterWorkflowImpl implements GreeterWorkflow { private GreeterActivitiesClient operations = new GreeterActivitiesClientImpl(); @Override public void greet() { Promise<String> name = operations.getName(); Promise<String> greeting = getGreeting(name); operations.say(greeting); } @Asynchronous private Promise<String> getGreeting(Promise<String> name) { String returnString = "Hello " + name.get() + "!"; return Promise.asPromise(returnString); } }

HelloWorldWorkflowAsync sostituisce l'attività getGreeting con un metodo asincrono getGreeting ma il funzionamento del metodo greet è praticamente lo stesso:

  1. Esegue l'attività getName, la quale restituisce immediatamente un oggetto Promise<String> nameche rappresenta il nome.

  2. Chiama il metodo asincrono getGreeting e gli passa l'oggetto name. getGreeting restituisce immediatamente un oggetto Promise<String>, ovvero greeting, che rappresenta la formula di apertura.

  3. Esegue l'attività say e le passa l'oggetto greeting.

  4. Al completamento di getName, name diventa pronto e getGreeting utilizza il relativo valore per costruire la formula di apertura.

  5. Al completamento di getGreeting, greeting diventa pronto e say stampa la stringa sulla console.

La differenza è che, anziché chiamare il client di attività per eseguire un'attività getGreeting, greet chiama il metodo asincrono getGreeting. Il risultato è lo stesso, ma il funzionamento del metodo getGreeting è un po' differente dall'attività getGreeting.

  • Il lavoratore di flusso di lavoro utilizza la semantica delle chiamate di funzione standard per eseguire getGreeting. Tuttavia, svolge il compito di intermediario per l'esecuzione asincrona Amazon SWF attività.

  • getGreeting viene eseguito nel processo dell'implementazione di flusso di lavoro.

  • getGreeting restituisce un oggetto Promise<String> anziché un oggetto String. Per ottenere il valore String incluso in Promise, devi chiamare il relativo metodo get(). Tuttavia, poiché l'attività viene eseguita in modo asincrono, il relativo valore restituito potrebbe non essere pronto immediatamente; get() genererà un'eccezione fino a che il valore restituito del metodo asincrono non è disponibile.

    Per ulteriori informazioni sul funzionamento di Promise, consulta AWS Flow FrameworkConcetti di base: Scambio di dati tra le attività e i flussi di lavoro.

getGreeting crea un valore restituito passando la stringa della formula di apertura al metodo Promise.asPromise statico. Questo metodo crea un oggetto Promise<T> del tipo appropriato, imposta il valore e ne attiva lo stato pronto.

Host e starter di flusso di attività e attività di HelloWorldWorkflowAsync

HelloWorldWorkflowAsync implementa GreeterWorker come classe host per le implementazioni di flusso di lavoro e attività. L'implementazione è identica a quella di HelloWorldWorkflow ad eccezione del nome taskListToPoll, che è impostato su "HelloWorldAsyncList".

import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflow; import com.amazonaws.services.simpleworkflow.AmazonSimpleWorkflowClient; import com.amazonaws.services.simpleworkflow.flow.ActivityWorker; import com.amazonaws.services.simpleworkflow.flow.WorkflowWorker; public class GreeterWorker { public static void main(String[] args) throws Exception { ClientConfiguration config = new ClientConfiguration().withSocketTimeout(70*1000); String swfAccessId = System.getenv("AWS_ACCESS_KEY_ID"); String swfSecretKey = System.getenv("AWS_SECRET_KEY"); AWSCredentials awsCredentials = new BasicAWSCredentials(swfAccessId, swfSecretKey); AmazonSimpleWorkflow service = new AmazonSimpleWorkflowClient(awsCredentials, config); service.setEndpoint("https://swf.us-east-1.amazonaws.com"); String domain = "helloWorldWalkthrough"; String taskListToPoll = "HelloWorldAsyncList"; ActivityWorker aw = new ActivityWorker(service, domain, taskListToPoll); aw.addActivitiesImplementation(new GreeterActivitiesImpl()); aw.start(); WorkflowWorker wfw = new WorkflowWorker(service, domain, taskListToPoll); wfw.addWorkflowImplementationType(GreeterWorkflowImpl.class); wfw.start(); } }

HelloWorldWorkflowAsync implementa lo starter di flusso di lavoro in GreeterMain. L'implementazione è identica a quella di HelloWorldWorkflow.

Per eseguire il flusso di lavoro, esegui GreeterWorker e GreeterMain, esattamente come con HelloWorldWorkflow.