Add await and async keywords to Crystal.
In your shards.yml:
dependencies:
await_async:
github: anykeyh/await_async
branch: masterThen:
require "await_async"
future = async fetch_something
do_some_computation_now
await future- Call
asyncon any method or block to create aMiniFuture - Call
awaiton anyMiniFutureto wait for/get the result - Conveniently, you can call
awaiton 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
endBy default, async! call the newly created fiber just after creation.
- You can use instead
asyncso 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 nowUsually, 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.
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.
- require
await_async/helperinstead ofawait_async - In the class/module you want to use the methods, add
include AwaitAsync::Helper. You can also simply callawait/asyncdirectly fromAwaitAsync::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|
# ...
endMIT