em-easy 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,5 @@
1
+ module Enumerable
2
+ def async
3
+ Async::Enumerator.new self
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module Kernel
2
+ def wait(object)
3
+ Async.wait object
4
+ end
5
+ end
data/lib/em-easy.rb ADDED
@@ -0,0 +1,71 @@
1
+ require "fiber"
2
+ require "eventmachine"
3
+ require "em-easy/extensions/kernel"
4
+ require "em-easy/extensions/enumerable"
5
+
6
+ Fiber = Rubinius::Fiber if defined? Rubinius
7
+
8
+ module Async
9
+ extend self
10
+ attr_reader :evented_loop
11
+
12
+ class Enumerator
13
+ include Enumerable
14
+
15
+ def initialize(collection)
16
+ @collection = collection
17
+ @total = collection.size
18
+ end
19
+
20
+ def each(&block)
21
+ @finished = 0
22
+ @block = block
23
+ iterate_collection = proc do
24
+ @collection.each do |it|
25
+ if it.respond_to? :callback
26
+ it.callback {|result| finished result }
27
+ else
28
+ finished it
29
+ end
30
+ end
31
+ end
32
+ Async.evented_loop.resume :block => iterate_collection, :smart => true
33
+ end
34
+
35
+ private
36
+
37
+ def finished(result)
38
+ @block.call result
39
+ @finished += 1
40
+ Async.send :next_iteration, Fiber.yield(@collection) if @finished == @total
41
+ end
42
+ end
43
+
44
+ @evented_loop = Fiber.new do
45
+ EM.run { next_iteration }
46
+ end
47
+
48
+ def wait(object)
49
+ handle_callback = proc do
50
+ object.callback {|*args| next_iteration Fiber.yield(*args) }
51
+ end
52
+ @evented_loop.resume :block => handle_callback, :smart => true
53
+ end
54
+
55
+ private
56
+
57
+ def next_iteration(options=nil)
58
+ block = options && options[:block]
59
+
60
+ if block && options[:smart]
61
+ block.call
62
+ else
63
+ instructions = Fiber.yield(block && block.call)
64
+ EM.next_tick do
65
+ next_iteration instructions
66
+ end
67
+ end
68
+ end
69
+
70
+ @evented_loop.resume
71
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path("../spec_helper", __FILE__)
2
+ require "em-http"
3
+ require "benchmark"
4
+
5
+ describe Async do
6
+ def request
7
+ EM::HttpRequest.new("http://www.postrank.com")
8
+ end
9
+
10
+ def time
11
+ Benchmark.realtime { yield }
12
+ end
13
+
14
+ def time_of_couple_serial_requests
15
+ time { 2.times { wait request.get }}
16
+ end
17
+
18
+ it "should let use EM-operations outside EM.run block" do
19
+ expect { request.get }.to_not raise_error
20
+ end
21
+
22
+ it "should not block async operations" do
23
+ time { request.get }.should be < 0.01
24
+ end
25
+
26
+ it "#wait should block until async operation returns" do
27
+ time { wait request.get }.should be > 0.05
28
+ end
29
+
30
+ it '#wait should return result of async operation' do
31
+ wait(request.get).response.should include("<!DOCTYPE html>")
32
+ end
33
+
34
+ it "#wait should not block other async operations" do
35
+ batch_duration = time { Array.new(5) { request.get }.map {|it| wait it }}
36
+ batch_duration.should be < time_of_couple_serial_requests
37
+ end
38
+
39
+ it "should iterate over async enumerable yielding results of async operations" do
40
+ Array.new(5) { request.get }.async.each do |it|
41
+ it.response.should include("<!DOCTYPE html>")
42
+ end
43
+ end
44
+
45
+ it "should iterate over async enumerable via transparent callbacks" do
46
+ time { Array.new(5) { request.get }.async.map do |it|
47
+ it.response
48
+ end }.should be < time_of_couple_serial_requests
49
+ end
50
+
51
+ it "should handle mixed array with non-deferrable and deferrable objects" do
52
+ result = [request.get, "hey"].async.to_a
53
+ result[0].should == "hey"
54
+ result[1].response.should include("<!DOCTYPE html>")
55
+ end
56
+ end
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
+ require "em-easy"
3
+ require "rspec"
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: em-easy
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - brainopia
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-07 00:00:00 +03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: eventmachine
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 12
31
+ - 10
32
+ version: 0.12.10
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ description: Asynchronous programming (based on EventMachine) without trouble of callbacks
36
+ email: ravwar@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - VERSION
45
+ - lib/em-easy.rb
46
+ - lib/em-easy/extensions/enumerable.rb
47
+ - lib/em-easy/extensions/kernel.rb
48
+ - spec/integration_spec.rb
49
+ - spec/spec_helper.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/brainopia/em-easy
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirements: []
76
+
77
+ rubyforge_project: em-easy
78
+ rubygems_version: 1.3.7
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Asynchronous programming (based on EventMachine) without trouble of callbacks
82
+ test_files:
83
+ - spec/integration_spec.rb