squadron_builder 0.7.0 squadron_builder: ^0.7.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 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