isolate_pool_executor 1.2.0 copy "isolate_pool_executor: ^1.2.0" to clipboard
isolate_pool_executor: ^1.2.0 copied to clipboard

isolate pool executor for Dart.

The current package provides background creation of isolates to perform CPU-intensive tasks without affecting the current isolate. Just like a thread pool, but with isolates.

Usage #

int _doTask(int count) {
  int sum = 0;
  final random = new Random();
  for (int i = 0; i < count; i++) {
    sum += random.nextInt(10000);
  }
  return sum;
}

//单个的isolate 任务顺序执行
final pool1 = IsolatePoolExecutor.newSingleIsolateExecutor();

//固定数量的isolate 任务按空闲分配
final pool2 = IsolatePoolExecutor.newFixedIsolatePool(3);
// 不限制总数 但空闲一段事件后如无新任务自动销毁 添加任务时没有空闲的isolate时创建新的isolate,有空闲的使用空闲的isolate
final pool3 = IsolatePoolExecutor.newCachedIsolatePool();

//按需求自定义
final pool4 = IsolatePoolExecutor(
  // 核心数量,无任务时一直等待,需要shutdown后才会销毁
    corePoolSize: 2,
    // 总数 超过核心数之后的空闲一段时间后会自动销毁
    maximumPoolSize: 4,
    //非核心的isolate空闲等待时间
    keepAliveTime: Duration(seconds: 1),
    // 任务寄放队列
    taskQueue: Queue(),
    // 当队列添加失败时的处理方式
    handler: RejectedExecutionHandler.abortPolicy);

void doSomething() async {
  ///...doSomething
  // 用来提交任务
  final result = await pool1.compute(_doTask, 100000000);

  ///...doSomething
}

void willKillPool() {
  //终止池
  pool1.shutdown();
}



If you need to use MethodChannel in an isolate in Flutter, you can make the following adjustments.

Note: This feature requires Flutter SDK >= 3.7.

///something
//in mainIsolate
RootIsolateToken rootIsolateToken = RootIsolateToken.instance!;

final pool = IsolatePoolExecutor.newXXXXXPool(
    isolateValues: {'rootIsolateToken': rootIsolateToken},
    onIsolateCreated: (isolateValues) {
      //in background isolate run
      final rootIsolateToken = isolateValues['rootIsolateToken'];
      BackgroundIsolateBinaryMessenger
          .ensureInitialized(rootIsolateToken);
    }
);

///...doSomething


int? _doInBackgroundGetSharedPreferencesValue(String spKey) async {
  SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
  return sharedPreferences.getInt(spKey);
}

void doSomething() async {
  final result = await pool.compute(_doInBackgroundGetSharedPreferencesValue, 'spKey');
}

///...doSomething

If you encounter similar issues(https://github.com/flutter/flutter/issues/132731) in Flutter, you can refer to the following mitigation solutions.

late final Future<R> Function<M, R>(
    FutureOr<R> Function(M message) callback, M message,
    {String? debugLabel}) compute;

void initPoolCompute() {
  final pool = Platform.isAndroid
      ? IsolatePoolExecutor(
    corePoolSize: 4,
    maximumPoolSize: 2147483647,
    keepAliveTime: const Duration(seconds: 30),
    //Start the 4 core isolates immediately.
    launchCoreImmediately: true,
    //If isolate creation times out twice consecutively, no new ones will be created, only the ones already started will be used.
    //If there's no timeout during creation, use the isolate containing the 4 cores and automatically destroy other cached isolates.
    onIsolateCreateTimeoutTimesDoNotCreateNew: 2,
  )
      : IsolatePoolExecutor.newCachedIsolatePool(
      keepAliveTime: const Duration(seconds: 30));

  compute = pool.compute;
}

void main() {
  // init pool
  initPoolCompute();

  // ... doSomething
  compute((arg) {
    // ... doSomething
  }, 0);
}

See example for detailed test case.

Issues #

If you encounter issues, here are some tips for debug, if nothing helps report to issue tracker on GitHub: