{"id":15698717,"url":"https://github.com/geopjr/non-blocking-spawn","last_synced_at":"2025-07-28T19:33:47.405Z","repository":{"id":51799075,"uuid":"453422273","full_name":"GeopJr/non-blocking-spawn","owner":"GeopJr","description":"Crystal shard that spawns fibers in any worker thread BUT the current one","archived":false,"fork":false,"pushed_at":"2024-03-25T01:27:43.000Z","size":51,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-09T01:49:46.171Z","etag":null,"topics":["concurrency","fibers","threads"],"latest_commit_sha":null,"homepage":"https://geopjr.github.io/non-blocking-spawn/","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GeopJr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"GeopJr","custom":["https://www.paypal.me/GeopJr","https://geopjr.dev/donate"]}},"created_at":"2022-01-29T14:33:03.000Z","updated_at":"2023-11-30T15:47:03.000Z","dependencies_parsed_at":"2024-03-25T02:44:49.588Z","dependency_job_id":"ccbbcebb-9600-4fff-94fb-c445d80fdae9","html_url":"https://github.com/GeopJr/non-blocking-spawn","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/GeopJr/non-blocking-spawn","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeopJr%2Fnon-blocking-spawn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeopJr%2Fnon-blocking-spawn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeopJr%2Fnon-blocking-spawn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeopJr%2Fnon-blocking-spawn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GeopJr","download_url":"https://codeload.github.com/GeopJr/non-blocking-spawn/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GeopJr%2Fnon-blocking-spawn/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267575494,"owners_count":24110199,"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-07-28T02:00:09.689Z","response_time":68,"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":["concurrency","fibers","threads"],"created_at":"2024-10-03T19:32:42.949Z","updated_at":"2025-07-28T19:33:47.346Z","avatar_url":"https://github.com/GeopJr.png","language":"Crystal","funding_links":["https://github.com/sponsors/GeopJr","https://www.paypal.me/GeopJr","https://geopjr.dev/donate"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003enon-blocking-spawn\u003c/h1\u003e\n\u003ch4 align=\"center\"\u003eA Crystal shard that spawns a fiber in any worker thread BUT the current one.\u003c/h4\u003e\n\n## Purpose\n\nWhen running Crystal with [`-Dpreview_mt`](https://crystal-lang.org/2019/09/06/parallelism-in-crystal.html) sometimes fibers spawn in the current thread that might be blocked at that moment or for the duration of the run.\nThis happens by design. Top level `spawn` has an option to force a fiber to spawn in the current thread (`same_thread`), but not one for the opposite (since it's probably not in high demand).\nThat's what this shard adds.\n\nIt's a copy of the spawn method but when `same_thread` is false, it goes through all available worker threads, filters out the current one and picks one at random to spawn the fiber in.\n\nWhile it might sound a bit useless, there are legit use cases:\n\n- GTK: The main thread is blocked and remains blocked for the whole time. Using non-blocking-spawn you can spawn fibers and be sure that all of them will execute and finish.\n- Wider range of examples (see: [`./spec/non-blocking-spawn_spec.cr`](./spec/non-blocking-spawn_spec.cr)): In the spec, two of the tests are similar but one of them uses non-blocking-spawn while the other uses top level spawn. The first one finishes with `i` being equal to `4` (/default amount of worker threads) while the second one finishes with `i` being equal to `3`. This is due to one of the fibers being spawned in the current thread.\n\n## WARNING\n\n- PLEASE don't use with newer or older versions of Crystal without checking that the spawn method is the same as the top level one (apart from the non-blocking-thread part). This shard uses private interfaces that may break at any point without notice.\n\n- Assumes that all crystal commands (including `spec`) are being ran with the `-Dpreview_mt` flag. The `Non::Blocking.threads` method is available to check whether there are worker threads - other than the current one - and act accordingly (probably run in sync).\n\n## Installation\n\n1. Add the dependency to your `shard.yml`:\n\n```yaml\ndependencies:\n  non-blocking-spawn:\n    github: GeopJr/non-blocking-spawn\n```\n\n2. Run `shards install`\n\n## Usage\n\nYou can find non-blocking-spawn's docs on the sidebar.\n\n```crystal\nrequire \"non-blocking-spawn\"\n\nNon::Blocking.spawn do\n  # expensive blocking code\nend\n\n# other expensive blocking code\n```\n\n## Development\n\n- Everything runs with the `-Dpreview_mt` flag.\n- When bumping Crystal version make sure that the method matches the top level one.\n\n## Contributing\n\n1. Read the [Code of Conduct](https://github.com/GeopJr/non-blocking-spawn/blob/main/CODE_OF_CONDUCT.md)\n2. Fork it (\u003chttps://github.com/GeopJr/non-blocking-spawn/fork\u003e)\n3. Create your feature branch (`git checkout -b my-new-feature`)\n4. Commit your changes (`git commit -am 'Add some feature'`)\n5. Push to the branch (`git push origin my-new-feature`)\n6. Create a new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeopjr%2Fnon-blocking-spawn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeopjr%2Fnon-blocking-spawn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeopjr%2Fnon-blocking-spawn/lists"}