eventmachine 1.0.0.beta.3 → 1.0.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. data/.gitignore +5 -0
  2. data/.yardopts +5 -1
  3. data/{docs/GNU → GNU} +0 -0
  4. data/Gemfile +1 -0
  5. data/{docs/COPYING → LICENSE} +0 -0
  6. data/README.md +109 -0
  7. data/Rakefile +8 -0
  8. data/docs/DocumentationGuidesIndex.md +27 -0
  9. data/docs/GettingStarted.md +521 -0
  10. data/docs/{ChangeLog → old/ChangeLog} +0 -0
  11. data/docs/{DEFERRABLES → old/DEFERRABLES} +0 -0
  12. data/docs/{EPOLL → old/EPOLL} +0 -0
  13. data/docs/{INSTALL → old/INSTALL} +0 -0
  14. data/docs/{KEYBOARD → old/KEYBOARD} +0 -0
  15. data/docs/{LEGAL → old/LEGAL} +0 -0
  16. data/docs/{LIGHTWEIGHT_CONCURRENCY → old/LIGHTWEIGHT_CONCURRENCY} +0 -0
  17. data/docs/{PURE_RUBY → old/PURE_RUBY} +0 -0
  18. data/docs/{RELEASE_NOTES → old/RELEASE_NOTES} +0 -0
  19. data/docs/{SMTP → old/SMTP} +0 -0
  20. data/docs/{SPAWNED_PROCESSES → old/SPAWNED_PROCESSES} +0 -0
  21. data/docs/{TODO → old/TODO} +0 -0
  22. data/eventmachine.gemspec +4 -1
  23. data/examples/guides/getting_started/01_eventmachine_echo_server.rb +18 -0
  24. data/examples/guides/getting_started/02_eventmachine_echo_server_that_recognizes_exit_command.rb +22 -0
  25. data/examples/guides/getting_started/03_simple_chat_server.rb +149 -0
  26. data/examples/guides/getting_started/04_simple_chat_server_step_one.rb +27 -0
  27. data/examples/guides/getting_started/05_simple_chat_server_step_two.rb +43 -0
  28. data/examples/guides/getting_started/06_simple_chat_server_step_three.rb +98 -0
  29. data/examples/guides/getting_started/07_simple_chat_server_step_four.rb +121 -0
  30. data/examples/guides/getting_started/08_simple_chat_server_step_five.rb +141 -0
  31. data/examples/{ex_channel.rb → old/ex_channel.rb} +3 -3
  32. data/examples/{ex_queue.rb → old/ex_queue.rb} +0 -0
  33. data/examples/{ex_tick_loop_array.rb → old/ex_tick_loop_array.rb} +0 -0
  34. data/examples/{ex_tick_loop_counter.rb → old/ex_tick_loop_counter.rb} +0 -0
  35. data/examples/{helper.rb → old/helper.rb} +0 -0
  36. data/ext/cmain.cpp +3 -3
  37. data/ext/ed.cpp +90 -15
  38. data/ext/ed.h +5 -5
  39. data/ext/em.cpp +47 -55
  40. data/ext/em.h +12 -2
  41. data/ext/pipe.cpp +2 -2
  42. data/ext/project.h +1 -1
  43. data/ext/rubymain.cpp +48 -3
  44. data/ext/ssl.cpp +5 -0
  45. data/java/src/com/rubyeventmachine/EmReactor.java +2 -2
  46. data/lib/em/buftok.rb +35 -63
  47. data/lib/em/callback.rb +43 -11
  48. data/lib/em/channel.rb +21 -14
  49. data/lib/em/completion.rb +304 -0
  50. data/lib/em/connection.rb +339 -209
  51. data/lib/em/deferrable.rb +4 -0
  52. data/lib/em/deferrable/pool.rb +2 -0
  53. data/lib/em/file_watch.rb +37 -18
  54. data/lib/em/iterator.rb +42 -42
  55. data/lib/em/pool.rb +146 -0
  56. data/lib/em/process_watch.rb +5 -4
  57. data/lib/em/processes.rb +8 -4
  58. data/lib/em/protocols/httpclient.rb +22 -11
  59. data/lib/em/protocols/httpclient2.rb +15 -5
  60. data/lib/em/protocols/line_protocol.rb +2 -1
  61. data/lib/em/protocols/memcache.rb +17 -9
  62. data/lib/em/protocols/object_protocol.rb +2 -1
  63. data/lib/em/protocols/postgres3.rb +8 -9
  64. data/lib/em/protocols/smtpclient.rb +19 -11
  65. data/lib/em/protocols/smtpserver.rb +1 -1
  66. data/lib/em/protocols/stomp.rb +8 -6
  67. data/lib/em/protocols/tcptest.rb +3 -2
  68. data/lib/em/pure_ruby.rb +212 -208
  69. data/lib/em/queue.rb +22 -13
  70. data/lib/em/resolver.rb +70 -64
  71. data/lib/em/spawnable.rb +6 -3
  72. data/lib/em/streamer.rb +33 -45
  73. data/lib/em/threaded_resource.rb +90 -0
  74. data/lib/em/timers.rb +6 -2
  75. data/lib/em/version.rb +1 -1
  76. data/lib/eventmachine.rb +538 -602
  77. data/lib/jeventmachine.rb +22 -1
  78. data/tasks/package.rake +12 -2
  79. data/tasks/test.rake +1 -0
  80. data/tests/em_test_helper.rb +12 -3
  81. data/tests/test_completion.rb +177 -0
  82. data/tests/test_epoll.rb +2 -2
  83. data/tests/test_httpclient.rb +9 -9
  84. data/tests/test_httpclient2.rb +11 -9
  85. data/tests/test_ltp.rb +2 -10
  86. data/tests/test_pool.rb +128 -0
  87. data/tests/test_processes.rb +20 -2
  88. data/tests/test_queue.rb +8 -0
  89. data/tests/test_resolver.rb +1 -1
  90. data/tests/test_set_sock_opt.rb +37 -0
  91. data/tests/test_shutdown_hooks.rb +23 -0
  92. data/tests/test_threaded_resource.rb +53 -0
  93. data/tests/test_unbind_reason.rb +31 -0
  94. metadata +262 -192
  95. data/README +0 -81
  96. data/tasks/doc.rake +0 -30
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -14,6 +14,8 @@ Gem::Specification.new do |s|
14
14
  s.extensions = ["ext/extconf.rb", "ext/fastfilereader/extconf.rb"]
