1313
1414package io .dapr .durabletask ;
1515
16- import com .google .protobuf .StringValue ;
1716import io .dapr .durabletask .implementation .protobuf .OrchestratorService ;
18- import io .dapr .durabletask .implementation .protobuf .OrchestratorService .TaskFailureDetails ;
1917import io .dapr .durabletask .implementation .protobuf .TaskHubSidecarServiceGrpc ;
18+ import io .dapr .durabletask .runner .ActivityRunner ;
19+ import io .dapr .durabletask .runner .OrchestratorRunner ;
2020import io .grpc .Channel ;
2121import io .grpc .ManagedChannel ;
2222import io .grpc .ManagedChannelBuilder ;
2323import io .grpc .Status ;
2424import io .grpc .StatusRuntimeException ;
25+ import io .opentelemetry .api .GlobalOpenTelemetry ;
26+ import io .opentelemetry .api .trace .Tracer ;
2527import io .opentelemetry .api .trace .propagation .W3CTraceContextPropagator ;
2628import io .opentelemetry .context .Context ;
2729import io .opentelemetry .context .propagation .TextMapGetter ;
@@ -54,6 +56,7 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
5456 private final Duration maximumTimerInterval ;
5557 private final ExecutorService workerPool ;
5658 private final String appId ; // App ID for cross-app routing
59+ private final Tracer tracer ;
5760
5861 private final TaskHubSidecarServiceGrpc .TaskHubSidecarServiceBlockingStub sidecarClient ;
5962 private final boolean isExecutorServiceManaged ;
@@ -85,6 +88,8 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
8588 sidecarGrpcChannel = this .managedSidecarChannel ;
8689 }
8790
91+ this .tracer = GlobalOpenTelemetry .getTracer ("dapr-workflow" );
92+
8893 this .sidecarClient = TaskHubSidecarServiceGrpc .newBlockingStub (sidecarGrpcChannel );
8994 this .dataConverter = builder .dataConverter != null ? builder .dataConverter : new JacksonDataConverter ();
9095 this .maximumTimerInterval = builder .maximumTimerInterval != null ? builder .maximumTimerInterval
@@ -95,6 +100,8 @@ public final class DurableTaskGrpcWorker implements AutoCloseable {
95100 this .workerPool = Context .taskWrapping (rawExecutor );
96101
97102 this .isExecutorServiceManaged = builder .executorService == null ;
103+
104+
98105 }
99106
100107 /**
@@ -167,109 +174,25 @@ public void startAndBlock() {
167174 while (workItemStream .hasNext ()) {
168175 OrchestratorService .WorkItem workItem = workItemStream .next ();
169176 OrchestratorService .WorkItem .RequestCase requestType = workItem .getRequestCase ();
177+
170178 if (requestType == OrchestratorService .WorkItem .RequestCase .ORCHESTRATORREQUEST ) {
171179 OrchestratorService .OrchestratorRequest orchestratorRequest = workItem .getOrchestratorRequest ();
172- logger .log (Level .FINEST ,
180+ logger .log (Level .INFO ,
173181 String .format ("Processing orchestrator request for instance: {0}" ,
174182 orchestratorRequest .getInstanceId ()));
175183
176- // TODO: Error handling
177- this .workerPool .submit (() -> {
178- TaskOrchestratorResult taskOrchestratorResult = taskOrchestrationExecutor .execute (
179- orchestratorRequest .getPastEventsList (),
180- orchestratorRequest .getNewEventsList ());
181-
182- OrchestratorService .OrchestratorResponse response = OrchestratorService .OrchestratorResponse .newBuilder ()
183- .setInstanceId (orchestratorRequest .getInstanceId ())
184- .addAllActions (taskOrchestratorResult .getActions ())
185- .setCustomStatus (StringValue .of (taskOrchestratorResult .getCustomStatus ()))
186- .setCompletionToken (workItem .getCompletionToken ())
187- .build ();
188-
189- try {
190- this .sidecarClient .completeOrchestratorTask (response );
191- logger .log (Level .FINEST ,
192- "Completed orchestrator request for instance: {0}" ,
193- orchestratorRequest .getInstanceId ());
194- } catch (StatusRuntimeException e ) {
195- if (e .getStatus ().getCode () == Status .Code .UNAVAILABLE ) {
196- logger .log (Level .WARNING ,
197- "The sidecar at address {0} is unavailable while completing the orchestrator task." ,
198- this .getSidecarAddress ());
199- } else if (e .getStatus ().getCode () == Status .Code .CANCELLED ) {
200- logger .log (Level .WARNING ,
201- "Durable Task worker has disconnected from {0} while completing the orchestrator task." ,
202- this .getSidecarAddress ());
203- } else {
204- logger .log (Level .WARNING ,
205- "Unexpected failure completing the orchestrator task at {0}." ,
206- this .getSidecarAddress ());
207- }
208- }
209- });
184+ this .workerPool .submit (new OrchestratorRunner (workItem , taskOrchestrationExecutor , sidecarClient , tracer ));
210185 } else if (requestType == OrchestratorService .WorkItem .RequestCase .ACTIVITYREQUEST ) {
211186 OrchestratorService .ActivityRequest activityRequest = workItem .getActivityRequest ();
212187
213-
214188 logger .log (Level .INFO ,
215189 String .format ("Processing activity request: %s for instance: %s, gRPC thread context: %s" ,
216190 activityRequest .getName (),
217191 activityRequest .getOrchestrationInstance ().getInstanceId (),
218192 Context .current ()));
219193
220- // Extract trace context from the ActivityRequest and set it as current
221- Context traceContext = extractTraceContext (activityRequest );
194+ this .workerPool .submit (new ActivityRunner (workItem , taskActivityExecutor , sidecarClient , tracer ));
222195
223- // TODO: Error handling
224- this .workerPool .submit (() -> {
225- String output = null ;
226- TaskFailureDetails failureDetails = null ;
227- try {
228- output = taskActivityExecutor .execute (
229- activityRequest .getName (),
230- activityRequest .getInput ().getValue (),
231- activityRequest .getTaskExecutionId (),
232- activityRequest .getTaskId (),
233- activityRequest .getParentTraceContext ().getTraceParent ());
234- } catch (Throwable e ) {
235- failureDetails = TaskFailureDetails .newBuilder ()
236- .setErrorType (e .getClass ().getName ())
237- .setErrorMessage (e .getMessage ())
238- .setStackTrace (StringValue .of (FailureDetails .getFullStackTrace (e )))
239- .build ();
240- }
241-
242- OrchestratorService .ActivityResponse .Builder responseBuilder = OrchestratorService .ActivityResponse
243- .newBuilder ()
244- .setInstanceId (activityRequest .getOrchestrationInstance ().getInstanceId ())
245- .setTaskId (activityRequest .getTaskId ())
246- .setCompletionToken (workItem .getCompletionToken ());
247-
248- if (output != null ) {
249- responseBuilder .setResult (StringValue .of (output ));
250- }
251-
252- if (failureDetails != null ) {
253- responseBuilder .setFailureDetails (failureDetails );
254- }
255-
256- try {
257- this .sidecarClient .completeActivityTask (responseBuilder .build ());
258- } catch (StatusRuntimeException e ) {
259- if (e .getStatus ().getCode () == Status .Code .UNAVAILABLE ) {
260- logger .log (Level .WARNING ,
261- "The sidecar at address {0} is unavailable while completing the activity task." ,
262- this .getSidecarAddress ());
263- } else if (e .getStatus ().getCode () == Status .Code .CANCELLED ) {
264- logger .log (Level .WARNING ,
265- "Durable Task worker has disconnected from {0} while completing the activity task." ,
266- this .getSidecarAddress ());
267- } else {
268- logger .log (Level .WARNING , "Unexpected failure completing the activity task at {0}." ,
269- this .getSidecarAddress ());
270- }
271- }
272- });
273196 } else if (requestType == OrchestratorService .WorkItem .RequestCase .HEALTHPING ) {
274197 // No-op
275198 } else {
0 commit comments