@@ -26,6 +26,7 @@ package worker
26
26
27
27
import (
28
28
"context"
29
+ "encoding/json"
29
30
"errors"
30
31
"fmt"
31
32
"os"
@@ -49,8 +50,10 @@ import (
49
50
"go.temporal.io/server/common/membership"
50
51
"go.temporal.io/server/common/namespace"
51
52
"go.temporal.io/server/common/primitives"
53
+ "go.temporal.io/server/common/primitives/timestamp"
52
54
"go.temporal.io/server/common/resource"
53
55
"go.temporal.io/server/common/sdk"
56
+ "go.temporal.io/server/common/util"
54
57
workercommon "go.temporal.io/server/service/worker/common"
55
58
)
56
59
63
66
fx.In
64
67
Logger log.Logger
65
68
SdkClientFactory sdk.ClientFactory
66
- SdkWorkerFactory sdk.WorkerFactory
67
69
NamespaceRegistry namespace.Registry
68
70
HostName resource.HostName
69
71
Config * Config
77
79
// from init params or Start
78
80
logger log.Logger
79
81
sdkClientFactory sdk.ClientFactory
80
- sdkWorkerFactory sdk.WorkerFactory
81
82
namespaceRegistry namespace.Registry
82
83
self * membership.HostInfo
83
84
hostName resource.HostName
@@ -105,6 +106,19 @@ type (
105
106
client sdkclient.Client
106
107
worker sdkworker.Worker
107
108
}
109
+
110
+ sdkWorkerOptions struct {
111
+ // Copy of relevant fields from sdkworker.Options
112
+ MaxConcurrentActivityExecutionSize int
113
+ WorkerActivitiesPerSecond float64
114
+ MaxConcurrentLocalActivityExecutionSize int
115
+ WorkerLocalActivitiesPerSecond float64
116
+ MaxConcurrentActivityTaskPollers int
117
+ MaxConcurrentWorkflowTaskExecutionSize int
118
+ MaxConcurrentWorkflowTaskPollers int
119
+ StickyScheduleToStartTimeout string // parse into time.Duration
120
+ StickyScheduleToStartTimeoutDuration time.Duration
121
+ }
108
122
)
109
123
110
124
var (
@@ -115,7 +129,6 @@ func NewPerNamespaceWorkerManager(params perNamespaceWorkerManagerInitParams) *p
115
129
return & perNamespaceWorkerManager {
116
130
logger : log .With (params .Logger , tag .ComponentPerNSWorkerManager ),
117
131
sdkClientFactory : params .SdkClientFactory ,
118
- sdkWorkerFactory : params .SdkWorkerFactory ,
119
132
namespaceRegistry : params .NamespaceRegistry ,
120
133
hostName : params .HostName ,
121
134
config : params .Config ,
@@ -249,6 +262,22 @@ func (wm *perNamespaceWorkerManager) getWorkerMultiplicity(ns *namespace.Namespa
249
262
return multiplicity , nil
250
263
}
251
264
265
+ func (wm * perNamespaceWorkerManager ) getWorkerOptions (ns * namespace.Namespace ) sdkWorkerOptions {
266
+ optionsMap := wm .config .PerNamespaceWorkerOptions (ns .Name ().String ())
267
+ var options sdkWorkerOptions
268
+ b , err := json .Marshal (optionsMap )
269
+ if err != nil {
270
+ return options
271
+ }
272
+ _ = json .Unmarshal (b , & options ) // ignore errors, just use the zero value anyway
273
+ if len (options .StickyScheduleToStartTimeout ) > 0 {
274
+ if options .StickyScheduleToStartTimeoutDuration , err = timestamp .ParseDuration (options .StickyScheduleToStartTimeout ); err != nil {
275
+ wm .logger .Warn ("invalid StickyScheduleToStartTimeout" , tag .Error (err ))
276
+ }
277
+ }
278
+ return options
279
+ }
280
+
252
281
// called on namespace state change callback
253
282
func (w * perNamespaceWorker ) refreshWithNewNamespace (ns * namespace.Namespace , deleted bool ) {
254
283
w .lock .Lock ()
@@ -357,7 +386,11 @@ func (w *perNamespaceWorker) tryRefresh(ns *namespace.Namespace) error {
357
386
return errNoWorkerNeeded
358
387
}
359
388
// ensure this changes if multiplicity changes
360
- componentSet += fmt .Sprintf ("%d" , multiplicity )
389
+ componentSet += fmt .Sprintf (",%d" , multiplicity )
390
+
391
+ // get sdk worker options
392
+ dcOptions := w .wm .getWorkerOptions (ns )
393
+ componentSet += fmt .Sprintf (",%+v" , dcOptions )
361
394
362
395
// we do need a worker, but maybe we have one already
363
396
w .lock .Lock ()
@@ -373,7 +406,7 @@ func (w *perNamespaceWorker) tryRefresh(ns *namespace.Namespace) error {
373
406
// create new one. note that even before startWorker returns, the worker may have started
374
407
// and already called the fatal error handler. we need to set w.client+worker+componentSet
375
408
// before releasing the lock to keep our state consistent.
376
- client , worker , err := w .startWorker (ns , enabledComponents , multiplicity )
409
+ client , worker , err := w .startWorker (ns , enabledComponents , multiplicity , dcOptions )
377
410
if err != nil {
378
411
// TODO: add metric also
379
412
return err
@@ -389,6 +422,7 @@ func (w *perNamespaceWorker) startWorker(
389
422
ns * namespace.Namespace ,
390
423
components []workercommon.PerNSWorkerComponent ,
391
424
multiplicity int ,
425
+ dcOptions sdkWorkerOptions ,
392
426
) (sdkclient.Client , sdkworker.Worker , error ) {
393
427
nsName := ns .Name ().String ()
394
428
// this should not block because it uses an existing grpc connection
@@ -398,28 +432,38 @@ func (w *perNamespaceWorker) startWorker(
398
432
})
399
433
400
434
var sdkoptions sdkworker.Options
435
+
436
+ // copy from dynamic config
437
+ sdkoptions .MaxConcurrentActivityExecutionSize = dcOptions .MaxConcurrentActivityExecutionSize
438
+ sdkoptions .WorkerActivitiesPerSecond = dcOptions .WorkerActivitiesPerSecond
439
+ sdkoptions .MaxConcurrentLocalActivityExecutionSize = dcOptions .MaxConcurrentLocalActivityExecutionSize
440
+ sdkoptions .WorkerLocalActivitiesPerSecond = dcOptions .WorkerLocalActivitiesPerSecond
441
+ sdkoptions .MaxConcurrentActivityTaskPollers = util .Max (2 , dcOptions .MaxConcurrentActivityTaskPollers )
442
+ sdkoptions .MaxConcurrentWorkflowTaskExecutionSize = dcOptions .MaxConcurrentWorkflowTaskExecutionSize
443
+ sdkoptions .MaxConcurrentWorkflowTaskPollers = util .Max (2 , dcOptions .MaxConcurrentWorkflowTaskPollers )
444
+ sdkoptions .StickyScheduleToStartTimeout = dcOptions .StickyScheduleToStartTimeoutDuration
445
+
401
446
sdkoptions .BackgroundActivityContext = headers .SetCallerInfo (context .Background (), headers .NewBackgroundCallerInfo (ns .Name ().String ()))
402
447
sdkoptions .Identity = fmt .Sprintf ("server-worker@%d@%s@%s" , os .Getpid (), w .wm .hostName , nsName )
403
- // sdk default is 2, we increase it if we're supposed to run with more multiplicity.
404
- // other defaults are already large enough.
405
- sdkoptions .MaxConcurrentWorkflowTaskPollers = 2 * multiplicity
406
- sdkoptions .MaxConcurrentActivityTaskPollers = 2 * multiplicity
448
+ // increase these if we're supposed to run with more multiplicity
449
+ sdkoptions .MaxConcurrentWorkflowTaskPollers *= multiplicity
450
+ sdkoptions .MaxConcurrentActivityTaskPollers *= multiplicity
407
451
sdkoptions .OnFatalError = w .onFatalError
408
452
409
453
// this should not block because the client already has server capabilities
410
- sdkworker := w .wm .sdkWorkerFactory . New (client , primitives .PerNSWorkerTaskQueue , sdkoptions )
454
+ worker := w .wm .sdkClientFactory . NewWorker (client , primitives .PerNSWorkerTaskQueue , sdkoptions )
411
455
for _ , cmp := range components {
412
- cmp .Register (sdkworker , ns )
456
+ cmp .Register (worker , ns )
413
457
}
414
458
415
459
// this blocks by calling DescribeNamespace a few times (with a 10s timeout)
416
- err := sdkworker .Start ()
460
+ err := worker .Start ()
417
461
if err != nil {
418
462
client .Close ()
419
463
return nil , nil , err
420
464
}
421
465
422
- return client , sdkworker , nil
466
+ return client , worker , nil
423
467
}
424
468
425
469
func (w * perNamespaceWorker ) onFatalError (err error ) {
0 commit comments