Skip to content

Commit

Permalink
add EM::Synchrony.sync for inline fiber sync (aka, inlineCallbacks in
Browse files Browse the repository at this point in the history
Python)
  • Loading branch information
igrigorik committed Jul 4, 2010
1 parent 848b260 commit ce3fefa
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
27 changes: 26 additions & 1 deletion lib/em-synchrony.rb
Expand Up @@ -24,4 +24,29 @@ def self.synchrony(blk=nil, tail=nil, &block)
self.run(context, tail)
end

end
module Synchrony

# sync is a close relative to inclineCallbacks from Twisted (Python)
#
# Synchrony.sync allows you to write sequential code while using asynchronous
# or callback-based methods under the hood. Example:
#
# result = EM::Synchrony.sync EventMachine::HttpRequest.new(URL).get
# p result.response
#
# As long as the asynchronous function returns a Deferrable object, which
# has a "callback" and an "errback", the sync methond will automatically

This comment has been minimized.

Copy link
@rfelix

rfelix Jul 5, 2010

Typo: methond to method

This comment has been minimized.

Copy link
@igrigorik

igrigorik Jul 5, 2010

Author Owner

Woops, thanks!

# yield and automatically resume your code (via Fibers) when the call
# either succeeds or fails. You do not need to patch or modify the
# Deferrable object, simply pass it to EM::Synchrony.sync
#
def self.sync(df)
f = Fiber.current
df.callback { |r| f.resume(r) }
df.errback { |r| f.resume(r) }

Fiber.yield
end
end

end
37 changes: 37 additions & 0 deletions spec/inlinesync_spec.rb
@@ -0,0 +1,37 @@
require "spec/helper/all"
require "em-synchrony/iterator"

describe EventMachine::Synchrony do

URL = "http://localhost:8081/"
DELAY = 0.01

it "should allow inline callbacks for Deferrable object" do
EM.synchrony do
s = StubServer.new("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nFoo", DELAY)

result = EM::Synchrony.sync EventMachine::HttpRequest.new(URL).aget
result.response.should match(/Foo/)

EM.stop
end
end

it "should inline errback/callback cases" do
EM.synchrony do
class E
include EventMachine::Deferrable
def run
EM.add_timer(0.01) {fail("uh oh!")}
self
end
end

result = EM::Synchrony.sync E.new.run
result.should match(/uh oh!/)

EM.stop
end
end

end

0 comments on commit ce3fefa

Please sign in to comment.