{"id":32305433,"url":"https://github.com/bitsydarel/executorservices","last_synced_at":"2025-10-23T06:51:10.578Z","repository":{"id":56828554,"uuid":"215142435","full_name":"bitsydarel/executorservices","owner":"bitsydarel","description":"Dart executer services.","archived":false,"fork":false,"pushed_at":"2019-11-05T03:04:45.000Z","size":82,"stargazers_count":18,"open_issues_count":0,"forks_count":2,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-22T23:45:35.252Z","etag":null,"topics":["dart","dart-library","flutter","isolate","multithreading"],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bitsydarel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-10-14T20:48:25.000Z","updated_at":"2023-10-07T09:05:25.000Z","dependencies_parsed_at":"2022-08-29T02:40:54.080Z","dependency_job_id":null,"html_url":"https://github.com/bitsydarel/executorservices","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/bitsydarel/executorservices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsydarel%2Fexecutorservices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsydarel%2Fexecutorservices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsydarel%2Fexecutorservices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsydarel%2Fexecutorservices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bitsydarel","download_url":"https://codeload.github.com/bitsydarel/executorservices/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bitsydarel%2Fexecutorservices/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280577134,"owners_count":26354072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-23T02:00:06.710Z","response_time":142,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dart-library","flutter","isolate","multithreading"],"created_at":"2025-10-23T06:51:07.239Z","updated_at":"2025-10-23T06:51:10.572Z","avatar_url":"https://github.com/bitsydarel.png","language":"Dart","readme":"[![Pub.dev](https://img.shields.io/pub/v/executorservices.svg?style=flat-square\u0026logo=data:image/png;base64,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)](https://pub.dartlang.org/packages/executorservices) [![License](https://img.shields.io/github/license/bitsydarel/executorservices?style=flat-square\u0026logo=github)](https://github.com/modulovalue/dart_fenwick_tree/blob/master/LICENSE) \n\nA library for Dart and Flutter developers.\n\n[license](https://github.com/bitsydarel/executorservices/blob/master/LICENSE).\n\n## Description\nIt allows you to execute code in isolates or any executor currently supported.\n\nSupport concurrent execution of tasks or functions.\n\nSupport cleanup of unused isolates.\n\nSupport caching of isolate that allow you to reuse them (like thread).\n\nIt's extendable.\n\n## Usage\n\n### For tasks that return either a value or an error:\n\nFor submitting a top level or static function without arguments to the executorservice.\nFor task that return a value or a future the executorService.submit* return a future, to track the progress of the task.\n```dart\nimport \"dart:math\";\nimport \"package:executorservices/executorservices.dart\";\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  final Future\u003cint\u003e futureResult = executorService.submitAction(_randomInt);\n\n  futureResult.then((result) =\u003e print(result));\n}\n\nint _randomInt() {\n  return Random.secure().nextInt(1000);\n}\n```\n\nFor submitting a top level or static function with one argument to the executorservice.\n```dart\nimport \"package:executorservices/executorservices.dart\";\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  final Future\u003cString\u003e futureResult = executorService.submitCallable(expensiveHelloWorld, \"Darel Bitsy\");\n\n  futureResult.then((result) =\u003e print(result));\n}\n\nFuture\u003cString\u003e expensiveHelloWorld(final String name) async {\n  await Future.delayed(Duration(seconds: 1));\n  return \"Hellow world $name\";\n}\n```\n\nFor submitting a top level or static function with many other arguments to the executorservice.\nThe executorservice provide method like submitFunction2,submitFunction3,submitFunction4.\n```dart\nimport \"package:executorservices/executorservices.dart\";\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  final Future\u003cString\u003e futureResult = executorService.submitFunction2(\n    expensiveHelloWorld,\n    \"Darel Bitsy\",\n    23,\n  );\n\n  futureResult.then((result) =\u003e print(result));\n}\n\nFuture\u003cString\u003e expensiveHelloWorld(final String name, final int age) async {\n  await Future.delayed(Duration(seconds: 1));\n  if (age \u003e= 80) {\n    return \"Hellow world elder $name\";\n  } else {\n    return \"Hellow world $name\";\n  }\n}\n```\n\nIf you want to run a instance method of a existing class you need to make it extend the Task class.\nIf if you want to have more than five arguments function.\nIf you don't want to have the code as top level or static function.\n```dart\nimport \"dart:async\";\nimport \"dart:isolate\";\n\nimport \"package:executorservices/executorservices.dart\";\nimport \"package:http/http.dart\" as http;\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  final Future\u003cString\u003e futureResult = executorService.submit(\n    GetPost(\"https://jsonplaceholder.typicode.com/posts\", 5),\n  );\n\n  futureResult.then(\n    (result) =\u003e print(\n      \"Recieved $result and it's running from ${Isolate.current.debugName}\",\n    ),\n  );\n}\n\nclass GetPost extends Task\u003cString\u003e {\n  GetPost(this.apiUrl, this.index);\n\n  final String apiUrl;\n  final int index;\n\n  @override\n  FutureOr\u003cString\u003e execute() {\n    return http\n        .get(\"$apiUrl/$index\")\n        .then((postResponse) =\u003e postResponse.body)\n        .then(\n      (json) {\n        print(\n          \"about to return $json and it's running from ${Isolate.current.debugName}\",\n        );\n        return json;\n      },\n    );\n  }\n}\n```\n\nA example of chaining tasks.\n```dart\nimport \"dart:async\";\nimport \"dart:math\";\n\nimport \"package:executorservices/executorservices.dart\";\nimport \"package:http/http.dart\" as http;\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  executorService\n      .submitFunction2(_fullName, \"Darel\", \"Bitsy\")\n      .then(\n        (fullName) {\n          print(\"Hi, $fullName\");\n          return executorService.submitAction(randomPostId);\n        },\n      )\n      .then(\n        (postId) =\u003e executorService.submit(\n          GetPost(\"https://jsonplaceholder.typicode.com/posts\", postId),\n        ),\n      )\n      .then(print);\n}\n\nint randomPostId() {\n  return Random.secure().nextInt(10);\n}\n\nFuture\u003cString\u003e _fullName(final String firstName, final String lastName) async {\n  await Future.delayed(Duration(milliseconds: 500));\n  return \"$firstName, $lastName\";\n}\n\nclass GetPost extends Task\u003cString\u003e {\n  GetPost(this.apiUrl, this.index);\n\n  final String apiUrl;\n  final int index;\n\n  @override\n  FutureOr\u003cString\u003e execute() {\n    return http.get(\"$apiUrl/$index\").then((postResponse) =\u003e postResponse.body);\n  }\n}\n```\n\n### For tasks that emit events (Code that return a stream):\n\nFor executing to a top level or static function without arguments that return a stream to the executorservice.\n```dart\nimport \"dart:async\";\nimport \"dart:isolate\";\nimport \"dart:math\";\n\nimport \"package:executorservices/executorservices.dart\";\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  final Stream\u003cint\u003e streamOfRandomNumber =\n      executorService.subscribeToAction(randomGenerator);\n\n  streamOfRandomNumber.listen(\n    (newData) =\u003e print(\n      \"Received $newData and it's running on isolate: ${Isolate.current.debugName}\",\n    ),\n    onError: (error) =\u003e print(\n      \"Received ${error.toString()} and it's running on isolate: ${Isolate.current.debugName}\",\n    ),\n    onDone: () =\u003e print(\n      \"Task's done and it's running on isolate: ${Isolate.current.debugName}\",\n    ),\n  );\n}\n\nStream\u003cint\u003e randomGenerator() async* {\n  for (var i = 0; i \u003c Random.secure().nextInt(10); i++) {\n    await Future.delayed(Duration(seconds: 1));\n    print(\n      \"about to yield $i and it's running from ${Isolate.current.debugName}\",\n    );\n    yield i;\n  }\n}\n```\n\nHere are the analogical method for other type of top level, or static functions:\nsubscribeToCallable, subscribeToFunction2, subscribeToFunction3, subscribeToFunction4\n\nIf you want to run a instance method of a existing class you need to make it extend the SubscribableTask class.\nIf if you want to have more than five arguments function.\nIf you don't want to have the code as top level or static function.\n\n```dart\nimport \"dart:async\";\nimport \"dart:isolate\";\n\nimport \"package:executorservices/executorservices.dart\";\nimport \"package:http/http.dart\" as http;\n\nvoid main() {\n  final executorService = ExecutorService.newSingleExecutor();\n\n  final Stream\u003cString\u003e streamOfPosts = executorService.subscribe(\n    GetPosts(\"https://jsonplaceholder.typicode.com/posts\", 10),\n  );\n\n  streamOfPosts.listen(\n    (newData) =\u003e print(\n      \"Received $newData and it's running on isolate: ${Isolate.current.debugName}\",\n    ),\n    onError: (error) =\u003e print(\n      \"Received ${error.toString()} and it's running on isolate: ${Isolate.current.debugName}\",\n    ),\n    onDone: () =\u003e print(\n      \"Task's done and it's running on isolate: ${Isolate.current.debugName}\",\n    ),\n  );\n}\n\nclass GetPosts extends SubscribableTask\u003cString\u003e {\n  GetPosts(this.apiUrl, this.maxPosts);\n\n  final String apiUrl;\n  final int maxPosts;\n\n  @override\n  Stream\u003cString\u003e execute() async* {\n    for (var index = 0; index \u003c maxPosts; index++) {\n      final postJson = await http\n          .get(\"$apiUrl/$index\")\n          .then((postResponse) =\u003e postResponse.body);\n\n      print(\n        \"about to yield $postJson and \"\n        \"it's running from ${Isolate.current.debugName}\",\n      );\n\n      yield postJson;\n    }\n  }\n}\n```\n\nA example of chaining tasks of different type together.\n```dart\nimport \"dart:async\";\nimport \"dart:io\";\n\nimport \"package:executorservices/executorservices.dart\";\nimport \"package:http/http.dart\" as http;\n\nvoid main() {\n  final executorService = ExecutorService.newUnboundExecutor();\n\n  executorService\n      .subscribeToAction(randomPostIds)\n      .asyncMap((randomPostId) =\u003e executorService.submit(GetPost(randomPostId)))\n      .listen(\n        (newData) =\u003e print(\"Received $newData\"),\n        onError: (error) =\u003e print(\"Received ${error.toString()}\"),\n        onDone: () {\n          print(\"Task's done\");\n          exit(0);\n        },\n      );\n}\n\nStream\u003cint\u003e randomPostIds() async* {\n  for (var index = 0; index \u003c 10; index++) {\n    await Future.delayed(Duration(milliseconds: 100));\n    yield index;\n  }\n}\n\nclass GetPost extends Task\u003cString\u003e {\n  GetPost(this.postId);\n\n  final int postId;\n\n  @override\n  Future\u003cString\u003e execute() {\n    return http\n        .get(\"https://jsonplaceholder.typicode.com/posts/$postId\")\n        .then((postResponse) =\u003e postResponse.body);\n  }\n}\n```\n\nBy default you can't re-submit the same instance of a ongoing Task to a ExecutorService multiple times.\nBecause the result of your submitted task is associated with the task instance identifier.\nSo by default submitting the same instance of a task multiple times will result in unexpected behaviors.\n\nFor example, this won't work:\n\n```dart\nmain() {\n  final executors = ExecutorService.newUnboundExecutor();\n  \n  final task = SameInstanceTask();\n\n  executors.submit(task);\n  executors.submit(task);\n  executors.submit(task);\n  \n  for (var index = 0; index \u003c 10; index++) {\n    executors.submit(task);\n  }\n}\n\nclass SameInstanceTask extends Task\u003cString\u003e {\n  @override\n  FutureOr\u003cString\u003e execute() async {\n    await Future.delayed(Duration(seconds: 5));\n    return \"Done executing same instance task\";\n  }\n} \n``` \n\n\nBut if you want to submit the same instance of a task multiple times you need to override the Task is clone method.\n\nFor example, this will now work:\n```dart\nmain() {\n  final executors = ExecutorService.newUnboundExecutor();\n  \n  final task = SameInstanceTask();\n\n  for (var index = 0; index \u003c 10; index++) {\n    executors.submit(task);\n  }\n  \n  final taskWithParams = SameInstanceTaskWithParams(\"Darel Bitsy\");\n\n  for (var index = 0; index \u003c 10; index++) {\n    executors.submit(taskWithParams);\n  }\n}\n\nclass SameInstanceTask extends Task\u003cString\u003e {\n  @override\n  FutureOr\u003cString\u003e execute() async {\n    await Future.delayed(Duration(minutes: 5));\n    return \"Done executing same instance task\";\n  }\n  \n  @override\n  SameInstanceTask clone() {\n    return SameInstanceTask();\n  }\n}\n\nclass SameInstanceTaskWithParams extends Task\u003cString\u003e {\n  SameInstanceTaskWithParams(this.name);\n\n  final String name;\n\n  @override\n  FutureOr\u003cString\u003e execute() async {\n    await Future.delayed(Duration(minutes: 5));\n    return \"Done executing same instance task with name: $name\";\n  }\n    \n  @override\n  SameInstanceTaskWithParams clone() {\n    return SameInstanceTaskWithParams(name);\n  }\n}\n```\n\n## Features and bugs\n\nPlease file feature requests and bugs at the [issue tracker][tracker].\n\n[tracker]:https://github.com/bitsydarel/executorservices/issues\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsydarel%2Fexecutorservices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbitsydarel%2Fexecutorservices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbitsydarel%2Fexecutorservices/lists"}