Similar to asyncio

Hello,

Does Crystal have a library similar to asyncio like in Python?

I’m not familiar with that lib or Python, but it seems Crystal already has this somewhat built in via Concurrency - Crystal. However [RFC] Structured Concurrency · Issue #6468 · crystal-lang/crystal · GitHub is still open in regards to providing higher level abstractions around it.

We don’t use async/await-like constructs in Crystal. Whereas asyncio does everything async and you use await to make something synchronous, everything in Crystal is synchronous and you use spawn to make something async. You can use a WaitGroup to ensure all your background work is done before you reach a certain point in your program. For example, if you need to send requests to three different services and those requests don’t depend on each other:

r.get :user_id do |user_id|
  account = nil
  profile = nil
  notification_preferences = nil

  WaitGroup.wait do |wg|
    wg.spawn { account = AccountService.get(user_id) }
    wg.spawn { profile = ProfileService.get(user_id) }
    wg.spawn { notification_preferences = NotificationService.get_preferences(user_id) }
  end

  if account && profile && notification_preferences
    render "user/show"
  else
    # handle errors
  end
end

This will execute all 3 service calls concurrently rather than sequentially. By the time the WaitGroup.wait method returns, all 3 services calls have completed and, unless they errored out, the variables are assigned.

2 Likes