@@ -56,6 +56,7 @@ type grpcExecutor struct {
56
56
onWorkItemConnection func (context.Context ) error
57
57
onWorkItemDisconnect func (context.Context ) error
58
58
streamShutdownChan <- chan any
59
+ streamSendTimeout * time.Duration
59
60
}
60
61
61
62
type grpcExecutorOptions func (g * grpcExecutor )
@@ -90,6 +91,12 @@ func WithStreamShutdownChannel(c <-chan any) grpcExecutorOptions {
90
91
}
91
92
}
92
93
94
+ func WithStreamSendTimeout (d time.Duration ) grpcExecutorOptions {
95
+ return func (g * grpcExecutor ) {
96
+ g .streamSendTimeout = & d
97
+ }
98
+ }
99
+
93
100
// NewGrpcExecutor returns the Executor object and a method to invoke to register the gRPC server in the executor.
94
101
func NewGrpcExecutor (be Backend , logger Logger , opts ... grpcExecutorOptions ) (executor Executor , registerServerFn func (grpcServer grpc.ServiceRegistrar )) {
95
102
grpcExecutor := & grpcExecutor {
@@ -322,7 +329,7 @@ func (g *grpcExecutor) GetWorkItems(req *protos.GetWorkItemsRequest, stream prot
322
329
}
323
330
}
324
331
325
- if err := stream . Send ( wi ); err != nil {
332
+ if err := g . sendWorkItem ( stream , wi ); err != nil {
326
333
g .logger .Errorf ("encountered an error while sending work item: %v" , err )
327
334
return err
328
335
}
@@ -336,6 +343,27 @@ func (g *grpcExecutor) GetWorkItems(req *protos.GetWorkItemsRequest, stream prot
336
343
}
337
344
}
338
345
346
+ func (g * grpcExecutor ) sendWorkItem (stream protos.TaskHubSidecarService_GetWorkItemsServer , wi * protos.WorkItem ) error {
347
+ ctx := stream .Context ()
348
+ if g .streamSendTimeout != nil {
349
+ var cancel context.CancelFunc
350
+ ctx , cancel = context .WithTimeout (ctx , * g .streamSendTimeout )
351
+ defer cancel ()
352
+ }
353
+
354
+ errCh := make (chan error , 2 )
355
+ go func () {
356
+ select {
357
+ case errCh <- stream .Send (wi ):
358
+ case <- ctx .Done ():
359
+ g .logger .Errorf ("timed out while sending work item" )
360
+ errCh <- ctx .Err ()
361
+ }
362
+ }()
363
+
364
+ return <- errCh
365
+ }
366
+
339
367
// CompleteOrchestratorTask implements protos.TaskHubSidecarServiceServer
340
368
func (g * grpcExecutor ) CompleteOrchestratorTask (ctx context.Context , res * protos.OrchestratorResponse ) (* protos.CompleteTaskResponse , error ) {
341
369
iid := api .InstanceID (res .InstanceId )
0 commit comments