Skip to content

Instantly share code, notes, and snippets.

@havenwood
Last active February 12, 2022 17:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/ea5c27016ec2827f44b1bd667688f91f to your computer and use it in GitHub Desktop.
Save havenwood/ea5c27016ec2827f44b1bd667688f91f to your computer and use it in GitHub Desktop.
require 'async'
class Enumerator
class Async
module Refinement
refine Enumerable do
def async
Enumerator::Async.new(self)
end
end
end
include Enumerable
def initialize(collection)
@enum = collection.to_enum
end
def eager
return @enum unless @enum.respond_to?(:eager)
@enum.eager
end
def lazy
@enum.lazy
end
def async
self
end
def each(&block)
Sync do |task|
@enum.each do |value|
task.async do
block.call(value)
end
end
end
self
end
end
end
using Enumerator::Async::Refinement
[1, 2, 3].async.map do |number|
sleep 2
number + 42
end
@bruno-
Copy link

bruno- commented Dec 30, 2021

Async creates a new task if it runs within an existing reactor. So I would maybe change line 34 to Sync do |task|:

  • It will start a new reactor (just like top-level Async) if one doesn't yet exist
  • If the method runs inside an existing reactor (Async block) it will just run synchronously

@havenwood
Copy link
Author

@bruno- that makes sense and is really interesting. I hadn't thought of it being used inside an existing reactor. Thank you for your feedback! I updated the gist accordingly to use Sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment