Squadron은 Isolate와 웹 워커 풀을 통해 멀티스레딩을 가능하게 하는 Dart/Flutter 패키지로, CPU 집약적이고 무거운 I/O 작업을 메인 스레드에서 분리할 수 있게 해줍니다. Android, iOS, Web, macOS, Windows, Linux 등 다양한 플랫폼에서 병렬 실행을 간편하게 처리할 수 있습니다. 네이티브 플랫폼에서는 Isolate를, 웹에서는 웹 워커를 활용함으로써 앱의 반응성과 성능을 향상시킵니다. 이 패키지는 워커 스레드 관리 및 작업 배포를 쉽게 처리할 수 있는 사용자 친화적인 API를 제공합니다.
사용 사례
CPU 집약적인 계산을 오프로드하기
대규모 파일 I/O 작업 처리
집중 작업 중 사용자 인터페이스 반응성 향상
백그라운드 데이터 처리 중
메인 스레드를 차단하지 않고 오랜 시간 실행되는 알고리즘을 실행하는 것
주요 기능
Isolate 및 Web Worker 풀을 지원합니다
크로스 플랫폼 호환성
간단한 작업 제출 API
자동 워커 관리
내장된 오류 처리
스레드 안전한 통신
적합한 대상
고성능 백그라운드 처리가 필요한 개발자
복잡한 데이터 변환을 가진 앱
미디어 또는 이미지 처리 앱
실시간 데이터 분석 도구
중량 작업 중에 반응성 있는 UI가 필요한 응용 프로그램
고려 사항
격리 및 동시성에 대한 이해가 필요합니다
많은 워커를 사용할 경우 메모리 사용량이 증가할 수 있습니다
웹 지원은 브라우저 기능에 의해 제한됨
경량 작업에 적합하지 않습니다
스레드 간 상태 관리에 주의가 필요합니다
원본 README
연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Squadron - Multithreading and worker pools in Dart
Offload CPU-bound and long running tasks and give your apps some air!
Works everywhere: Desktop, Server, Mobile, and Browser (JS & WASM).
Dart is single-threaded by nature. While Isolate.run() is great for one-off tasks, it creates overhead for frequent operations, and is not available on browser platforms.
Squadron provides:
🔄 Persistent Worker Pools: Keep workers alive and ready to process tasks instantly.
🌐 Seamless Web Support: Uniform API for Isolates (Native) and Web Workers (JS/Wasm).
🛡️ Type Safety: Automatic code generation ensures your thread boundaries are type-safe.
📡 Streaming: Native support for Stream return types from workers.
🏗️ Architecture
sequenceDiagram
autonumber
participant App as Main App (UI)
box rgb(40, 100, 200, 0.1) Squadron / Generated Code
participant Pool as HelloWorldWorkerPool/Worker
end
box rgb(0, 150, 0, 0.1) Background Thread
participant Service as User Service
end
App->>Pool: worker.hello('Squadron')
Pool->>Service: Assign Task (Marshaled)
activate Service
Note over Service: Executing on background Isolate/Web Worker
Service-->>Pool: Return Result (Unmarshaled)
deactivate Service
Pool-->>App: Future<String> Result
Squadron uses code generation to handle the boilerplate of thread communication. Run the following command:
dart run build_runner build
This creates HelloWorldWorker and HelloWorldWorkerPool. These classes implement the same interface as your service but proxy calls to background threads.
4. Running your Worker
In your application, instantiate the worker and use it like a normal service.
[!IMPORTANT] Always stop your workers. Failure to call worker.stop() will keep your program running indefinitely.
import'hello_world.dart';
voidmain() async {
final worker = HelloWorldWorker();
try {
// Squadron starts the worker automatically on the first callfinal message = await worker.hello('Squadron');
print(message);
} finally {
worker.stop(); // Clean up the background thread
}
}
🌍 Web Support (JS & Wasm)
Squadron is designed for a "write once, run anywhere" experience. When targeting the web, you must compile your worker entry points:
# 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"
Squadron will automatically detect the runtime environment and choose the correct implementation.
🛠️ Advanced Concepts
Data Transfer & Marshaling
Because workers run in separate memory spaces, data must be serialized ("marshaled") to cross thread boundaries. While base types (Strings, Numbers, Lists, Maps) are handled automatically, custom objects require a SquadronMarshaler.
Exceptions thrown in a worker are caught, serialized, and re-thrown on the caller's side, preserving the stack trace and error information where possible.
Debugging background workers can be tricky. Squadron provides mechanisms to forward log messages from workers back to the main thread's debugger or console.