15
15
 
16
16
  s.add_development_dependency 'rake-compiler', '0.7.6'
17
+ s.add_development_dependency 'yard', ">= 0.7.2"
18
+ s.add_development_dependency 'bluecloth'
17
19
 
18
20
  s.summary = 'Ruby/EventMachine library'
19
21
  s.description = "EventMachine implements a fast, single-threaded engine for arbitrary network
@@ -27,5 +29,6 @@ are provided with the package, primarily to serve as examples. The real goal
27
29
  of EventMachine is to enable programs to easily interface with other programs
28
30
  using TCP/IP, especially if custom protocols are required."
29
31
 
30
- s.rdoc_options = ["--title", "EventMachine", "--main", "README", "-x", "lib/em/version", "-x", "lib/jeventmachine"]
32
+ s.rdoc_options = ["--title", "EventMachine", "--main", "README.md", "-x", "lib/em/version", "-x", "lib/jeventmachine"]
33
+ s.extra_rdoc_files = ["README.md"] + `git ls-files -- docs/*`.split("\n")
31
34
  end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class EchoServer < EM::Connection
7
+ def receive_data(data)
8
+ send_data(data)
9
+ end
10
+ end
11
+
12
+ EventMachine.run do
13
+ # hit Control + C to stop
14
+ Signal.trap("INT") { EventMachine.stop }
15
+ Signal.trap("TERM") { EventMachine.stop }
16
+
17
+ EventMachine.start_server("0.0.0.0", 10000, EchoServer)
18
+ end
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class EchoServer < EM::Connection
7
+ def receive_data(data)
8
+ if data.strip =~ /exit$/i
9
+ EventMachine.stop
10
+ else
11
+ send_data(data)
12
+ end
13
+ end
14
+ end
15
+
16
+ EventMachine.run do
17
+ # hit Control + C to stop
18
+ Signal.trap("INT") { EventMachine.stop }
19
+ Signal.trap("TERM") { EventMachine.stop }
20
+
21
+ EventMachine.start_server("0.0.0.0", 10000, EchoServer)
22
+ end
@@ -0,0 +1,149 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class SimpleChatServer < EM::Connection
7
+
8
+ @@connected_clients = Array.new
9
+ DM_REGEXP = /^@([a-zA-Z0-9]+)\s*:?\s*(.+)/.freeze
10
+
11
+ attr_reader :username
12
+
13
+
14
+ #
15
+ # EventMachine handlers
16
+ #
17
+
18
+ def post_init
19
+ @username = nil
20
+
21
+ puts "A client has connected..."
22
+ ask_username
23
+ end
24
+
25
+ def unbind
26
+ @@connected_clients.delete(self)
27
+ puts "[info] #{@username} has left" if entered_username?
28
+ end
29
+
30
+ def receive_data(data)
31
+ if entered_username?
32
+ handle_chat_message(data.strip)
33
+ else
34
+ handle_username(data.strip)
35
+ end
36
+ end
37
+
38
+
39
+ #
40
+ # Username handling
41
+ #
42
+
43
+ def entered_username?
44
+ !@username.nil? && !@username.empty?
45
+ end # entered_username?
46
+
47
+ def handle_username(input)
48
+ if input.empty?
49
+ send_line("Blank usernames are not allowed. Try again.")
50
+ ask_username
51
+ else
52
+ @username = input
53
+ @@connected_clients.push(self)
54
+ self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
55
+ puts "#{@username} has joined"
56
+
57
+ self.send_line("[info] Ohai, #{@username}")
58
+ end
59
+ end # handle_username(input)
60
+
61
+ def ask_username
62
+ self.send_line("[info] Enter your username:")
63
+ end # ask_username
64
+
65
+
66
+ #
67
+ # Message handling
68
+ #
69
+
70
+ def handle_chat_message(msg)
71
+ if command?(msg)
72
+ self.handle_command(msg)
73
+ else
74
+ if direct_message?(msg)
75
+ self.handle_direct_message(msg)
76
+ else
77
+ self.announce(msg, "#{@username}:")
78
+ end
79
+ end
80
+ end # handle_chat_message(msg)
81
+
82
+ def direct_message?(input)
83
+ input =~ DM_REGEXP
84
+ end # direct_message?(input)
85
+
86
+ def handle_direct_message(input)
87
+ username, message = parse_direct_message(input)
88
+
89
+ if connection = @@connected_clients.find { |c| c.username == username }
90
+ puts "[dm] @#{@username} => @#{username}"
91
+ connection.send_line("[dm] @#{@username}: #{message}")
92
+ else
93
+ send_line "@#{username} is not in the room. Here's who is: #{usernames.join(', ')}"
94
+ end
95
+ end # handle_direct_message(input)
96
+
97
+ def parse_direct_message(input)
98
+ return [$1, $2] if input =~ DM_REGEXP
99
+ end # parse_direct_message(input)
100
+
101
+
102
+ #
103
+ # Commands handling
104
+ #
105
+
106
+ def command?(input)
107
+ input =~ /(exit|status)$/i
108
+ end # command?(input)
109
+
110
+ def handle_command(cmd)
111
+ case cmd
112
+ when /exit$/i then self.close_connection
113
+ when /status$/i then self.send_line("[chat server] It's #{Time.now.strftime('%H:%M')} and there are #{self.number_of_connected_clients} people in the room")
114
+ end
115
+ end # handle_command(cmd)
116
+
117
+
118
+ #
119
+ # Helpers
120
+ #
121
+
122
+ def announce(msg = nil, prefix = "[chat server]")
123
+ @@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty?
124
+ end # announce(msg)
125
+
126
+ def number_of_connected_clients
127
+ @@connected_clients.size
128
+ end # number_of_connected_clients
129
+
130
+ def other_peers
131
+ @@connected_clients.reject { |c| self == c }
132
+ end # other_peers
133
+
134
+ def send_line(line)
135
+ self.send_data("#{line}\n")
136
+ end # send_line(line)
137
+
138
+ def usernames
139
+ @@connected_clients.map { |c| c.username }
140
+ end # usernames
141
+ end
142
+
143
+ EventMachine.run do
144
+ # hit Control + C to stop
145
+ Signal.trap("INT") { EventMachine.stop }
146
+ Signal.trap("TERM") { EventMachine.stop }
147
+
148
+ EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
149
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class SimpleChatServer < EM::Connection
7
+
8
+ #
9
+ # EventMachine handlers
10
+ #
11
+
12
+ def post_init
13
+ puts "A client has connected..."
14
+ end
15
+
16
+ def unbind
17
+ puts "A client has left..."
18
+ end
19
+ end
20
+
21
+ EventMachine.run do
22
+ # hit Control + C to stop
23
+ Signal.trap("INT") { EventMachine.stop }
24
+ Signal.trap("TERM") { EventMachine.stop }
25
+
26
+ EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
27
+ end
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class SimpleChatServer < EM::Connection
7
+
8
+ @@connected_clients = Array.new
9
+
10
+
11
+ #
12
+ # EventMachine handlers
13
+ #
14
+
15
+ def post_init
16
+ @@connected_clients.push(self)
17
+ puts "A client has connected..."
18
+ end
19
+
20
+ def unbind
21
+ @@connected_clients.delete(self)
22
+ puts "A client has left..."
23
+ end
24
+
25
+
26
+
27
+
28
+ #
29
+ # Helpers
30
+ #
31
+
32
+ def other_peers
33
+ @@connected_clients.reject { |c| self == c }
34
+ end # other_peers
35
+ end
36
+
37
+ EventMachine.run do
38
+ # hit Control + C to stop
39
+ Signal.trap("INT") { EventMachine.stop }
40
+ Signal.trap("TERM") { EventMachine.stop }
41
+
42
+ EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
43
+ end
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class SimpleChatServer < EM::Connection
7
+
8
+ @@connected_clients = Array.new
9
+
10
+
11
+ attr_reader :username
12
+
13
+
14
+ #
15
+ # EventMachine handlers
16
+ #
17
+
18
+ def post_init
19
+ @username = nil
20
+
21
+ puts "A client has connected..."
22
+ ask_username
23
+ end
24
+
25
+ def unbind
26
+ @@connected_clients.delete(self)
27
+ puts "A client has left..."
28
+ end
29
+
30
+ def receive_data(data)
31
+ if entered_username?
32
+ handle_chat_message(data.strip)
33
+ else
34
+ handle_username(data.strip)
35
+ end
36
+ end
37
+
38
+
39
+
40
+
41
+ #
42
+ # Username handling
43
+ #
44
+
45
+ def entered_username?
46
+ !@username.nil? && !@username.empty?
47
+ end # entered_username?
48
+
49
+ def handle_username(input)
50
+ if input.empty?
51
+ send_line("Blank usernames are not allowed. Try again.")
52
+ ask_username
53
+ else
54
+ @username = input
55
+ @@connected_clients.push(self)
56
+ self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
57
+ puts "#{@username} has joined"
58
+
59
+ self.send_line("[info] Ohai, #{@username}")
60
+ end
61
+ end # handle_username(input)
62
+
63
+ def ask_username
64
+ self.send_line("[info] Enter your username:")
65
+ end # ask_username
66
+
67
+
68
+
69
+ #
70
+ # Message handling
71
+ #
72
+
73
+ def handle_chat_message(msg)
74
+ raise NotImplementedError
75
+ end
76
+
77
+
78
+
79
+ #
80
+ # Helpers
81
+ #
82
+
83
+ def other_peers
84
+ @@connected_clients.reject { |c| self == c }
85
+ end # other_peers
86
+
87
+ def send_line(line)
88
+ self.send_data("#{line}\n")
89
+ end # send_line(line)
90
+ end
91
+
92
+ EventMachine.run do
93
+ # hit Control + C to stop
94
+ Signal.trap("INT") { EventMachine.stop }
95
+ Signal.trap("TERM") { EventMachine.stop }
96
+
97
+ EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
98
+ end
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems' # or use Bundler.setup
4
+ require 'eventmachine'
5
+
6
+ class SimpleChatServer < EM::Connection
7
+
8
+ @@connected_clients = Array.new
9
+
10
+
11
+ attr_reader :username
12
+
13
+
14
+ #
15
+ # EventMachine handlers
16
+ #
17
+
18
+ def post_init
19
+ @username = nil
20
+
21
+ puts "A client has connected..."
22
+ ask_username
23
+ end
24
+
25
+ def unbind
26
+ @@connected_clients.delete(self)
27
+ puts "[info] #{@username} has left" if entered_username?
28
+ end
29
+
30
+ def receive_data(data)
31
+ if entered_username?
32
+ handle_chat_message(data.strip)
33
+ else
34
+ handle_username(data.strip)
35
+ end
36
+ end
37
+
38
+
39
+
40
+
41
+ #
42
+ # Username handling
43
+ #
44
+
45
+ def entered_username?
46
+ !@username.nil? && !@username.empty?
47
+ end # entered_username?
48
+
49
+ def handle_username(input)
50
+ if input.empty?
51
+ send_line("Blank usernames are not allowed. Try again.")
52
+ ask_username
53
+ else
54
+ @username = input
55
+ @@connected_clients.push(self)
56
+ self.other_peers.each { |c| c.send_data("#{@username} has joined the room\n") }
57
+ puts "#{@username} has joined"
58
+
59
+ self.send_line("[info] Ohai, #{@username}")
60
+ end
61
+ end # handle_username(input)
62
+
63
+ def ask_username
64
+ self.send_line("[info] Enter your username:")
65
+ end # ask_username
66
+
67
+
68
+
69
+ #
70
+ # Message handling
71
+ #
72
+
73
+ def handle_chat_message(msg)
74
+ if command?(msg)
75
+ self.handle_command(msg)
76
+ else
77
+ self.announce(msg, "#{@username}:")
78
+ end
79
+ end
80
+
81
+
82
+ #
83
+ # Commands handling
84
+ #
85
+
86
+ def command?(input)
87
+ input =~ /exit$/i
88
+ end # command?(input)
89
+
90
+ def handle_command(cmd)
91
+ case cmd
92
+ when /exit$/i then self.close_connection
93
+ end
94
+ end # handle_command(cmd)
95
+
96
+
97
+
98
+ #
99
+ # Helpers
100
+ #
101
+
102
+ def announce(msg = nil, prefix = "[chat server]")
103
+ @@connected_clients.each { |c| c.send_line("#{prefix} #{msg}") } unless msg.empty?
104
+ end # announce(msg)
105
+
106
+ def other_peers
107
+ @@connected_clients.reject { |c| self == c }
108
+ end # other_peers
109
+
110
+ def send_line(line)
111
+ self.send_data("#{line}\n")
112
+ end # send_line(line)
113
+ end
114
+
115
+ EventMachine.run do
116
+ # hit Control + C to stop
117
+ Signal.trap("INT") { EventMachine.stop }
118
+ Signal.trap("TERM") { EventMachine.stop }
119
+
120
+ EventMachine.start_server("0.0.0.0", 10000, SimpleChatServer)
121
+ end