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 squadron
annotations:
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 {
@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));
@override
late final Map<int, CommandHandler> operations =
buildMyServiceOperations(this);
}
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 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
Libraries
- squadron_builder
- Support for doing something awesome.