https://github.com/geopjr/non-blocking-spawn
Crystal shard that spawns fibers in any worker thread BUT the current one
https://github.com/geopjr/non-blocking-spawn
concurrency fibers threads
Last synced: 11 months ago
JSON representation
Crystal shard that spawns fibers in any worker thread BUT the current one
- Host: GitHub
- URL: https://github.com/geopjr/non-blocking-spawn
- Owner: GeopJr
- License: bsd-2-clause
- Created: 2022-01-29T14:33:03.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2024-03-25T01:27:43.000Z (over 2 years ago)
- Last Synced: 2025-05-09T01:49:46.171Z (about 1 year ago)
- Topics: concurrency, fibers, threads
- Language: Crystal
- Homepage: https://geopjr.github.io/non-blocking-spawn/
- Size: 49.8 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
non-blocking-spawn
A Crystal shard that spawns a fiber in any worker thread BUT the current one.
## Purpose
When 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.
This 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).
That's what this shard adds.
It'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.
While it might sound a bit useless, there are legit use cases:
- 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.
- 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.
## WARNING
- 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.
- 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).
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
non-blocking-spawn:
github: GeopJr/non-blocking-spawn
```
2. Run `shards install`
## Usage
You can find non-blocking-spawn's docs on the sidebar.
```crystal
require "non-blocking-spawn"
Non::Blocking.spawn do
# expensive blocking code
end
# other expensive blocking code
```
## Development
- Everything runs with the `-Dpreview_mt` flag.
- When bumping Crystal version make sure that the method matches the top level one.
## Contributing
1. Read the [Code of Conduct](https://github.com/GeopJr/non-blocking-spawn/blob/main/CODE_OF_CONDUCT.md)
2. Fork it ()
3. Create your feature branch (`git checkout -b my-new-feature`)
4. Commit your changes (`git commit -am 'Add some feature'`)
5. Push to the branch (`git push origin my-new-feature`)
6. Create a new Pull Request