From a20b0a99e75f8df0ac54b1b2075c9fcb58faee4c Mon Sep 17 00:00:00 2001 From: d-markey Date: Thu, 8 Jun 2023 12:00:57 +0200 Subject: [PATCH] Properly handle platform worker thread parameter + getter in generated worker/worker pool when `with_finalizers` is enabled (fix for https://github.com/d-markey/squadron_builder/issues/5) --- CHANGELOG.md | 4 ++ example/generated/my_service.worker.g.dart | 25 ++++++----- example/main.dart | 10 ++--- example/my_service.dart | 2 +- lib/src/_overrides.dart | 1 + lib/src/worker_assets.dart | 48 ++++++++++++++-------- pubspec.yaml | 2 +- 7 files changed, 54 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07433fc..ee57fe2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.2.1 + +- Properly handle platform worker thread parameter + getter in generated worker/worker pool when `with_finalizers` is enabled (fix for https://github.com/d-markey/squadron_builder/issues/5). + ## 2.2.0 - Automatically discover Squadron capabilities (`WorkerRequest`/`WorkerResponse` serialization type + availability of `EntryPoint` and `PlatformWorkerHook`). diff --git a/example/generated/my_service.worker.g.dart b/example/generated/my_service.worker.g.dart index 5d1d0e1..83eb1f7 100644 --- a/example/generated/my_service.worker.g.dart +++ b/example/generated/my_service.worker.g.dart @@ -56,19 +56,19 @@ mixin $MyServiceOperations on WorkerService { } // Service initializer -MyService $MyServiceInitializer(WorkerRequest startRequest) => - MyService(MyServiceConfig.fromJson(startRequest.args[0]), - workloadDelay: (startRequest.args[1] == null) - ? null - : MyServiceConfig.fromJson(startRequest.args[1])); +MyService $MyServiceInitializer(WorkerRequest startRequest) => MyService( + MyServiceConfig.fromJson(startRequest.args[0]), + (startRequest.args[1] == null) + ? null + : MyServiceConfig.fromJson(startRequest.args[1])); // Worker for MyService class MyServiceWorker extends Worker with $MyServiceOperations implements MyService { - MyServiceWorker(MyServiceConfig trace, - {MyServiceConfig? workloadDelay, - PlatformWorkerHook? platformWorkerHook}) + MyServiceWorker( + MyServiceConfig trace, MyServiceConfig? workloadDelay, + {PlatformWorkerHook? platformWorkerHook}) : super($MyServiceActivator, args: [trace.toJson(), workloadDelay?.toJson()], platformWorkerHook: platformWorkerHook); @@ -162,13 +162,12 @@ class MyServiceWorker extends Worker class MyServiceWorkerPool extends WorkerPool with $MyServiceOperations implements MyService { - MyServiceWorkerPool(MyServiceConfig trace, - {MyServiceConfig? workloadDelay, - ConcurrencySettings? concurrencySettings, + MyServiceWorkerPool( + MyServiceConfig trace, MyServiceConfig? workloadDelay, + {ConcurrencySettings? concurrencySettings, PlatformWorkerHook? platformWorkerHook}) : super( - () => MyServiceWorker(trace, - workloadDelay: workloadDelay, + () => MyServiceWorker(trace, workloadDelay, platformWorkerHook: platformWorkerHook), concurrencySettings: concurrencySettings); diff --git a/example/main.dart b/example/main.dart index cbc1098..b0b9054 100644 --- a/example/main.dart +++ b/example/main.dart @@ -88,16 +88,15 @@ void main() async { Future runService( MyServiceConfig trace, MyServiceConfig workloadDelay) async { - var counters = await testWith(MyService(trace, workloadDelay: workloadDelay)); + var counters = await testWith(MyService(trace, workloadDelay)); await Future.delayed(Duration.zero); - counters += await testWith(MyService(trace, workloadDelay: workloadDelay)); + counters += await testWith(MyService(trace, workloadDelay)); return counters / 2; } Future runWorker( MyServiceConfig trace, MyServiceConfig workloadDelay) async { - final worker = MyServiceWorker(trace, - workloadDelay: workloadDelay, + final worker = MyServiceWorker(trace, workloadDelay, platformWorkerHook: (w) => Squadron.info( 'Standalone worker ready (platform worker is a ${w.runtimeType})')); @@ -116,8 +115,7 @@ Future runWorker( Future runPool( MyServiceConfig trace, MyServiceConfig workloadDelay) async { - final pool = MyServiceWorkerPool(trace, - workloadDelay: workloadDelay, + final pool = MyServiceWorkerPool(trace, workloadDelay, concurrencySettings: ConcurrencySettings( minWorkers: 5, maxWorkers: 5, diff --git a/example/my_service.dart b/example/my_service.dart index ccdae62..f514537 100644 --- a/example/my_service.dart +++ b/example/my_service.dart @@ -15,7 +15,7 @@ part 'generated/my_service.worker.g.dart'; @SquadronService() @UseLogger(ParentSquadronLogger) class MyService extends WorkerService with $MyServiceOperations { - MyService(this._trace, {MyServiceConfig? workloadDelay}) + MyService(this._trace, MyServiceConfig? workloadDelay) : _delay = Duration(microseconds: workloadDelay?.value ?? 50); final MyServiceConfig _trace; diff --git a/lib/src/_overrides.dart b/lib/src/_overrides.dart index d55a251..124405a 100644 --- a/lib/src/_overrides.dart +++ b/lib/src/_overrides.dart @@ -12,6 +12,7 @@ const workerOverrides = { 'Duration get upTime': 'upTime', 'String get workerId': 'workerId', 'int get workload': 'workload', + 'PlatformWorkerHook? get platformWorkerHook': 'platformWorkerHook', // worker control 'Future start()': 'start()', 'void stop()': 'stop()', diff --git a/lib/src/worker_assets.dart b/lib/src/worker_assets.dart index 521bcad..24c78c7 100644 --- a/lib/src/worker_assets.dart +++ b/lib/src/worker_assets.dart @@ -172,6 +172,8 @@ class WorkerAssets { yield _generateServiceInitializer(); + final withPlatformWorkerHook = _squadron?.hasPlatformWorkerHook ?? false; + final generateWorker = withFinalizers ? _generateFinalizableWorker : _generateWorker; @@ -179,10 +181,9 @@ class WorkerAssets { ? serviceActivator : '$serviceActivator, args: [${service.serializedArguments}]'; - final platformWorkerHook = _squadron?.hasPlatformWorkerHook ?? false; - var workerParameters = service.parameters; - if (platformWorkerHook) { + + if (withPlatformWorkerHook) { // worker constructors also have an optional PlatformWorkerHook parameter activationsArgs += ', platformWorkerHook: platformWorkerHook'; if (workerParameters.isEmpty) { @@ -200,8 +201,8 @@ class WorkerAssets { } } - yield generateWorker( - workerParameters, activationsArgs, commands, unimplemented); + yield generateWorker(workerParameters, activationsArgs, + withPlatformWorkerHook, commands, unimplemented); if (service.pool) { final generatePool = @@ -210,27 +211,27 @@ class WorkerAssets { var poolParameters = service.parameters; // worker pool constructors also have an optional ConcurrencySettings parameter if (poolParameters.isEmpty) { - poolParameters = platformWorkerHook + poolParameters = withPlatformWorkerHook ? '{ConcurrencySettings? concurrencySettings, PlatformWorkerHook? platformWorkerHook}' : '{ConcurrencySettings? concurrencySettings}'; } else if (poolParameters.endsWith('}')) { poolParameters = poolParameters.substring(0, poolParameters.length - 1); - poolParameters += platformWorkerHook + poolParameters += withPlatformWorkerHook ? ', ConcurrencySettings? concurrencySettings, PlatformWorkerHook? platformWorkerHook}' : ', ConcurrencySettings? concurrencySettings}'; } else if (poolParameters.endsWith(']')) { poolParameters = poolParameters.substring(0, poolParameters.length - 1); - poolParameters += platformWorkerHook + poolParameters += withPlatformWorkerHook ? ', ConcurrencySettings? concurrencySettings, PlatformWorkerHook? platformWorkerHook]' : ', ConcurrencySettings? concurrencySettings]'; } else { - poolParameters += platformWorkerHook + poolParameters += withPlatformWorkerHook ? ', {ConcurrencySettings? concurrencySettings, PlatformWorkerHook? platformWorkerHook}' : ', {ConcurrencySettings? concurrencySettings}'; } yield generatePool( - poolParameters, platformWorkerHook, commands, unimplemented); + poolParameters, withPlatformWorkerHook, commands, unimplemented); } } @@ -257,6 +258,7 @@ class WorkerAssets { String _generateWorker( String workerParameters, String activationsArgs, + bool platformWorkerHook, List commands, List unimplemented) => ''' @@ -281,11 +283,22 @@ class WorkerAssets { '''; String _generateFinalizableWorker( - String workerParameters, - String activationsArgs, - List commands, - List unimplemented) => - ''' + String workerParameters, + String activationsArgs, + bool withPlatformWorkerHook, + List commands, + List unimplemented) { + var nonFormalArguments = service.nonFormalArguments; + if (withPlatformWorkerHook) { + if (nonFormalArguments.isEmpty) { + nonFormalArguments = 'platformWorkerHook: platformWorkerHook'; + } else if (service.parameters.endsWith(']')) { + nonFormalArguments += ', platformWorkerHook'; + } else { + nonFormalArguments += ', platformWorkerHook: platformWorkerHook'; + } + } + return ''' // Worker for ${service.name} class _$workerClassName extends Worker with $operationsMixinName @@ -310,7 +323,7 @@ class WorkerAssets { // Finalizable worker wrapper for ${service.name} class $workerClassName implements _$workerClassName { - $workerClassName(${service.nonFormalParameters}) : _worker = _$workerClassName(${service.nonFormalArguments}) { + $workerClassName($workerParameters) : _worker = _$workerClassName($nonFormalArguments) { _finalizer.attach(this, _worker, detach: _worker._detachToken); } @@ -339,6 +352,7 @@ class WorkerAssets { ${workerOverrides.entries.map((e) => _forwardOverride(e.key, '_worker', e.value)).join('\n\n')} } '''; + } String _generateWorkerPool( String poolParameters, @@ -439,7 +453,7 @@ class WorkerAssets { implements ${service.name} { _$workerPoolClassName($poolParameters) : super( - () => $workerClassName($serviceArguments}), + () => $workerClassName($serviceArguments), concurrencySettings: concurrencySettings); ${service.fields.values.map(_generateField).join('\n\n')} diff --git a/pubspec.yaml b/pubspec.yaml index 036b43a..90ca369 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: squadron_builder description: Dart code generator for Squadron workers. Implement your worker service and let squadron_builder bridge the gap with Web Workers and Isolates! -version: 2.2.0 +version: 2.2.1 homepage: https://github.com/d-markey/squadron_builder repository: https://github.com/d-markey/squadron_builder