-
-
Notifications
You must be signed in to change notification settings - Fork 7
Manual Implementation
While squadron_builder is excellent for rapid development, understanding how Squadron works "under the hood" is valuable for advanced scenarios, debugging, or when you need behavior not yet supported by the generator (like passing workers to workers).
Examples in the Squadron repository itself use this manual approach.
A complete Squadron implementation consists of 5 main parts:
- Service Interface: The defining contract.
- Service Implementation: The actual business logic (runs on the worker thread).
- Service Client: The proxy (runs on the main thread) that sends commands to the worker.
- Worker Entry Points: The thread function that initializes the worker channel and service instance.
- Worker / WorkerPool: The class you instantiate to manage the thread.
This is just a Dart class or abstract class. It defines the operations and Command IDs.
abstract class MyService {
Future<int> add(int a, int b);
// Command IDs are used to identify which method to call
static const addCommand = 1;
}This class runs inside the worker. It implements WorkerService and maps Command IDs to method calls.
class MyServiceImpl implements MyService, WorkerService {
@override
Future<int> add(int a, int b) async => a + b;
// The Operations Map routes incoming requests (Command ID) to methods
@override
late final OperationsMap operations = OperationsMap({
MyService.addCommand: (WorkerRequest r) => add(r.args[0], r.args[1]),
});
}This class runs on the main thread. It implements WorkerService but forwards everything to the Worker via the Channel.
// 'WorkerClient' handles the low-level channel communication
class MyServiceClient extends WorkerClient implements MyService {
MyServiceClient(Channel channel) : super(channel);
@override
final operations = WorkerService.noOperations; // Clients don' handle operations
@override
Future<int> add(int a, int b) => send(
MyService.addCommand,
args: [a, b]
);
}Note: This WorkerClient is what allows you to treat a Remote Worker exactly like a Local Service.
This is the bridge between the OS thread and your code.
Native (VM) Entry Point:
void start(List args) => Squadron.run((startRequest) => MyServiceImpl(), args);Web (JS/WASM) Entry Point:
void main() => Squadron.run((startRequest) => MyServiceImpl());Finally, the class the user interacts with. It typically extends Worker and implements MyService.
class MyWorker extends Worker implements MyService {
MyWorker(entryPoint) : super(entryPoint);
@override
Future<int> add(int a, int b) => send(MyService.addCommand, args: [a, b]);
// ...
}- Custom Construction: Pass start arguments (like other Channels, database paths, or configuration maps) to your service implementation.
- Stateful Workers: Manage complex initialization logic before the service starts handling requests.
- Optimization: Fine-tune marshaling/unmarshaling without relying on generic code.
💖 Support the project! Sponsor d-markey on GitHub.