### Connect Worker to Platform Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_worker_runner.dart.gcov.html Establishes a connection with the platform worker. This method handles the initial start request, logger setup, and service initialization. It expects a valid connection request and ensures the worker is not already connected. ```dart void connect(WorkerRequest? startRequest, PlatformChannel channelInfo, WorkerInitializer initializer) async { late final WorkerChannel? channel; try { startRequest?.unwrapInPlace(internalLogger); channel = startRequest?.channel; if (startRequest == null) { throw SquadronErrorImpl.create('Missing connection request'); } else if (channel == null) { throw SquadronErrorImpl.create('Missing client for connection request'); } if (_logForwarder == null) { final logger = channel.log; _logForwarder = (event) => logger(event.origin); Logger.addOutputListener(_logForwarder!); } if (!startRequest.isConnection) { throw SquadronErrorImpl.create('Connection request expected'); } else if (_service != null || _operations != null) { throw SquadronErrorImpl.create('Already connected'); } var service = initializer(startRequest); if (service is Future) service = await service; service as WorkerService; _checkOperations(service.operations); _service = service; _operations = service.operations; channel.connect(channelInfo); if (service is ServiceInstaller) { _installCompleter = Completer(); try { final result = (service as ServiceInstaller).install(); if (result is Future) await result; } catch (ex, st) { internalLogger.e(() => 'Service installation failed: $ex'); channel.error(ex, st); channel.closeStream(); _installError = SquadronException.from(ex, st); } finally { _installCompleter?.complete(); } } } catch (ex, st) { internalLogger.e(() => 'Failed to connect: $ex'); channel?.error(ex, st); channel?.closeStream(); _installError = SquadronException.from(ex, st); rethrow; } } ``` -------------------------------- ### Provisioning Workers Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/worker_pool.dart.gcov.html This snippet illustrates the process of provisioning new workers for the pool. It handles the creation, configuration, and starting of workers, including error handling for failed starts and registration of successful ones. It also manages the count of starting workers and adds them to the task list for completion. ```Dart for (var i = 0; i < workload; i++) { t try { final worker = _workerFactory(exceptionManager); worker.channelLogger = channelLogger; final poolWorker = PoolWorker(worker, maxParallel); _startingWorkers++; tasks.add(poolWorker.worker.start().whenComplete(() { _startingWorkers--; }).then((_) { // start succeeded: register worker _addWorkerAndNotify(poolWorker); }).catchError((ex, st) { // start failed, ensure the worker is stopped poolWorker.worker.terminate(); errors.add(SquadronException.from(ex, st)); })); } catch (ex, st) { errors.add(SquadronException.from(ex, st)); } } ``` -------------------------------- ### Starting a Channel Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker/worker.dart.gcov.html Starts a new `Channel` if one does not already exist. It handles the case where the worker is stopped and returns an existing channel if available. ```dart @override Future start() { if (isStopped) { throw WorkerException('Invalid state: worker is stopped'); } if (_channel != null) { return Future.value(_channel!); } return _openChannel ??= Channel.open( exceptionManager, channelLogger, _entryPoint, getStartArgs() ?? const [], _threadHook, ).then((channel) { _channel = channel; _stats.start(); return channel; }); } ``` -------------------------------- ### Example Usage of Marshaler Annotations Source: https://github.com/d-markey/squadron/wiki/Annotations Demonstrates how to apply marshaler annotations to classes, methods, or parameters for custom serialization. ```dart @PersonMarshaler() // Applied to the class: all instances will use this marshaler class Person { ... } // OR @SquadronMethod() @PersonMarshaler() // Applied to the method: the return value will use this marshaler FutureOr getMe() { ... } // OR @SquadronMethod() FutureOr getAge(@PersonMarshaler() Person p) { ... } // Applied to a parameter ``` -------------------------------- ### WorkerRequest Factory Constructor for Start Requests Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker/worker_request.dart.gcov.html Creates a new request to start a worker, including channel information and arguments. The response is set to be inspected. ```dart factory WorkerRequest.start(PlatformChannel channelInfo, List args) => WorkerRequest._([ Timestamp.now(), // 0 - travel time channelInfo, // 1 - channel _connectCommand, // 2 - command args, // 3 - args null, // 4 - cancelation token null, // 5 - stream id true, // 6 - inspect response ]); ``` -------------------------------- ### Implement a Service with Squadron Source: https://github.com/d-markey/squadron/blob/main/README.md Define a class with background logic using @SquadronService and @SquadronMethod annotations. This example shows a simple 'hello' method. ```dart // file: hello_world.dart import 'dart:async'; import 'package:squadron/squadron.dart'; import 'hello_world.activator.g.dart'; part 'hello_world.worker.g.dart'; @SquadronService(baseUrl: '~/workers', targetPlatform: TargetPlatform.all) base class HelloWorld { @SquadronMethod() FutureOr hello([String? name]) { name = name?.trim() ?? 'World'; return 'Hello, $name!'; } } ``` -------------------------------- ### WorkerService Bootstrapping Function Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/bootstrapper.dart.gcov.html This function initializes and installs a WorkerService. The 'command' argument is ignored on Web platforms but must be set to the Isolate's startup parameter on native platforms. ```dart /// Instantiates a [WorkerService] via the [initializer] and installs the service in a platform worker. /// The [command] argument is ignored on Web platforms. On native platforms, the [command] argument **must /// be** set to the [Isolate]'s startup parameter. void run(WorkerInitializer initializer, [WorkerRequest? command]) => impl.bootstrap(initializer, command); ``` -------------------------------- ### Add Squadron Dependencies to pubspec.yaml Source: https://github.com/d-markey/squadron/wiki/Getting-Started Include squadron in your dependencies and squadron_builder with build_runner in your dev_dependencies. Run 'dart pub get' to install. ```yaml dependencies: squadron: ^7.4.0 dev_dependencies: build_runner: squadron_builder: ^9.0.0 ``` -------------------------------- ### Open Native Channel Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_channel.dart.gcov.html Starts an Isolate using the provided entry point and arguments. It sets up communication channels for requests, errors, and exit signals, and returns a future that completes with the connected channel. ```dart Future openChannel( EntryPoint entryPoint, ExceptionManager exceptionManager, Logger? logger, List startArguments, PlatformThreadHook? hook, ) async { final completer = Completer<_VmChannel>(); Channel? channel; void $failure(Object error, [StackTrace? stackTrace]) { if (!completer.isCompleted) { completer.completeError(SquadronException.from(error, stackTrace)); } } void $success(_VmChannel channel) { if (!completer.isInitialized) { completer.complete(channel); } } final receiver = vm.ReceivePort(); final exitPort = vm.ReceivePort(); final errorPort = vm.ReceivePort(); exitPort.listen((message) { $failure(SquadronErrorImpl.create('Connection to worker failed')); logger?.t('Isolate terminated with message $message.'); channel?.close(); receiver.close(); errorPort.close(); exitPort.close(); }); errorPort.listen((message) { SquadronException? error; try { final data = jsonDecode(message[0]); if (data is List) { error = exceptionManager.deserialize(data.cast()); } } catch (_) { // not a String representing a SquadronException } error ??= WorkerException( message[0], SquadronException.loadStackTrace(message[1]), ); logger?.d(() => 'Unhandled error from Isolate: ${error?.message}.'); $failure(error); }); final disconnected = DisconnectedChannel(exceptionManager, logger); receiver.listen((message) { final response = WorkerResponse.from(message); if (!response.unwrapInPlace(disconnected)) { return; } final error = response.error; if (error != null) { logger?.e(() => 'Connection to Isolate failed: $error'); $failure(error); } else if (response.endOfStream) { logger?.w('Disconnecting from Isolate'); channel?.close(); } else if (!completer.isCompleted) { logger?.t('Connected to Isolate'); final platformChannel = _VmChannel._(response.result, logger, exceptionManager); channel = platformChannel; $success(platformChannel); } else { logger?.e(() => 'Unexpected response: $response'); } }); final startRequest = WorkerRequest.start(receiver.sendPort, startArguments); startRequest.wrapInPlace(); final isolate = await vm.Isolate.spawn( entryPoint, startRequest, errorsAreFatal: false, onExit: exitPort.sendPort, onError: errorPort.sendPort, ); try { final channel = await completer.future; channel._thread = isolate; if (hook != null) { await hook.call(isolate); } logger?.t('Created Isolate'); return channel; } ``` -------------------------------- ### Starting the Worker Pool Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/worker_pool.dart.gcov.html Ensures that at least a minimum number of workers are started. If the queue is empty, it provisions one worker; otherwise, it provisions based on the queue length. Returns a future that completes when the provisioning is done. ```Dart @override Future start() { _stopped = false; final needs = _getProvisionNeeds(_queue.isEmpty ? 1 : _queue.length); return (needs > 0) ? _provisionWorkers(needs) : Future.value(); } ``` -------------------------------- ### Begin Request Monitoring Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_worker_runner.dart.gcov.html Starts monitoring the execution of a worker request. It increments the executing count and associates the request's cancelation token with a reference. ```dart CancelationTokenReference _begin(WorkerRequest request) { _executing++; final token = _getTokenRef(request.cancelToken); token.usedBy(request); return token; } ``` -------------------------------- ### Get Platform Type Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_platform.dart.gcov.html Returns the platform type as 'unknown'. This is a placeholder and might be updated in a more complete implementation. ```dart SquadronPlatformType getPlatformType() => SquadronPlatformType.unknown; ``` -------------------------------- ### Dart: indexWhere Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Returns the index of the first element that satisfies the provided test function, or -1 if none is found. The search starts from the optional 'start' index. ```dart @override int indexWhere(bool Function(E element) test, [int start = 0]) { final l = length; for (var i = start; i < l; i++) { if (test(_get(i))) return i; } return -1; } ``` -------------------------------- ### Correct Type Casting with Context Converter Source: https://github.com/d-markey/squadron/wiki/Converters This example demonstrates the recommended way to cast values using the context's converter, ensuring cross-platform compatibility by handling potential type discrepancies like int-as-double. ```dart // GOOD (handles int-as-double cases automatically) final age = context.converter.value()(data[1]); ``` -------------------------------- ### Get Converter Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/squadron_singleton.dart.gcov.html Provides access to the current converter instance. ```dart static Converter get converter => _converter; ``` -------------------------------- ### Bootstrap Worker Initialization Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_bootstrapper.dart.gcov.html Initializes a worker by setting up a ReceivePort, a WorkerRunner, and connecting the command to the worker. This function is crucial for starting worker processes in a native environment. ```dart import 'dart:isolate'; import '../../typedefs.dart'; import '../../worker/worker_request.dart'; import '../xplat/_worker_runner.dart'; import '_worker_runner.dart'; void bootstrap(WorkerInitializer initializer, WorkerRequest? command) { final workerPort = ReceivePort(); final runner = WorkerRunner((r) { r.internalLogger.t('Terminating Isolate'); workerPort.close(); Isolate.current.kill(priority: Isolate.beforeNextEvent); }); workerPort.listen(runner.handle); runner.connect(command, workerPort.sendPort, initializer); } ``` -------------------------------- ### Dart: indexOf Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Returns the first index in which the specified element can be found in the list, or -1 if it is not present. The search starts from the optional 'start' index. ```dart @override int indexOf(E element, [int start = 0]) { final l = length; for (var i = start; i < l; i++) { if (_get(i) == element) return i; } return -1; } ``` -------------------------------- ### Get Platform Type Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/squadron_singleton.dart.gcov.html Statically retrieves the current platform type using the platform-specific implementation. ```dart static final platformType = impl.getPlatformType(); ``` -------------------------------- ### Configuring Channel Logger in Main Thread Source: https://github.com/d-markey/squadron/wiki/Internal-Logging-Mechanism Example of configuring a channelLogger on the main thread to receive and process logs from worker threads. Log filtering is based on the level set here. ```dart final mainLogger = Logger( printer: SimplePrinter(), level: Level.info, ); final worker = MyServiceWorker(); worker.channelLogger = mainLogger; await worker.start(); ``` -------------------------------- ### Get Platform Type Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_platform.dart.gcov.html Returns the platform type as SquadronPlatformType.vm. ```dart SquadronPlatformType getPlatformType() => SquadronPlatformType.vm; ``` -------------------------------- ### WorkerStreamTask Constructor and Stream Initialization Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/_worker_stream_task.dart.gcov.html Initializes the WorkerStreamTask and sets up the ForwardStreamController. It handles the initial listen event to start data production from the worker. ```dart WorkerStreamTask(this._producer, PerfCounter? counter) : super(counter) { _controller = ForwardStreamController(onListen: () async { try { if (canceledException != null) { // the task was canceled throw canceledException!; } final worker = await _worker.future; if (canceledException != null || worker == null) { // the task was canceled throw canceledException!; } else { // otherwise, forward data from the worker _controller.attachSubscription(_producer(worker).listen( _controller.safeAdd, onError: (ex, st) => _controller.safeAddError(SquadronException.from(ex, st)), onDone: _controller.close, cancelOnError: false, )); } } catch (ex, st) { _closeWithError(SquadronException.from(ex, st)); } }); } ``` -------------------------------- ### Worker Unmount and Service Uninstallation Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_worker_runner.dart.gcov.html Handles the unmounting of the worker, including the uninstallation of any associated services. It ensures that installation is complete before attempting to uninstall and logs any uninstallation errors. ```dart void _unmount() async { try { // uninstall the service if necessary if (_service is ServiceInstaller) { // check installation result final pendingInstallation = _installCompleter?.future; if (pendingInstallation != null) { await pendingInstallation; _installCompleter = null; } if (_installError == null) { // uninstall iif the service installed succesfuly await (_service as ServiceInstaller).uninstall(); } } } catch (ex) { internalLogger.e('Service uninstallation failed with error: $ex'); } finally { _exit(); } } ``` -------------------------------- ### Stateful Worker Example with Potential Corruption Source: https://github.com/d-markey/squadron/wiki/Stateful-Workers Demonstrates a service storing intermediate state in a field. Without `maxParallel: 1`, concurrent calls can corrupt this state between `await` points. ```dart @SquadronService() base class SessionService { String? _currentUser; @SquadronMethod() Future login(String user) async { _currentUser = user; // (1) await _initSession(); // (2) — yields here! } @SquadronMethod() Future whoAmI() async => _currentUser; } ``` -------------------------------- ### Worker send Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker/worker.dart.gcov.html Sends a command and arguments to the worker. It ensures the worker is started if not already connected and handles request inspection and cancellation tokens. The response is returned as a Future. ```dart @override Future send( int command, { List args = const [], CancelationToken? token, bool inspectRequest = false, bool inspectResponse = false, }) async { token?.throwIfCanceled(); // get the channel, start the worker if necessary final channel = _channel ?? await start(); final completer = ForwardCompleter(); final squadronToken = token?.wrap(); squadronToken?.onCanceled.then((ex) { _channel?.cancelToken(squadronToken); completer.failure(SquadronException.from(ex, null, command)); }); _stats.beginWork(); completer.future.whenComplete(_stats.endWork).ignore(); try { final res = await channel.sendRequest( command, args, token: squadronToken, inspectRequest: inspectRequest, inspectResponse: inspectResponse, ); completer.success(res); } catch (ex, st) { _stats.failed(); completer.failure(SquadronException.from(ex, st, command)); } return completer.future; } ``` -------------------------------- ### Handle Stream Listen Event Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_result_stream.dart.gcov.html Initiates the request when the stream is listened to. It checks for cancellation tokens and then starts listening to the request's response stream, directing responses to the appropriate decoding function. ```dart void $onListen() { try { // do not send the request if the token is already canceled token?.throwIfCanceled(); // send the request and start decoding responses _controller.attachSubscription(sendRequest().listen( streaming ? $decodeStreamOfResponses : $decodeSingleResponse, onError: $closeWithError, onDone: _controller.close, cancelOnError: false, )); } catch (e) { $closeWithError(e); } } ``` -------------------------------- ### Configuring Log Level for Squadron Source: https://github.com/d-markey/squadron/wiki/Observability-and-Logging Adjust the verbosity of Squadron's internal logging by setting the logger's level. This example sets the level to 'debug'. ```dart // Set the logger to capture debug-level and above logger.level = Level.debug; worker.channelLogger = logger; ``` -------------------------------- ### Custom Logger in Worker Service Source: https://github.com/d-markey/squadron/wiki/Internal-Logging-Mechanism Example of a worker service implementing its own Logger instance. Output from this logger will be automatically forwarded to the main thread's channelLogger. ```dart class MyService implements WorkerService { final myLogger = Logger( printer: PrettyPrinter(), level: Level.debug, ); void processRequest(String data) { myLogger.i('Processing request with data: $data'); // ... processing logic ... myLogger.d('Request completed successfully'); } @override late final operations = OperationsMap({ 1: (r) => processRequest(r.args[0] as String), }); } ``` -------------------------------- ### Get Sublist Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Returns a new list containing elements from 'start' index up to (but not including) the 'end' index. If 'end' is null, it goes to the end of the list. ```dart List sublist(int start, [int? end]) => getRange(start, end ?? length).toList(); ``` -------------------------------- ### Implement Custom Person Marshaler Source: https://github.com/d-markey/squadron/wiki/Marshaling Example of implementing `SquadronMarshaler` to serialize and deserialize a `Person` object to and from a `List` of primitives. The `marshal` method converts the object to a list, and `unmarshal` reconstructs the object from the list. ```dart class Person { final String name; final int age; Person(this.name, this.age); } class PersonMarshaler implements SquadronMarshaler { const PersonMarshaler(); @override List marshal(Person data, [MarshalingContext? context]) { return [data.name, data.age]; } @override Person unmarshal(List data, [MarshalingContext? context]) { // Rehydrate return Person( data[0] as String, context?.converter.value()(data[1]) ?? data[1] as int ); } } ``` -------------------------------- ### Compile Worker Entry Points for Web Source: https://github.com/d-markey/squadron/blob/main/README.md Compile worker entry points for web targets. Squadron automatically detects the runtime environment and selects the appropriate implementation. ```bash # Compile to JavaScript dart compile js ".\src\lib\hello_world.web.g.dart" -o "..\web\workers\hello_world.web.g.dart.js" # Compile to Web Assembly dart compile wasm ".\src\lib\hello_world.web.g.dart" -o "..\web\workers\hello_world.web.g.dart.wasm" ``` -------------------------------- ### Compile Worker to WebAssembly Source: https://github.com/d-markey/squadron/wiki/Platform-Support Compile a generated worker entry point to a WebAssembly file for web deployment. Ensure the output path is accessible by your web server. ```bash dart compile wasm "lib/hello.web.g.dart" -o "web/workers/hello.web.g.dart.wasm" ``` -------------------------------- ### Dart: lastIndexOf Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Returns the index of the last occurrence of the specified element in the list, or -1 if not found. The search starts from the optional 'start' index and proceeds backward. ```dart @override int lastIndexOf(E element, [int? start]) { for (var i = start ?? (length - 1); i >= 0; i--) { if (element == _get(i)) return i; } return -1; } ``` -------------------------------- ### Static Channel Methods Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/channel.dart.gcov.html Provides static methods for creating and managing Channel instances, including opening new channels and deserializing existing ones. ```APIDOC ## Static Channel Methods ### Description Utility methods for managing `Channel` instances. ### Methods #### `static Future open( ExceptionManager exceptionManager, Logger? logger, EntryPoint entryPoint, List startArguments, PlatformThreadHook? hook, )` Starts a worker and opens a new channel. #### `static Channel? deserialize( PlatformChannel? channelInfo, Logger? logger, ExceptionManager? exceptionManager, )` Deserializes a `Channel` from platform-specific channel information. ``` -------------------------------- ### Instantiate and Use a Worker Source: https://github.com/d-markey/squadron/blob/main/README.md Instantiate a worker and use it like a normal service. Remember to always stop your workers using `worker.stop()` to prevent indefinite program execution. ```dart import 'hello_world.dart'; void main() async { final worker = HelloWorldWorker(); try { // Squadron starts the worker automatically on the first call final message = await worker.hello('Squadron'); print(message); } finally { worker.stop(); // Clean up the background thread } } ``` -------------------------------- ### Dart: lastIndexWhere Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Returns the index of the last element that satisfies the provided test function, or -1 if none is found. The search starts from the optional 'start' index and proceeds backward. ```dart @override int lastIndexWhere(bool Function(E element) test, [int? start]) { for (var i = start ?? (length - 1); i >= 0; i--) { if (test(_get(i))) return i; } return -1; } ``` -------------------------------- ### Initializing ForwardStreamController Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_result_stream.dart.gcov.html Initializes a ForwardStreamController with listen and cancel callbacks. ```Dart _controller = ForwardStreamController( onListen: $onListen, onCancel: $onCancel, ); ``` -------------------------------- ### Dart: setRange Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Replaces the elements of the list within the specified inclusive start and exclusive end indices with the elements from the given iterable, starting from the specified skipCount. The number of elements replaced is equal to the number of elements in the iterable minus skipCount. ```dart @override void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) => _data.setRange(start, end, iterable, skipCount); ``` -------------------------------- ### Run Builder with Output Conflict Resolution Source: https://github.com/d-markey/squadron/wiki/Installation-and-Generation Use this command to generate code and automatically resolve output conflicts. This can be useful for ensuring generated files are correctly formatted. ```bash dart run build_runner build --delete-conflicting-outputs ``` -------------------------------- ### Worker Initialization and Stream Handling Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker/worker.dart.gcov.html Initializes the `ForwardStreamController` and sets up the stream subscription for handling requests. It includes error handling and ensures the controller is closed properly. ```dart controller = ForwardStreamController(onListen: () async { try { if (controller.isClosed) return; squadronToken?.throwIfCanceled(); final channel = _channel ?? await start(); if (controller.isClosed) return; _stats.beginWork(); controller.done.whenComplete(_stats.endWork).ignore(); controller.attachSubscription(channel .sendStreamingRequest( command, args, token: squadronToken, inspectRequest: inspectRequest, inspectResponse: inspectResponse, ) .listen( controller.safeAdd, onError: (ex, st) => controller .safeAddError(SquadronException.from(ex, st, command)), onDone: controller.close, cancelOnError: false, )); } catch (ex, st) { _stats.failed(); controller.subscription?.cancel(); controller.safeAddError(SquadronException.from(ex, st, command)); controller.close(); } }); return controller.stream; ``` -------------------------------- ### Get Platform Converter Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_platform.dart.gcov.html Returns the instance of CastConverter for platform-specific conversions. ```dart Converter getPlatformConverter() => CastConverter.instance; ``` -------------------------------- ### Getting Stream Completion Future Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_result_stream.dart.gcov.html Returns a Future that completes when the stream has been closed. ```Dart Future get done => _controller.done; ``` -------------------------------- ### Getting Pending Workload Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/worker_pool.dart.gcov.html Returns the number of tasks currently waiting in the queue to be processed. ```Dart int get pendingWorkload => _queue.length; ``` -------------------------------- ### Compile Worker to JavaScript Source: https://github.com/d-markey/squadron/wiki/Platform-Support Compile a generated worker entry point to a JavaScript file for web deployment. Ensure the output path is accessible by your web server. ```bash dart compile js "lib/hello.web.g.dart" -o "web/workers/hello.web.g.dart.js" ``` -------------------------------- ### Import platform utility Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_token_id.dart.gcov.html Imports platform-specific utilities, likely including threadId. ```dart import '_platform.dart'; ``` -------------------------------- ### Import Utils Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_platform.dart.gcov.html Imports utility functions. ```dart import '../../utils.dart'; ``` -------------------------------- ### Import Meta Package Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_platform.dart.gcov.html Imports the meta package for annotations like @internal. ```dart import 'package:meta/meta.dart'; ``` -------------------------------- ### Get Cancelation Token Reference Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_worker_runner.dart.gcov.html Retrieves or creates a CancelationTokenReference for a given SquadronCancelationToken. If the token is null, it returns a no-token reference. ```dart CancelationTokenReference _getTokenRef(SquadronCancelationToken? token) => (token == null) ? CancelationTokenReference.noToken : _cancelTokens.putIfAbsent( token.id, () => CancelationTokenReference(token.id)); ``` -------------------------------- ### Get Active Connections Count Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_channel.dart.gcov.html Returns the number of active connections for a given channel. Returns 0 if the channel is not a _VmChannel. ```dart @internal int getActiveConnections(Channel channel) => (channel is _VmChannel) ? channel._activeConnections.length : 0; ``` -------------------------------- ### Generate Worker Code with Build Runner Source: https://github.com/d-markey/squadron/wiki/Getting-Started Run the build runner command to generate the necessary worker plumbing files. ```bash dart run build_runner build ``` -------------------------------- ### Get Thread ID Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_platform.dart.gcov.html Retrieves the current thread ID. This function delegates to an implementation specific to the platform (web or native). ```dart String get threadId => impl.threadId; ``` -------------------------------- ### Basic Worker Usage Source: https://github.com/d-markey/squadron/wiki/Workers-and-Pools Instantiate and use a single Worker for simple task offloading. Remember to stop the worker to terminate its thread. ```dart final worker = MyServiceWorker(); await worker.doWork(); worker.stop(); // Terminates the thread ``` -------------------------------- ### Setting Up Channel Logger for a Worker Source: https://github.com/d-markey/squadron/wiki/Observability-and-Logging Configure a worker to use a custom logger instance for observing internal events. Ensure the 'logger' package is imported. ```dart import 'package:logger/logger.dart'; import 'package:squadron/squadron.dart'; void main() async { // Create a logger instance final logger = Logger( printer: PrettyPrinter(), level: Level.debug, ); // Create and configure your worker final worker = MyServiceWorker(); worker.channelLogger = logger; // Start the worker - internal events will now be logged await worker.start(); // Use the worker normally await worker.doSomething(); } ``` -------------------------------- ### Get Full Worker Statistics Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/worker_pool.dart.gcov.html Returns statistics for all workers, including active and previously dead workers. Useful for historical analysis. ```dart Iterable get fullStats => _deadWorkerStats.followedBy(stats); ``` -------------------------------- ### Get Worker Statistics Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/worker_pool.dart.gcov.html Provides an iterable of WorkerStat objects for all active workers in the pool. Used for monitoring worker performance and status. ```dart Iterable get stats => _workers.map(PoolWorker.getStats); ``` -------------------------------- ### Import Statements Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/bootstrapper.dart.gcov.html These lines import necessary platform-specific implementations and type definitions for the bootstrapper functionality. ```dart import '_impl/xplat/_bootstrapper.dart'; ``` ```dart if (dart.library.io) '_impl/native/_bootstrapper.dart' ``` ```dart if (dart.library.html) '_impl/web/_bootstrapper.dart' ``` ```dart if (dart.library.js) '_impl/web/_bootstrapper.dart' ``` ```dart if (dart.library.js_interop) '_impl/web/_bootstrapper.dart' as impl; ``` ```dart import 'typedefs.dart'; ``` ```dart import 'worker/worker_request.dart'; ``` ```dart import 'worker_service.dart'; ``` -------------------------------- ### LazyInPlaceList Length Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Gets or sets the length of the list. Setting a larger length may result in null values if not explicitly filled. ```dart @override int get length => _data.length; @override set length(int value) { if (value > length) null as E; _data.length = value; } ``` -------------------------------- ### Native VM Worker Entry Point Source: https://github.com/d-markey/squadron/wiki/Manual-Implementation The entry point for native Dart VM workers. It initializes the Squadron service using `Squadron.run` and provides the service implementation. ```dart void start(List args) => Squadron.run((startRequest) => MyServiceImpl(), args); ``` -------------------------------- ### Get Thread ID Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_platform.dart.gcov.html Retrieves the unique thread ID for the current isolate. Note that thread IDs may not be unique on the VM. ```dart final threadId = Isolate.current.hashCode.hex; ``` -------------------------------- ### WorkerClient Constructor Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker_client.dart.gcov.html Initializes a WorkerClient with a given channel. The channel must be obtained from the target Worker. ```dart WorkerClient(this.channel); ``` -------------------------------- ### Incorrect Type Casting Source: https://github.com/d-markey/squadron/wiki/Converters This example shows an incorrect way to cast a value that might fail on Web Assembly due to type differences. ```dart // BAD (might fail on Wasm if age comes in as double) final age = data[1] as int; ``` -------------------------------- ### Worker-Side Service Initialization Source: https://github.com/d-markey/squadron/wiki/Service-Setup Define services with constructor arguments that are automatically transferred to the worker thread by squadron_builder. Use this for providing configuration or dependencies to your services. ```dart @SquadronService() class MyService { // Arguments passed here will be managed by squadron_builder MyService(this.config, this.apiKey); final Map config; final String apiKey; @SquadronMethod() Future doWork() async { // Service is already initialized with config and apiKey } } ``` ```dart final worker = MyServiceWorker(config, apiKey); ``` -------------------------------- ### IdentityMarshaler Class Definition Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/marshalers/identity_marshaler.dart.gcov.html Defines the IdentityMarshaler class, which acts as a pass-through for data during marshaling and unmarshaling. It requires no specific setup beyond its instantiation. ```dart import 'marshaling_context.dart'; import 'squadron_marshaler.dart'; /// Identity marshaler. final class IdentityMarshaler extends SquadronMarshaler { const IdentityMarshaler(); @override T marshal(T data, [MarshalingContext? context]) => data; @override T unmarshal(T data, [MarshalingContext? context]) => data; } ``` -------------------------------- ### Web WASM Worker Entry Point Source: https://github.com/d-markey/squadron/wiki/Manual-Implementation The entry point for web-based workers compiled to WASM. It initializes the Squadron service using `Squadron.run`. ```dart void main() => Squadron.run((startRequest) => MyServiceImpl()); ``` -------------------------------- ### LazyInPlaceList Get Last Element Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Retrieves the last element of the list, converting it if necessary. Setting the last element directly updates the underlying data. ```dart @override E get last => _get(length - 1); @override set last(E value) => _data[length - 1] = value; ``` -------------------------------- ### WorkerValueTask Constructor Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/pool/_worker_value_task.dart.gcov.html Initializes a new WorkerValueTask with a computer function and an optional performance counter. ```dart WorkerValueTask(this._computer, PerfCounter? counter) : super(counter); ``` -------------------------------- ### LazyInPlaceList Get First Element Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Retrieves the first element of the list, converting it if necessary. Setting the first element directly updates the underlying data. ```dart @override E get first => _get(0); @override set first(E value) => _data[0] = value; ``` -------------------------------- ### Dart: removeRange Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Removes the elements of the list within the specified inclusive start and exclusive end indices. Elements after the removed range are shifted to the left. ```dart @override void removeRange(int start, int end) => _data.removeRange(start, end); ``` -------------------------------- ### Create Service Client Proxy Source: https://github.com/d-markey/squadron/wiki/Manual-Implementation Implement the service interface on the main thread using `WorkerClient`. This proxy forwards commands to the worker via a `Channel`, allowing remote workers to be treated like local services. ```dart // '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 add(int a, int b) => send( MyService.addCommand, args: [a, b] ); } ``` -------------------------------- ### ResultStream Constructor Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_result_stream.dart.gcov.html Initializes a ResultStream with channel, request, a function to send requests, and a flag indicating if streaming is enabled. It sets up completers for stream IDs and command/token details. ```dart ResultStream( Channel channel, WorkerRequest req, Stream Function() sendRequest, bool streaming, ) { final streamIdCompleter = streaming ? Completer() : null; final command = req.command, token = req.cancelToken; ``` -------------------------------- ### ParentService with Shared ChildService Source: https://github.com/d-markey/squadron/wiki/Worker-Orchestration Demonstrates how to inject a child service into a parent service using the `@sharedService` annotation. The parent can then use the injected child service to offload sub-tasks. ```dart @SquadronService() class ParentService { ParentService(@sharedService ChildService child) : _child = child; final ChildService _child; @SquadronMethod() Future doSomethingComplex() async { // ParentService can now use _child to offload sub-tasks await _child.subTask(); } } ``` -------------------------------- ### Dart: setAll Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Replaces the elements of the list with the elements from the given iterable, starting from the specified index. The number of elements replaced is equal to the number of elements in the iterable. ```dart @override void setAll(int index, Iterable iterable) => _data.setAll(index, iterable); ``` -------------------------------- ### Define Service Interface Source: https://github.com/d-markey/squadron/wiki/Manual-Implementation Define the contract for your service, including methods and their corresponding Command IDs. This class serves as the blueprint for both the implementation and the client. ```dart abstract class MyService { Future add(int a, int b); // Command IDs are used to identify which method to call static const addCommand = 1; } ``` -------------------------------- ### Run Squadron Code Builder Source: https://github.com/d-markey/squadron/wiki/Installation-and-Generation Execute the build_runner to generate necessary worker code. Use the 'build' command for a one-time generation or 'watch' to automatically rebuild when files change. ```bash dart run build_runner build ``` ```bash dart run build_runner watch ``` -------------------------------- ### Setting Up Channel Logger for a Worker Pool Source: https://github.com/d-markey/squadron/wiki/Observability-and-Logging Assign a logger instance to a worker pool to enable logging for all workers within that pool. The pool's logger will be used by all its workers. ```dart final pool = MyServiceWorkerPool(); pool.channelLogger = logger; await pool.start(); // All workers in the pool will use the same logger ``` -------------------------------- ### PlatformThreadHook Type Definition Source: https://github.com/d-markey/squadron/wiki/Service-Setup Defines the signature for a function that can configure the underlying platform thread (Isolate or Web Worker) before service execution. This is useful for low-level thread setup. ```dart typedef PlatformThreadHook = FutureOr Function(PlatformThread thread); ``` -------------------------------- ### TargetPlatform Extension for Platform Checks Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/annotations/target_platform.dart.gcov.html Provides methods to check if a given platform integer includes VM, JS, or WASM. ```dart extension TargetPlatformExt on int { bool get hasVm => (this & TargetPlatform.vm) != 0; bool get hasJs => (this & TargetPlatform.js) != 0; bool get hasWasm => (this & TargetPlatform.wasm) != 0; } ``` -------------------------------- ### SquadronException Initialization Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/exceptions/squadron_exception.dart.gcov.html Initializes a SquadronException, capturing the current stack trace if none is provided. ```dart SquadronException.init(this.message, [this._stackTrace]) { if (_stackTrace == null) { try { _stackTrace = StackTrace.current; } catch (_, st) { // failed, take the opportunity to get the stack trace from this exception! _stackTrace = st; } } } ``` -------------------------------- ### Import Dart Isolate Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/native/_platform.dart.gcov.html Imports the Dart Isolate library for concurrency features. ```dart import 'dart:isolate'; ``` -------------------------------- ### Apply Marshaler on Service Method Source: https://github.com/d-markey/squadron/wiki/Marshaling Shows how to apply a custom marshaler to a specific parameter of a Squadron service method. This allows for selective marshaling of arguments. ```dart @SquadronService() class MyService { @SquadronMethod() Future savePerson(@PersonMarshaler() Person p) async { ... } } ``` -------------------------------- ### Get Element with Type Casting Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Retrieves an element at a specific index, performing a type cast if the element is not already of the expected type 'E'. The cast element is then updated in the underlying data. ```dart E _get(int idx) { dynamic v = _data[idx]; if (v != null && v is! E) { v = _cast(v); _data[idx] = v; } return v; } ``` -------------------------------- ### Worker Pool Initialization and Usage Source: https://github.com/d-markey/squadron/wiki/Workers-and-Pools Set up a WorkerPool with specific concurrency settings to manage multiple workers for high concurrency. The pool handles load balancing and scaling. ```dart final pool = MyServiceWorkerPool( concurrencySettings: ConcurrencySettings( minWorkers: 2, maxWorkers: 4, maxParallel: 2, // tasks per worker before spinning up a new one ) ); await pool.start(); // ... await pool.doWork(); // Dispatched to one of the workers // ... pool.stop(); // Stops all workers ``` -------------------------------- ### Dart: replaceRange Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Replaces the elements of the list within the specified inclusive start and exclusive end indices with the elements from the given iterable. The existing elements are removed, and the new elements are inserted in their place. ```dart @override void replaceRange(int start, int end, Iterable replacements) => _data.replaceRange(start, end, replacements); ``` -------------------------------- ### Apply Marshaler on Class Source: https://github.com/d-markey/squadron/wiki/Marshaling Demonstrates applying a custom marshaler directly to a Dart class using an annotation. This is the recommended approach for Data Transfer Objects (DTOs) that you own. ```dart @PersonMarshaler() class Person { // ... } ``` -------------------------------- ### Get Stream ID with Subscription Management Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_result_stream.dart.gcov.html Retrieves the stream ID from the completer's future. If the subscription is paused and the stream ID is not yet available, it resumes the subscription. It also restores the subscription's pause state after retrieval. ```dart Future $getStreamId(StreamSubscription sub) { streamIdCompleter as Completer; var count = 0; if (sub.isPaused && !streamIdCompleter.isCompleted) { // if the subscription was paused and the streamId is not available, // resume to have the streamId eventually come through. while (sub.isPaused) { count++; sub.resume(); } } // wait for the streamId... return streamIdCompleter.future.then((streamId) { while (count > 0) { count--; sub.pause(); } return streamId; }); // restore subscription pause } ``` -------------------------------- ### Import Dart Completer Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_forward_completer.dart.gcov.html Imports the Dart Completer class for managing asynchronous operations. ```dart import 'dart:async'; ``` -------------------------------- ### ForwardStreamController Constructor Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_forward_stream_controller.dart.gcov.html Initializes a ForwardStreamController with optional callbacks for listen, pause, resume, and cancel events. It sets up an internal StreamController to manage the stream. ```dart ForwardStreamController({ void Function()? onListen, FutureOr Function()? onCancel, }) { _controller = StreamController( onListen: onListen, onPause: _pause, onResume: _resume, onCancel: onCancel, ); } ``` -------------------------------- ### Expose a Method in a Squadron Service Source: https://github.com/d-markey/squadron/wiki/Defining-Services Annotate methods with `@SquadronMethod()` to make them callable from the worker. All methods must be asynchronous. ```dart @SquadronMethod() Future add(int a, int b) async => a + b; ``` -------------------------------- ### WorkerResponse Factory Constructors Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker/worker_response.dart.gcov.html Demonstrates the factory constructors for creating different types of WorkerResponse objects: ready, withResult, withError, log, and closeStream. These constructors help in packaging data, errors, or status updates for worker communication. ```dart factory WorkerResponse.from(List data) { if (data.length != 5) { throw SquadronErrorImpl.create('Invalid worker response'); } return WorkerResponse._(data); } ``` ```dart factory WorkerResponse.ready([bool status = true]) => WorkerResponse._([ Timestamp.now(), // 0 - travel time status, // 1 - ready null, // 2 - error null, // 3 - end of stream null, // 4 - log message ]); ``` ```dart factory WorkerResponse.withResult(dynamic result) => WorkerResponse._([ Timestamp.now(), // 0 - travel time result, // 1 - result null, // 2 - error null, // 3 - end of stream null, // 4 - log message ]); ``` ```dart factory WorkerResponse.withError(SquadronException exception, [StackTrace? stackTrace]) => WorkerResponse._([ Timestamp.now(), // 0 - travel time null, // 1 - result exception, // 2 - error null, // 3 - end of stream null, // 4 - log message ]); ``` ```dart factory WorkerResponse.log(LogEvent message) => WorkerResponse._([ Timestamp.now(), // 0 - travel time null, // 1 - result null, // 2 - error null, // 3 - end of stream message, // 4 - log message ]); ``` ```dart factory WorkerResponse.closeStream() => WorkerResponse._([ Timestamp.now(), // 0 - travel time null, // 1 - result null, // 2 - error true, // 3 - end of stream null, // 4 - log message ]); ``` -------------------------------- ### Stateful Service Implementation for Transactions Source: https://github.com/d-markey/squadron/wiki/Stateful-Workers The background thread service implementation for transactional patterns. It uses fields to store pending entries and provides methods for beginning, processing, committing, and rolling back transactions. ```dart @SquadronService() base class LedgerService { final _pendingEntries = []; @SquadronMethod() Future begin() async { _pendingEntries.clear(); } @SquadronMethod() Future processEntry(String entry) async { Entry value; // ... compute ... _pendingEntries.add(value); } @SquadronMethod() Future commit() async { final count = _pendingEntries.length; // ... persist _pendingEntries to storage ... _pendingEntries.clear(); return count; } @SquadronMethod() Future rollback() async { _pendingEntries.clear(); } } ``` -------------------------------- ### ServiceInstaller Mixin Definition Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/service_installer.dart.gcov.html Defines the ServiceInstaller mixin for worker services. Use this mixin to add custom logic for worker thread initialization and shutdown. ```dart import 'dart:async'; import 'worker/worker.dart'; /// Extend this class or implement this interface in your worker service if it needs /// to take action when the worker thread is started or stopped. mixin ServiceInstaller { /// Squadron will call this method as part of the worker thread initialization. /// It will be called just after the service instance has been constructed. The /// future returned by [Worker.start] will not complete before this method completes /// whether synchronously or asynchronously. If this method throws, the future /// returned by [Worker.start] will complete with an error and the service will not /// be available. FutureOr install() {} /// Squadron will call this method as part of the worker thread shutdown process. /// It will be called just before effectively closing the platform channel. If /// this method throws, the exception will not bubble up to the parent thread. /// Also, [Worker.stop] does not wait for this method to complete. FutureOr uninstall() {} } ``` -------------------------------- ### Worker Constructor Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/worker/worker.dart.gcov.html Initializes a Worker instance with an entry point and optional thread hook or exception manager. The stats are initialized upon creation. ```dart Worker(this._entryPoint, {PlatformThreadHook? threadHook, ExceptionManager? exceptionManager}) : _threadHook = threadHook, _exceptionManager = exceptionManager { _stats = _Stats(this); } ``` -------------------------------- ### Dart: forEach Method Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/converters/lazy_in_place_list.dart.gcov.html Executes a provided function once for each element in the list. It iterates through the list and applies the action to each element. ```dart @override void forEach(void Function(E element) action) { final l = length; for (var i = 0; i < l; i++) { action(_get(i)); } } ``` -------------------------------- ### Import Statements for _platform.dart Source: https://github.com/d-markey/squadron/blob/main/doc/coverage/html/src/_impl/xplat/_platform.dart.gcov.html These import statements bring in necessary libraries and platform-specific implementations for the squadron package. ```dart import 'package:meta/meta.dart'; import '../../converters/cast_converter.dart'; import '../../converters/converter.dart'; import '../../squadron_platform_type.dart'; import '../web/_platform.dart' if (dart.library.io) '../native/_platform.dart' as impl; ```