eventmachine 0.12.10 → 1.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/Gemfile +1 -0
- data/README +1 -2
- data/Rakefile +4 -76
- data/docs/DEFERRABLES +183 -70
- data/docs/KEYBOARD +15 -11
- data/docs/LIGHTWEIGHT_CONCURRENCY +84 -24
- data/docs/SMTP +3 -1
- data/docs/SPAWNED_PROCESSES +84 -25
- data/eventmachine.gemspec +19 -26
- data/examples/ex_tick_loop_array.rb +15 -0
- data/examples/ex_tick_loop_counter.rb +32 -0
- data/ext/binder.cpp +0 -1
- data/ext/cmain.cpp +36 -11
- data/ext/cplusplus.cpp +1 -1
- data/ext/ed.cpp +104 -113
- data/ext/ed.h +24 -30
- data/ext/em.cpp +347 -248
- data/ext/em.h +23 -16
- data/ext/eventmachine.h +5 -3
- data/ext/extconf.rb +5 -3
- data/ext/fastfilereader/extconf.rb +5 -3
- data/ext/fastfilereader/mapper.cpp +1 -1
- data/ext/kb.cpp +1 -3
- data/ext/pipe.cpp +9 -11
- data/ext/project.h +12 -4
- data/ext/rubymain.cpp +138 -89
- data/java/src/com/rubyeventmachine/EmReactor.java +1 -0
- data/lib/em/channel.rb +1 -1
- data/lib/em/connection.rb +6 -1
- data/lib/em/deferrable.rb +16 -2
- data/lib/em/iterator.rb +270 -0
- data/lib/em/protocols.rb +1 -1
- data/lib/em/protocols/httpclient.rb +5 -0
- data/lib/em/protocols/line_protocol.rb +28 -0
- data/lib/em/protocols/smtpserver.rb +101 -8
- data/lib/em/protocols/stomp.rb +1 -1
- data/lib/{pr_eventmachine.rb → em/pure_ruby.rb} +1 -11
- data/lib/em/queue.rb +1 -0
- data/lib/em/streamer.rb +1 -1
- data/lib/em/tick_loop.rb +85 -0
- data/lib/em/timers.rb +2 -1
- data/lib/em/version.rb +1 -1
- data/lib/eventmachine.rb +38 -84
- data/lib/jeventmachine.rb +1 -0
- data/tests/test_attach.rb +13 -3
- data/tests/test_basic.rb +60 -95
- data/tests/test_channel.rb +3 -2
- data/tests/test_defer.rb +14 -12
- data/tests/test_deferrable.rb +35 -0
- data/tests/test_file_watch.rb +1 -1
- data/tests/test_futures.rb +1 -1
- data/tests/test_hc.rb +40 -68
- data/tests/test_httpclient.rb +15 -6
- data/tests/test_httpclient2.rb +3 -2
- data/tests/test_inactivity_timeout.rb +3 -3
- data/tests/test_ltp.rb +13 -5
- data/tests/test_next_tick.rb +1 -1
- data/tests/test_pending_connect_timeout.rb +2 -2
- data/tests/test_process_watch.rb +36 -34
- data/tests/test_proxy_connection.rb +52 -0
- data/tests/test_pure.rb +10 -1
- data/tests/test_sasl.rb +1 -1
- data/tests/test_send_file.rb +16 -7
- data/tests/test_servers.rb +1 -1
- data/tests/test_tick_loop.rb +59 -0
- data/tests/test_timers.rb +13 -15
- metadata +45 -17
- data/web/whatis +0 -7
data/docs/KEYBOARD
CHANGED
@@ -1,38 +1,42 @@
|
|
1
|
-
EventMachine (EM) can respond to keyboard events. This gives your event-driven
|
1
|
+
EventMachine (EM) can respond to keyboard events. This gives your event-driven
|
2
|
+
programs the ability to respond to input from local users.
|
2
3
|
|
3
|
-
Programming EM to handle keyboard input in Ruby is simplicity itself. Just use
|
4
|
+
Programming EM to handle keyboard input in Ruby is simplicity itself. Just use
|
5
|
+
EventMachine#open_keyboard, and supply the name of a Ruby module or class that
|
6
|
+
will receive the input:
|
4
7
|
|
5
8
|
require 'rubygems'
|
6
9
|
require 'eventmachine'
|
7
|
-
|
10
|
+
|
8
11
|
module MyKeyboardHandler
|
9
12
|
def receive_data keystrokes
|
10
13
|
puts "I received the following data from the keyboard: #{keystrokes}"
|
11
14
|
end
|
12
15
|
end
|
13
|
-
|
16
|
+
|
14
17
|
EM.run {
|
15
18
|
EM.open_keyboard(MyKeyboardHandler)
|
16
19
|
}
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
21
|
+
If you want EM to send line-buffered keyboard input to your program, just
|
22
|
+
include the LineText2 protocol module in your handler class or module:
|
22
23
|
|
23
24
|
require 'rubygems'
|
24
25
|
require 'eventmachine'
|
25
|
-
|
26
|
+
|
26
27
|
module MyKeyboardHandler
|
27
28
|
include EM::Protocols::LineText2
|
28
29
|
def receive_line data
|
29
30
|
puts "I received the following line from the keyboard: #{data}"
|
30
31
|
end
|
31
32
|
end
|
32
|
-
|
33
|
+
|
33
34
|
EM.run {
|
34
35
|
EM.open_keyboard(MyKeyboardHandler)
|
35
36
|
}
|
36
37
|
|
37
|
-
As we said, simplicity itself. You can call EventMachine#open_keyboard at any
|
38
|
+
As we said, simplicity itself. You can call EventMachine#open_keyboard at any
|
39
|
+
time while the EM reactor loop is running. In other words, the method
|
40
|
+
invocation may appear anywhere in an EventMachine#run block, or in any code
|
41
|
+
invoked in the #run block.
|
38
42
|
|
@@ -1,24 +1,43 @@
|
|
1
|
-
EventMachine (EM) adds two different formalisms for lightweight concurrency to
|
1
|
+
EventMachine (EM) adds two different formalisms for lightweight concurrency to
|
2
|
+
the Ruby programmer's toolbox: spawned processes and deferrables. This note
|
3
|
+
will show you how to use them.
|
2
4
|
|
3
5
|
|
4
6
|
=== What is Lightweight Concurrency?
|
5
7
|
|
6
|
-
We use the term "Lightweight Concurrency" (LC) to refer to concurrency
|
8
|
+
We use the term "Lightweight Concurrency" (LC) to refer to concurrency
|
9
|
+
mechanisms that are lighter than Ruby threads. By "lighter," we mean: less
|
10
|
+
resource-intensive in one or more dimensions, usually including memory and
|
11
|
+
CPU usage. In general, you turn to LC in the hope of improving the
|
12
|
+
performance and scalability of your programs.
|
7
13
|
|
8
|
-
In addition to the two EventMachine mechanisms we will discuss here, Ruby
|
14
|
+
In addition to the two EventMachine mechanisms we will discuss here, Ruby
|
15
|
+
has at least one other LC construct: Fibers, which are currently under
|
16
|
+
development in Ruby 1.9.
|
9
17
|
|
10
|
-
The technical feature that makes all of these LC mechanisms different from
|
18
|
+
The technical feature that makes all of these LC mechanisms different from
|
19
|
+
standard Ruby threads is that they are not scheduled automatically.
|
11
20
|
|
12
|
-
When you create and run Ruby threads, you can assume (within certain
|
21
|
+
When you create and run Ruby threads, you can assume (within certain
|
22
|
+
constraints) that your threads will all be scheduled fairly by Ruby's runtime.
|
23
|
+
Ruby itself is responsible for giving each of your threads its own share of
|
24
|
+
the total runtime.
|
13
25
|
|
14
|
-
But with LC, your program is responsible for causing different execution
|
26
|
+
But with LC, your program is responsible for causing different execution
|
27
|
+
paths to run. In effect, your program has to act as a "thread scheduler."
|
28
|
+
Scheduled entities in LC run to completion and are never preempted. The
|
29
|
+
runtime system has far less work to do since it has no need to interrupt
|
30
|
+
threads or to schedule them fairly. This is what makes LC lighter and faster.
|
15
31
|
|
16
|
-
You'll learn exactly how LC scheduling works in practice as we work through
|
32
|
+
You'll learn exactly how LC scheduling works in practice as we work through
|
33
|
+
specific examples.
|
17
34
|
|
18
35
|
|
19
36
|
=== EventMachine Lightweight Concurrency
|
20
37
|
|
21
|
-
Recall that EM provides a reactor loop that must be running in order for
|
38
|
+
Recall that EM provides a reactor loop that must be running in order for
|
39
|
+
your programs to perform event-driven logic. An EM program typically has a
|
40
|
+
structure like this:
|
22
41
|
|
23
42
|
require 'eventmachine'
|
24
43
|
|
@@ -33,38 +52,79 @@ Recall that EM provides a reactor loop that must be running in order for your pr
|
|
33
52
|
# end of the program
|
34
53
|
|
35
54
|
|
36
|
-
EventMachine#run executes the reactor loop, which causes your code to be
|
55
|
+
EventMachine#run executes the reactor loop, which causes your code to be
|
56
|
+
called as events of interest to your program occur. The block you pass to
|
57
|
+
EventMachine#run is executed right after the reactor loop starts, and is
|
58
|
+
the right place to start socket acceptors, etc.
|
37
59
|
|
38
|
-
Because the reactor loop runs constantly in an EM program (until it is
|
60
|
+
Because the reactor loop runs constantly in an EM program (until it is
|
61
|
+
stopped by a call to EventMachine#stop), it has the ability to schedule
|
62
|
+
blocks of code for asynchronous execution. Unlike a pre-emptive thread
|
63
|
+
scheduler, it's NOT able to interrupt code blocks while they execute. But
|
64
|
+
the scheduling capability it does have is enough to enable lightweight
|
65
|
+
concurrency.
|
39
66
|
|
40
67
|
|
41
|
-
For information on Spawned Processes, see the separate document
|
68
|
+
For information on Spawned Processes, see the separate document
|
69
|
+
SPAWNED_PROCESSES.
|
42
70
|
|
43
71
|
For information on Deferrables, see the separate document DEFERRABLES.
|
44
72
|
|
45
73
|
|
46
74
|
=== [SIDEBAR]: I Heard That EventMachine Doesn't Work With Ruby Threads.
|
47
75
|
|
48
|
-
This is incorrect. EM is fully interoperable with all versions of Ruby
|
76
|
+
This is incorrect. EM is fully interoperable with all versions of Ruby
|
77
|
+
threads, and has been since its earliest releases.
|
49
78
|
|
50
|
-
It's very true that EM encourages an "evented" (non-threaded) programming
|
79
|
+
It's very true that EM encourages an "evented" (non-threaded) programming
|
80
|
+
style. The specific benefits of event-driven programming are far better
|
81
|
+
performance and scalability for well-written programs, and far easier
|
82
|
+
debugging.
|
51
83
|
|
52
|
-
The benefit of using threads for similar applications is a possibly more
|
84
|
+
The benefit of using threads for similar applications is a possibly more
|
85
|
+
intuitive programming model, as well as the fact that threads are already
|
86
|
+
familiar to most programmers. Also, bugs in threaded programs often fail
|
87
|
+
to show up until programs go into production. These factors create the
|
88
|
+
illusion that threaded programs are easier to write.
|
53
89
|
|
54
|
-
However, some operations that occur frequently in professional-caliber
|
90
|
+
However, some operations that occur frequently in professional-caliber
|
91
|
+
applications simply can't be done without threads. (The classic example
|
92
|
+
is making calls to database client-libraries that block on network I/O
|
93
|
+
until they complete.)
|
55
94
|
|
56
|
-
EventMachine not only allows the use of Ruby threads in these cases, but
|
95
|
+
EventMachine not only allows the use of Ruby threads in these cases, but
|
96
|
+
it even provides a built-in thread-pool object to make them easier to
|
97
|
+
work with.
|
57
98
|
|
58
|
-
You may have heard a persistent criticism that evented I/O is fundamentally
|
99
|
+
You may have heard a persistent criticism that evented I/O is fundamentally
|
100
|
+
incompatible with Ruby threads. It is true that some well-publicized attempts
|
101
|
+
to incorporate event-handling libraries into Ruby were not successful. But
|
102
|
+
EventMachine was designed from the ground up with Ruby compatibility in mind,
|
103
|
+
so EM never suffered from the problems that defeated the earlier attempts.
|
59
104
|
|
60
105
|
|
61
106
|
=== [SIDEBAR]: I Heard That EventMachine Doesn't Work Very Well On Windows.
|
62
107
|
|
63
|
-
This too is incorrect. EventMachine is an extension written in C++ and Java,
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
108
|
+
This too is incorrect. EventMachine is an extension written in C++ and Java,
|
109
|
+
and therefore it requires compilation. Many Windows computers (and some Unix
|
110
|
+
computers, especially in production environments) don't have a build stack.
|
111
|
+
Attempting to install EventMachine on a machine without a compiler usually
|
112
|
+
produces a confusing error.
|
113
|
+
|
114
|
+
In addition, Ruby has a much-debated issue with Windows compiler versions.
|
115
|
+
Ruby on Windows works best with Visual Studio 6, a compiler version that is
|
116
|
+
long out-of-print, no longer supported by Microsoft, and difficult to obtain.
|
117
|
+
(This problem is not specific to EventMachine.)
|
118
|
+
|
119
|
+
Shortly after EventMachine was first released, the compiler issues led to
|
120
|
+
criticism that EM was incompatible with Windows. Since that time, every
|
121
|
+
EventMachine release has been supplied in a precompiled binary form for
|
122
|
+
Windows users, that does not require you to compile the code yourself. EM
|
123
|
+
binary Gems for Windows are compiled using Visual Studio 6.
|
124
|
+
|
125
|
+
EventMachine does supply some advanced features (such as Linux EPOLL support,
|
126
|
+
reduced-privilege operation, UNIX-domain sockets, etc.) that have no
|
127
|
+
meaningful implementation on Windows. Apart from these special cases, all EM
|
128
|
+
functionality (including lightweight concurrency) works perfectly well on
|
129
|
+
Windows.
|
70
130
|
|
data/docs/SMTP
CHANGED
@@ -1,2 +1,4 @@
|
|
1
|
-
This note details the usage of EventMachine's built-in support for SMTP. EM
|
1
|
+
This note details the usage of EventMachine's built-in support for SMTP. EM
|
2
|
+
supports both client and server connections, which will be described in
|
3
|
+
separate sections.
|
2
4
|
|
data/docs/SPAWNED_PROCESSES
CHANGED
@@ -1,21 +1,30 @@
|
|
1
|
-
EventMachine (EM) adds two different formalisms for lightweight concurrency
|
1
|
+
EventMachine (EM) adds two different formalisms for lightweight concurrency
|
2
|
+
to the Ruby programmer's toolbox: spawned processes and deferrables. This
|
3
|
+
note will show you how to use spawned processes. For more information, see
|
4
|
+
the separate document LIGHTWEIGHT_CONCURRENCY.
|
2
5
|
|
3
6
|
|
4
7
|
=== What are Spawned Processes?
|
5
8
|
|
6
|
-
Spawned Processes in EventMachine are inspired directly by the "processes"
|
9
|
+
Spawned Processes in EventMachine are inspired directly by the "processes"
|
10
|
+
found in the Erlang programming language. EM deliberately borrows much (but
|
11
|
+
not all) of Erlang's terminology. However, EM's spawned processes differ from
|
12
|
+
Erlang's in ways that reflect not only Ruby style, but also the fact that
|
13
|
+
Ruby is not a functional language like Erlang.
|
7
14
|
|
8
|
-
Let's proceed with a complete, working code sample that we will analyze line
|
15
|
+
Let's proceed with a complete, working code sample that we will analyze line
|
16
|
+
by line. Here's an EM implementation of the "ping-pong" program that also
|
17
|
+
appears in the Erlang tutorial:
|
9
18
|
|
10
19
|
|
11
20
|
require 'eventmachine'
|
12
|
-
|
21
|
+
|
13
22
|
EM.run {
|
14
23
|
pong = EM.spawn {|x, ping|
|
15
24
|
puts "Pong received #{x}"
|
16
25
|
ping.notify( x-1 )
|
17
26
|
}
|
18
|
-
|
27
|
+
|
19
28
|
ping = EM.spawn {|x|
|
20
29
|
if x > 0
|
21
30
|
puts "Pinging #{x}"
|
@@ -24,7 +33,7 @@ Let's proceed with a complete, working code sample that we will analyze line by
|
|
24
33
|
EM.stop
|
25
34
|
end
|
26
35
|
}
|
27
|
-
|
36
|
+
|
28
37
|
ping.notify 3
|
29
38
|
}
|
30
39
|
|
@@ -39,17 +48,43 @@ If you run this program, you'll see the following output:
|
|
39
48
|
|
40
49
|
Let's take it step by step.
|
41
50
|
|
42
|
-
EventMachine#spawn works very much like the built-in function spawn in
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
51
|
+
EventMachine#spawn works very much like the built-in function spawn in
|
52
|
+
Erlang. It returns a reference to a Ruby object of class
|
53
|
+
EventMachine::SpawnedProcess, which is actually a schedulable entity. In
|
54
|
+
Erlang, the value returned from spawn is called a "process identifier" or
|
55
|
+
"pid." But we'll refer to the Ruby object returned from EM#spawn simply as a
|
56
|
+
"spawned process."
|
57
|
+
|
58
|
+
You pass a Ruby block with zero or more parameters to EventMachine#spawn.
|
59
|
+
Like all Ruby blocks, this one is a closure, so it can refer to variables
|
60
|
+
defined in the local context when you call EM#spawn.
|
61
|
+
|
62
|
+
However, the code block passed to EM#spawn does NOT execute immediately by
|
63
|
+
default. Rather, it will execute only when the Spawned Object is "notified."
|
64
|
+
In Erlang, this process is called "message passing," and is done with the
|
65
|
+
operator !, but in Ruby it's done simply by calling the #notify method of a
|
66
|
+
spawned-process object. The parameters you pass to #notify must match those
|
67
|
+
defined in the block that was originally passed to EM#spawn.
|
68
|
+
|
69
|
+
When you call the #notify method of a spawned-process object, EM's reactor
|
70
|
+
core will execute the code block originally passed to EM#spawn, at some point
|
71
|
+
in the future. (#notify itself merely adds a notification to the object's
|
72
|
+
message queue and ALWAYS returns immediately.)
|
73
|
+
|
74
|
+
When a SpawnedProcess object executes a notification, it does so in the
|
75
|
+
context of the SpawnedProcess object itself. The notified code block can see
|
76
|
+
local context from the point at which EM#spawn was called. However, the value
|
77
|
+
of "self" inside the notified code block is a reference to the SpawnedProcesss
|
78
|
+
object itself.
|
79
|
+
|
80
|
+
An EM spawned process is nothing more than a Ruby object with a message
|
81
|
+
queue attached to it. You can have any number of spawned processes in your
|
82
|
+
program without compromising scalability. You can notify a spawned process
|
83
|
+
any number of times, and each notification will cause a "message" to be
|
84
|
+
placed in the queue of the spawned process. Spawned processes with non-empty
|
85
|
+
message queues are scheduled for execution automatically by the EM reactor.
|
86
|
+
Spawned processes with no visible references are garbage-collected like any
|
87
|
+
other Ruby object.
|
53
88
|
|
54
89
|
Back to our code sample:
|
55
90
|
|
@@ -58,9 +93,17 @@ Back to our code sample:
|
|
58
93
|
ping.notify( x-1 )
|
59
94
|
}
|
60
95
|
|
61
|
-
This simply creates a spawned process and assigns it to the local variable
|
96
|
+
This simply creates a spawned process and assigns it to the local variable
|
97
|
+
pong. You can see that the spawned code block takes a numeric parameter and a
|
98
|
+
reference to another spawned process. When pong is notified, it expects to
|
99
|
+
receive arguments corresponding to these two parameters. It simply prints out
|
100
|
+
the number it receives as the first argument. Then it notifies the spawned
|
101
|
+
process referenced by the second argument, passing it the first argument
|
102
|
+
minus 1.
|
62
103
|
|
63
|
-
And then the block ends, which is crucial because otherwise nothing else
|
104
|
+
And then the block ends, which is crucial because otherwise nothing else
|
105
|
+
can run. (Remember that in LC, scheduled entities run to completion and are
|
106
|
+
never preempted.)
|
64
107
|
|
65
108
|
On to the next bit of the code sample:
|
66
109
|
|
@@ -73,17 +116,33 @@ On to the next bit of the code sample:
|
|
73
116
|
end
|
74
117
|
}
|
75
118
|
|
76
|
-
Here, we're spawning a process that takes a single (numeric) parameter. If
|
119
|
+
Here, we're spawning a process that takes a single (numeric) parameter. If
|
120
|
+
the parameter is greater than zero, the block writes it to the console. It
|
121
|
+
then notifies the spawned process referenced by the pong local variable,
|
122
|
+
passing as arguments its number argument, and a reference to itself. The
|
123
|
+
latter reference, as you saw above, is used by pong to send a return
|
124
|
+
notification.
|
77
125
|
|
78
|
-
If the ping process receives a zero value, it will stop the reactor loop and
|
126
|
+
If the ping process receives a zero value, it will stop the reactor loop and
|
127
|
+
end the program.
|
79
128
|
|
80
|
-
Now we've created a pair of spawned processes, but nothing else has happened.
|
129
|
+
Now we've created a pair of spawned processes, but nothing else has happened.
|
130
|
+
If we stop now, the program will spin in the EM reactor loop, doing nothing
|
131
|
+
at all. Our spawned processes will never be scheduled for execution.
|
81
132
|
|
82
133
|
But look at the next line in the code sample:
|
83
134
|
|
84
135
|
ping.notify 3
|
85
136
|
|
86
|
-
This line gets the ping-pong ball rolling. We call ping's #notify method,
|
87
|
-
|
88
|
-
|
137
|
+
This line gets the ping-pong ball rolling. We call ping's #notify method,
|
138
|
+
passing the argument 3. This causes a message to be sent to the ping spawned
|
139
|
+
process. The message contains the single argument, and it causes the EM
|
140
|
+
reactor to schedule the ping process. And this in turn results in the
|
141
|
+
execution of the Ruby code block passed to EM#spawn when ping was created.
|
142
|
+
Everything else proceeds as a result of the messages that are subsequently
|
143
|
+
passed to each other by the spawned processes.
|
144
|
+
|
145
|
+
[TODO, present the outbound network i/o use case, and clarify that spawned
|
146
|
+
processes are interleaved with normal i/o operations and don't interfere
|
147
|
+
with them at all. Also, blame Erlang for the confusing term "process"]
|
89
148
|
|
data/eventmachine.gemspec
CHANGED
@@ -1,13 +1,24 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/em/version', __FILE__)
|
2
3
|
|
3
4
|
Gem::Specification.new do |s|
|
4
|
-
s.
|
5
|
-
s.version = "0.12.10"
|
5
|
+
s.date = "2010-11-13"
|
6
6
|
|
7
|
-
s.
|
8
|
-
s.
|
9
|
-
s.
|
10
|
-
s.
|
7
|
+
s.name = 'eventmachine'
|
8
|
+
s.version = EventMachine::VERSION
|
9
|
+
s.homepage = 'http://rubyeventmachine.com'
|
10
|
+
s.rubyforge_project = 'eventmachine'
|
11
|
+
|
12
|
+
s.authors = ["Francis Cianfrocca", "Aman Gupta"]
|
13
|
+
s.email = ["garbagecat10@gmail.com", "aman@tmm1.net"]
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
|
17
|
+
|
18
|
+
s.add_development_dependency 'rake-compiler'
|
19
|
+
|
20
|
+
s.summary = 'Ruby/EventMachine library'
|
21
|
+
s.description = "EventMachine implements a fast, single-threaded engine for arbitrary network
|
11
22
|
communications. It's extremely easy to use in Ruby. EventMachine wraps all
|
12
23
|
interactions with IP sockets, allowing programs to concentrate on the
|
13
24
|
implementation of network protocols. It can be used to create both network
|
@@ -16,25 +27,7 @@ to specify the IP address and port, and provide a Module that implements the
|
|
16
27
|
communications protocol. Implementations of several standard network protocols
|
17
28
|
are provided with the package, primarily to serve as examples. The real goal
|
18
29
|
of EventMachine is to enable programs to easily interface with other programs
|
19
|
-
using TCP/IP, especially if custom protocols are required.
|
20
|
-
}
|
21
|
-
s.email = %q{garbagecat10@gmail.com}
|
22
|
-
s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
|
23
|
-
s.files = [".gitignore", "README", "Rakefile", "docs/COPYING", "docs/ChangeLog", "docs/DEFERRABLES", "docs/EPOLL", "docs/GNU", "docs/INSTALL", "docs/KEYBOARD", "docs/LEGAL", "docs/LIGHTWEIGHT_CONCURRENCY", "docs/PURE_RUBY", "docs/RELEASE_NOTES", "docs/SMTP", "docs/SPAWNED_PROCESSES", "docs/TODO", "eventmachine.gemspec", "examples/ex_channel.rb", "examples/ex_queue.rb", "examples/helper.rb", "ext/binder.cpp", "ext/binder.h", "ext/cmain.cpp", "ext/cplusplus.cpp", "ext/ed.cpp", "ext/ed.h", "ext/em.cpp", "ext/em.h", "ext/emwin.cpp", "ext/emwin.h", "ext/epoll.cpp", "ext/epoll.h", "ext/eventmachine.h", "ext/eventmachine_cpp.h", "ext/extconf.rb", "ext/fastfilereader/extconf.rb", "ext/fastfilereader/mapper.cpp", "ext/fastfilereader/mapper.h", "ext/fastfilereader/rubymain.cpp", "ext/files.cpp", "ext/files.h", "ext/kb.cpp", "ext/page.cpp", "ext/page.h", "ext/pipe.cpp", "ext/project.h", "ext/rubymain.cpp", "ext/sigs.cpp", "ext/sigs.h", "ext/ssl.cpp", "ext/ssl.h", "java/.classpath", "java/.project", "java/src/com/rubyeventmachine/EmReactor.java", "java/src/com/rubyeventmachine/EmReactorException.java", "java/src/com/rubyeventmachine/EventableChannel.java", "java/src/com/rubyeventmachine/EventableDatagramChannel.java", "java/src/com/rubyeventmachine/EventableSocketChannel.java", "java/src/com/rubyeventmachine/application/Application.java", "java/src/com/rubyeventmachine/application/Connection.java", "java/src/com/rubyeventmachine/application/ConnectionFactory.java", "java/src/com/rubyeventmachine/application/DefaultConnectionFactory.java", "java/src/com/rubyeventmachine/application/PeriodicTimer.java", "java/src/com/rubyeventmachine/application/Timer.java", "java/src/com/rubyeventmachine/tests/ApplicationTest.java", "java/src/com/rubyeventmachine/tests/ConnectTest.java", "java/src/com/rubyeventmachine/tests/EMTest.java", "java/src/com/rubyeventmachine/tests/TestDatagrams.java", "java/src/com/rubyeventmachine/tests/TestServers.java", "java/src/com/rubyeventmachine/tests/TestTimers.java", "lib/em/buftok.rb", "lib/em/callback.rb", "lib/em/channel.rb", "lib/em/connection.rb", "lib/em/deferrable.rb", "lib/em/file_watch.rb", "lib/em/future.rb", "lib/em/messages.rb", "lib/em/process_watch.rb", "lib/em/processes.rb", "lib/em/protocols.rb", "lib/em/protocols/header_and_content.rb", "lib/em/protocols/httpclient.rb", "lib/em/protocols/httpclient2.rb", "lib/em/protocols/line_and_text.rb", "lib/em/protocols/linetext2.rb", "lib/em/protocols/memcache.rb", "lib/em/protocols/object_protocol.rb", "lib/em/protocols/postgres3.rb", "lib/em/protocols/saslauth.rb", "lib/em/protocols/smtpclient.rb", "lib/em/protocols/smtpserver.rb", "lib/em/protocols/socks4.rb", "lib/em/protocols/stomp.rb", "lib/em/protocols/tcptest.rb", "lib/em/queue.rb", "lib/em/spawnable.rb", "lib/em/streamer.rb", "lib/em/timers.rb", "lib/em/version.rb", "lib/eventmachine.rb", "lib/evma.rb", "lib/evma/callback.rb", "lib/evma/container.rb", "lib/evma/factory.rb", "lib/evma/protocol.rb", "lib/evma/reactor.rb", "lib/jeventmachine.rb", "lib/pr_eventmachine.rb", "setup.rb", "tasks/cpp.rake_example", "tests/client.crt", "tests/client.key", "tests/test_attach.rb", "tests/test_basic.rb", "tests/test_channel.rb", "tests/test_connection_count.rb", "tests/test_defer.rb", "tests/test_epoll.rb", "tests/test_error_handler.rb", "tests/test_errors.rb", "tests/test_exc.rb", "tests/test_file_watch.rb", "tests/test_futures.rb", "tests/test_get_sock_opt.rb", "tests/test_handler_check.rb", "tests/test_hc.rb", "tests/test_httpclient.rb", "tests/test_httpclient2.rb", "tests/test_inactivity_timeout.rb", "tests/test_kb.rb", "tests/test_ltp.rb", "tests/test_ltp2.rb", "tests/test_next_tick.rb", "tests/test_object_protocol.rb", "tests/test_pause.rb", "tests/test_pending_connect_timeout.rb", "tests/test_process_watch.rb", "tests/test_processes.rb", "tests/test_proxy_connection.rb", "tests/test_pure.rb", "tests/test_queue.rb", "tests/test_running.rb", "tests/test_sasl.rb", "tests/test_send_file.rb", "tests/test_servers.rb", "tests/test_smtpclient.rb", "tests/test_smtpserver.rb", "tests/test_spawn.rb", "tests/test_ssl_args.rb", "tests/test_ssl_methods.rb", "tests/test_ssl_verify.rb", "tests/test_timers.rb", "tests/test_ud.rb", "tests/testem.rb", "web/whatis"]
|
24
|
-
s.homepage = %q{http://rubyeventmachine.com}
|
25
|
-
s.rdoc_options = ["--title", "EventMachine", "--main", "README", "--line-numbers", "-x", "lib/em/version", "-x", "lib/emva", "-x", "lib/evma/", "-x", "lib/pr_eventmachine", "-x", "lib/jeventmachine"]
|
26
|
-
s.require_paths = ["lib"]
|
27
|
-
s.rubyforge_project = %q{eventmachine}
|
28
|
-
s.rubygems_version = %q{1.3.5}
|
29
|
-
s.summary = %q{Ruby/EventMachine library}
|
30
|
-
|
31
|
-
if s.respond_to? :specification_version then
|
32
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
33
|
-
s.specification_version = 3
|
30
|
+
using TCP/IP, especially if custom protocols are required."
|
34
31
|
|
35
|
-
|
36
|
-
else
|
37
|
-
end
|
38
|
-
else
|
39
|
-
end
|
32
|
+
s.rdoc_options = ["--title", "EventMachine", "--main", "README", "-x", "lib/em/version", "-x", "lib/emva", "-x", "lib/evma/", "-x", "lib/jeventmachine"]
|
40
33
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class TickCounter
|
4
|
+
attr_reader :start_time, :count
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
reset
|
8
|
+
@tick_loop = EM.tick_loop(method(:tick))
|
9
|
+
end
|
10
|
+
|
11
|
+
def reset
|
12
|
+
@count = 0
|
13
|
+
@start_time = EM.current_time
|
14
|
+
end
|
15
|
+
|
16
|
+
def tick
|
17
|
+
@count += 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def rate
|
21
|
+
@count / (EM.current_time - @start_time)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
period = 5
|
26
|
+
EM.run do
|
27
|
+
counter = TickCounter.new
|
28
|
+
EM.add_periodic_timer(period) do
|
29
|
+
puts "Ticks per second: #{counter.rate} (mean of last #{period}s)"
|
30
|
+
counter.reset
|
31
|
+
end
|
32
|
+
end
|