squadron_builder 2.1.0 squadron_builder: ^2.1.0 copied to clipboard
Dart code generator for Squadron workers. Implement your worker service and let squadron_builder bridge the gap with Web Workers and Isolates!
squadron_builder #
Dart code generator for Squadron workers. Implement your worker service and let squadron_builder bridge the gap with Web Workers and Isolates!
Example #
The example computes Fibonacci numbers recursively, simply applying the definition of the Fibonacci sequence. It is very inefficient, but illustrates the effect of multithreading.
The service implementation uses annotations from squadron:
import 'dart:async';
import 'package:squadron/squadron_annotations.dart';
import 'package:squadron/squadron.dart';
import 'my_service.activator.g.dart';
part 'my_service.worker.g.dart';
@SquadronService(baseUrl: '/workers')
class MyService extends WorkerService with $MyServiceOperations {
@SquadronMethod()
Future<int> fibonacci(int i) async => _fib(i);
// naive & inefficient implementation of the Fibonacci sequence
static int _fib(int i) => (i < 2) ? i : (_fib(i - 2) + _fib(i - 1));
}
To have squadron_builder
generate the code for the worker and the worker pool, run:
dart run build_runner build
The main program runs the same computation:
- first with a plain instance of
MyService
(single-threaded, running in the main program's Isolate), - then with a plain instance of
MyService
(single-threaded, running in the main program's Isolate), - finally with an instance of
MyServiceWorkerPool
(multi-threaded, running in specific Isolates managed by the worker pool).
The worker and worker pool generated by squadron_builder
both wrap the original service and implement it: as a result, they are interchangeable with the original service.
import 'package:squadron/squadron.dart';
import 'my_service.dart';
void main() async {
Squadron.setId('MAIN');
Squadron.setLogger(ConsoleSquadronLogger());
Squadron.logLevel = SquadronLogLevel.info;
int count = 5;
Squadron.info('Computing with MyService (single-threaded)');
await computeWith(MyService(), count);
Squadron.info('Computing with MyServiceWorkerPool (multi-threaded)');
final pool = MyServiceWorkerPool(
concurrencySettings: ConcurrencySettings(
minWorkers: count,
maxWorkers: count,
maxParallel: 1,
));
await pool.start();
await computeWith(pool, count);
pool.stop();
}
Future computeWith(MyService service, int count) async {
final sw = Stopwatch();
sw.start();
final futures = <Future<int>>[];
for (var i = 0; i < count; i++) {
futures.add(service.fibonacci(40 + i));
}
final results = await Future.wait(futures);
Squadron.info(' * Results = $results');
Squadron.info(' * Total elapsed time: ${sw.elapsed}');
sw.stop();
}
To run the example:
dart run .\example\main.dart
Sample output:
[2022-08-21T19:55:46.358940Z] [INFO] [MAIN] Computing with MyService (single-threaded)
[2022-08-21T19:55:52.559343Z] [INFO] [MAIN] * Results = [102334155, 165580141, 267914296, 433494437, 701408733]
[2022-08-21T19:55:52.571404Z] [INFO] [MAIN] * Total elapsed time: 0:00:06.199773
[2022-08-21T19:55:52.571404Z] [INFO] [MAIN] Computing with MyServiceWorkerPool (multi-threaded)
[2022-08-21T19:55:55.777452Z] [INFO] [MAIN] * Results = [102334155, 165580141, 267914296, 433494437, 701408733]
[2022-08-21T19:55:55.777452Z] [INFO] [MAIN] * Total elapsed time: 0:00:03.170634