Provide await and async methods to Crystal Lang
Add await
and async
keywords to Crystal.
In your shards.yml
:
dependencies:
await_async:
github: anykeyh/await_async
branch: master
Then:
require "await_async"
future = async fetch_something
do_some_computation_now
await future
async
on any method or block to create a MiniFuture
await
on any MiniFuture
to wait for/get the resultawait
on future's array.Can improve drastically application which relay on blocking IO like web API or file writing.
future = async check_website
begin
await 5.seconds, future
rescue MiniFuture::TimeoutException
# rescue from timeout
end
async!
/ async
By default, async!
call the newly created fiber just after creation.
async
so the fiber won't start now:future = async! { 1 + 2 }
# At this moment the result is already computed
# future.finished? == true
await future # => 3
# vs
future = async { 1 + 2 }
# Here the result is not computed
# future.finished? == false
await future # Compute now
Usually, use async
if your block is computation intensive and current thread
has IO blocking operation. Use async!
in other cases.
In case of errors, the exception will be raise at await
moment, in the await
thread.
MiniFuture
A minimalist version of future. Has finished?
and running?
methods.
I don't use Crystal's Concurrent::Future
class because :nodoc:
.
Because crystal is great for building CLI tools. And CLI deals a lot with files and sockets. And IO performed in main thread are slow.
Usage of Channel
is recommended for complex software, as it offers more patterns.
await/async
is useful to build fast and deliver fast.
await_async/helper
instead of await_async
include AwaitAsync::Helper
.
You can also simply call await/async
directly from AwaitAsync::Helper
def fetch_websites_async
%w[
www.github.com
www.yahoo.com
www.facebook.com
www.twitter.com
crystal-lang.org
].map do |url|
async! do
HTTP::Client.get "https://#{url}"
end
end
end
# Process the websites concurrently. Start querying another website when the
# first one is waiting for response
await(5.seconds, fetch_websites_async).each do |response|
# ...
end
MIT