packet 0.1.5 → 0.1.7
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/README +0 -1
- data/Rakefile +4 -23
- data/bin/packet_worker_runner +50 -0
- data/lib/packet.rb +4 -1
- data/lib/packet/double_keyed_hash.rb +33 -24
- data/lib/packet/packet_callback.rb +1 -0
- data/lib/packet/packet_connection.rb +57 -7
- data/lib/packet/packet_core.rb +57 -30
- data/lib/packet/packet_event.rb +1 -1
- data/lib/packet/packet_guid.rb +1 -0
- data/lib/packet/packet_helper.rb +15 -43
- data/lib/packet/packet_invalid_worker.rb +8 -0
- data/lib/packet/packet_master.rb +31 -48
- data/lib/packet/packet_meta_pimp.rb +3 -3
- data/lib/packet/packet_nbio.rb +19 -10
- data/lib/packet/packet_parser.rb +72 -66
- data/lib/packet/packet_pimp.rb +0 -1
- data/lib/packet/packet_worker.rb +16 -18
- metadata +6 -10
- data/examples/netbeans.jpg +0 -0
- data/lib/packet.rbc +0 -0
- data/spec/spec_helper.rb +0 -10
- data/spec/test_double_keyed_hash.rb +0 -14
- data/spec/test_packet_core.rb +0 -39
data/README
CHANGED
data/Rakefile
CHANGED
@@ -17,6 +17,7 @@ $LOAD_PATH.unshift __DIR__+'/lib'
|
|
17
17
|
require 'packet'
|
18
18
|
|
19
19
|
CLEAN.include ['**/.*.sw?', '*.gem', '.config','*.rbc']
|
20
|
+
Dir["tasks/**/*.rake"].each { |rake| load rake }
|
20
21
|
|
21
22
|
|
22
23
|
@windows = (PLATFORM =~ /win32/)
|
@@ -30,17 +31,6 @@ task :default => [:package]
|
|
30
31
|
|
31
32
|
task :doc => [:rdoc]
|
32
33
|
|
33
|
-
|
34
|
-
Rake::RDocTask.new do |rdoc|
|
35
|
-
files = ['README', 'MIT-LICENSE', 'CHANGELOG',
|
36
|
-
'lib/**/*.rb']
|
37
|
-
rdoc.rdoc_files.add(files)
|
38
|
-
rdoc.main = 'README'
|
39
|
-
rdoc.title = 'Packet Docs'
|
40
|
-
rdoc.rdoc_dir = 'doc/rdoc'
|
41
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
42
|
-
end
|
43
|
-
|
44
34
|
spec = Gem::Specification.new do |s|
|
45
35
|
s.name = NAME
|
46
36
|
s.version = Packet::VERSION
|
@@ -55,10 +45,10 @@ spec = Gem::Specification.new do |s|
|
|
55
45
|
s.email = 'mail@gnufied.org'
|
56
46
|
s.homepage = 'http://code.google.com/p/packet/'
|
57
47
|
s.required_ruby_version = '>= 1.8.5'
|
58
|
-
|
59
48
|
s.files = %w(MIT-LICENSE README Rakefile TODO) + Dir.glob("{spec,lib,examples}/**/*")
|
60
|
-
|
61
49
|
s.require_path = "lib"
|
50
|
+
s.bindir = "bin"
|
51
|
+
s.executables = "packet_worker_runner"
|
62
52
|
end
|
63
53
|
|
64
54
|
Rake::GemPackageTask.new(spec) do |p|
|
@@ -75,16 +65,6 @@ task :uninstall => [:clean] do
|
|
75
65
|
sh %{#{SUDO} gem uninstall #{NAME}}
|
76
66
|
end
|
77
67
|
|
78
|
-
##############################################################################
|
79
|
-
# SVN
|
80
|
-
##############################################################################
|
81
|
-
|
82
|
-
desc "Add new files to subversion"
|
83
|
-
task :svn_add do
|
84
|
-
system "svn status | grep '^\?' | sed -e 's/? *//' | sed -e 's/ /\ /g' | xargs svn add"
|
85
|
-
end
|
86
|
-
|
87
|
-
|
88
68
|
desc "Converts a YAML file into a test/spec skeleton"
|
89
69
|
task :yaml_to_spec do
|
90
70
|
require 'yaml'
|
@@ -93,3 +73,4 @@ task :yaml_to_spec do
|
|
93
73
|
t+(s ?%.context "#{c}" do.+s.map{|d|%.\n xspecify "#{d}" do\n end\n.}*''+"end\n\n":'')
|
94
74
|
}.strip
|
95
75
|
end
|
76
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
PACKET_LIB_PATH = File.expand_path(File.dirname(__FILE__))
|
3
|
+
["lib"].each { |x| $LOAD_PATH.unshift(File.join(PACKET_LIB_PATH,"..",x))}
|
4
|
+
|
5
|
+
require "packet"
|
6
|
+
|
7
|
+
module Packet
|
8
|
+
class WorkerRunner
|
9
|
+
include Packet::NbioHelper
|
10
|
+
def initialize args
|
11
|
+
cmd_args = args.split(':')
|
12
|
+
worker_name = cmd_args[2]
|
13
|
+
initial_arg_data_length = cmd_args[3].to_i
|
14
|
+
@worker_root = cmd_args[4]
|
15
|
+
@worker_load_env = cmd_args[5]
|
16
|
+
|
17
|
+
|
18
|
+
@worker_read_fd = UNIXSocket.for_fd(cmd_args[0].to_i)
|
19
|
+
|
20
|
+
@worker_write_fd = UNIXSocket.for_fd(cmd_args[1].to_i)
|
21
|
+
|
22
|
+
initial_arg_data = @worker_read_fd.read(initial_arg_data_length)
|
23
|
+
|
24
|
+
Packet::WorkerRunner.const_set(:WORKER_OPTIONS,Marshal.load(initial_arg_data))
|
25
|
+
require @worker_load_env if @worker_load_env && !@worker_load_env.empty?
|
26
|
+
load_worker worker_name
|
27
|
+
end
|
28
|
+
|
29
|
+
def load_worker worker_name
|
30
|
+
if @worker_root && (File.file? "#{@worker_root}/#{worker_name}.rb")
|
31
|
+
require "#{@worker_root}/#{worker_name}"
|
32
|
+
worker_klass = Object.const_get(packet_classify(worker_name))
|
33
|
+
worker_klass.start_worker(:read_end => @worker_read_fd,:write_end => @worker_write_fd,:options => WORKER_OPTIONS)
|
34
|
+
else
|
35
|
+
require worker_name
|
36
|
+
worker_klass = Object.const_get(packet_classify(worker_name))
|
37
|
+
if worker_klass.is_worker?
|
38
|
+
worker_klass.start_worker(:read_end => @worker_read_fd,:write_end => @worker_write_fd,:options => WORKER_OPTIONS)
|
39
|
+
else
|
40
|
+
raise Packet::InvalidWorker.new(worker_name)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
Packet::WorkerRunner.new(ARGV[0])
|
48
|
+
|
49
|
+
|
50
|
+
|
data/lib/packet.rb
CHANGED
@@ -6,8 +6,11 @@ require "yaml"
|
|
6
6
|
require "forwardable"
|
7
7
|
require "ostruct"
|
8
8
|
require "thread"
|
9
|
+
require "fcntl"
|
10
|
+
#require "enumerable"
|
9
11
|
|
10
12
|
require "packet/packet_parser"
|
13
|
+
require "packet/packet_invalid_worker"
|
11
14
|
require "packet/packet_guid"
|
12
15
|
require "packet/packet_helper"
|
13
16
|
require "packet/double_keyed_hash"
|
@@ -26,5 +29,5 @@ require "packet/packet_worker"
|
|
26
29
|
PACKET_APP = File.expand_path'../' unless defined?(PACKET_APP)
|
27
30
|
|
28
31
|
module Packet
|
29
|
-
VERSION='0.1.
|
32
|
+
VERSION='0.1.7'
|
30
33
|
end
|
@@ -1,31 +1,40 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Packet
|
2
|
+
class DoubleKeyedHash
|
3
|
+
# include Enumerable
|
4
|
+
attr_accessor :internal_hash
|
5
|
+
def initialize
|
6
|
+
@keys1 = {}
|
7
|
+
@internal_hash = {}
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def []=(key1,key2,value)
|
11
|
+
@keys1[key2] = key1
|
12
|
+
@internal_hash[key1] = value
|
13
|
+
end
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
def [] key
|
16
|
+
@internal_hash[key] || @internal_hash[@keys1[key]]
|
17
|
+
end
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
def delete(key)
|
20
|
+
t_key = @keys1[key]
|
21
|
+
if t_key
|
22
|
+
@keys1.delete(key)
|
23
|
+
@internal_hash.delete(t_key)
|
24
|
+
else
|
25
|
+
@keys1.delete_if { |key,value| value == key }
|
26
|
+
@internal_hash.delete(key)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def length
|
31
|
+
@internal_hash.keys.length
|
25
32
|
end
|
26
|
-
end
|
27
33
|
|
28
|
-
|
29
|
-
|
34
|
+
def each
|
35
|
+
@internal_hash.each { |key,value| yield(key,value)}
|
36
|
+
end
|
30
37
|
end
|
31
38
|
end
|
39
|
+
|
40
|
+
|
@@ -1,14 +1,18 @@
|
|
1
|
-
# FIMXE: following class must modify the fd_watchlist thats being monitored by
|
2
|
-
# main eventloop.
|
3
|
-
|
4
1
|
module Packet
|
5
2
|
module Connection
|
6
3
|
attr_accessor :outbound_data,:connection_live
|
4
|
+
attr_accessor :worker,:connection,:reactor, :initialized,:signature
|
5
|
+
include NbioHelper
|
6
|
+
|
7
|
+
def unbind; end
|
8
|
+
def connection_completed; end
|
9
|
+
def post_init; end
|
10
|
+
def receive_data data; end
|
7
11
|
|
8
12
|
def send_data p_data
|
9
13
|
@outbound_data << p_data
|
10
14
|
begin
|
11
|
-
write_and_schedule(connection)
|
15
|
+
write_and_schedule(connection)
|
12
16
|
rescue DisconnectError => sock
|
13
17
|
close_connection
|
14
18
|
end
|
@@ -18,23 +22,69 @@ module Packet
|
|
18
22
|
@initialized = true
|
19
23
|
@connection_live = true
|
20
24
|
@outbound_data = []
|
21
|
-
post_init
|
25
|
+
post_init
|
22
26
|
end
|
23
27
|
|
24
28
|
def close_connection(sock = nil)
|
25
|
-
unbind
|
29
|
+
unbind
|
26
30
|
reactor.cancel_write(connection)
|
27
31
|
reactor.remove_connection(connection)
|
28
32
|
end
|
29
33
|
|
30
34
|
def close_connection_after_writing
|
31
|
-
connection.flush
|
35
|
+
connection.flush unless connection.closed?
|
32
36
|
close_connection
|
33
37
|
end
|
34
38
|
|
39
|
+
def get_peername
|
40
|
+
connection.getpeername
|
41
|
+
end
|
42
|
+
|
35
43
|
def send_object p_object
|
36
44
|
dump_object(p_object,connection)
|
37
45
|
end
|
38
46
|
|
47
|
+
def ask_worker(*args)
|
48
|
+
worker_name = args.shift
|
49
|
+
data_options = *args
|
50
|
+
data_options[:client_signature] = connection.fileno
|
51
|
+
t_worker = reactor.live_workers[worker_name]
|
52
|
+
raise Packet::InvalidWorker.new("Invalid worker with name #{worker_name} and key #{data_options[:data][:worker_key]}") unless t_worker
|
53
|
+
t_worker.send_request(data_options)
|
54
|
+
end
|
55
|
+
def start_server ip,port,t_module,&block
|
56
|
+
reactor.start_server(ip,port,t_module,block)
|
57
|
+
end
|
58
|
+
|
59
|
+
def connect ip,port,t_module,&block
|
60
|
+
reactor.connect(ip,port,t_module,block)
|
61
|
+
end
|
62
|
+
|
63
|
+
def add_periodic_timer interval, &block
|
64
|
+
reactor.add_periodic_timer(interval,block)
|
65
|
+
end
|
66
|
+
|
67
|
+
def add_timer(t_time,&block)
|
68
|
+
reactor.add_timer(t_time,block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def cancel_timer(t_timer)
|
72
|
+
reactor.cancel_timer(t_timer)
|
73
|
+
end
|
74
|
+
|
75
|
+
def reconnect server,port,handler
|
76
|
+
reactor.reconnect(server,port,handler)
|
77
|
+
end
|
78
|
+
|
79
|
+
def start_worker(worker_options = {})
|
80
|
+
reactor.start_worker(worker_options)
|
81
|
+
end
|
82
|
+
|
83
|
+
def delete_worker worker_options = {}
|
84
|
+
reactor.delete_worker(worker_options)
|
85
|
+
end
|
86
|
+
|
39
87
|
end # end of class Connection
|
40
88
|
end # end of module Packet
|
89
|
+
|
90
|
+
|
data/lib/packet/packet_core.rb
CHANGED
@@ -4,9 +4,8 @@ module Packet
|
|
4
4
|
def self.included(base_klass)
|
5
5
|
base_klass.extend(ClassMethods)
|
6
6
|
base_klass.instance_eval do
|
7
|
-
|
8
|
-
|
9
|
-
cattr_accessor :connection_callbacks
|
7
|
+
iattr_accessor :connection_callbacks
|
8
|
+
inheritable_attribute(:connection_callbacks,:default => {})
|
10
9
|
attr_accessor :read_ios, :write_ios, :listen_sockets
|
11
10
|
attr_accessor :connection_completion_awaited,:write_scheduled
|
12
11
|
attr_accessor :connections, :windows_flag
|
@@ -22,6 +21,7 @@ module Packet
|
|
22
21
|
connection_callbacks[:after_connection] << p_method
|
23
22
|
end
|
24
23
|
|
24
|
+
# FIXME: following callbacks hasn't been tested and not usable.
|
25
25
|
def after_unbind p_method
|
26
26
|
connection_callbacks[:after_unbind] ||= []
|
27
27
|
connection_callbacks[:after_unbind] << p_method
|
@@ -53,7 +53,9 @@ module Packet
|
|
53
53
|
|
54
54
|
def reconnect(server,port,handler)
|
55
55
|
raise "invalid handler" unless handler.respond_to?(:connection_completed)
|
56
|
-
|
56
|
+
if !handler.connection.closed? && connections.keys.include?(handler.connection.fileno)
|
57
|
+
return handler
|
58
|
+
end
|
57
59
|
connect(server,port,handler)
|
58
60
|
end
|
59
61
|
|
@@ -101,9 +103,10 @@ module Packet
|
|
101
103
|
connections.delete(t_sock.fileno)
|
102
104
|
t_sock.close
|
103
105
|
rescue
|
106
|
+
puts "#{$!.message}"
|
104
107
|
end
|
105
108
|
end
|
106
|
-
|
109
|
+
|
107
110
|
def next_turn &block
|
108
111
|
@on_next_tick = block
|
109
112
|
end
|
@@ -111,7 +114,17 @@ module Packet
|
|
111
114
|
# method opens a socket for listening
|
112
115
|
def start_server(ip,port,t_module,&block)
|
113
116
|
BasicSocket.do_not_reverse_lookup = true
|
114
|
-
|
117
|
+
# Comment TCPServer for the time being
|
118
|
+
#t_socket = TCPServer.new(ip,port.to_i)
|
119
|
+
#t_socket = TCPSocket.
|
120
|
+
|
121
|
+
t_socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
|
122
|
+
t_socket.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR,true)
|
123
|
+
sockaddr = Socket.sockaddr_in(port.to_i,ip)
|
124
|
+
t_socket.bind(sockaddr)
|
125
|
+
t_socket.listen(50)
|
126
|
+
t_socket.setsockopt(Socket::IPPROTO_TCP,Socket::TCP_NODELAY,1)
|
127
|
+
|
115
128
|
# t_socket.setsockopt(*@tcp_defer_accept_opts) rescue nil
|
116
129
|
listen_sockets[t_socket.fileno] = { :socket => t_socket,:block => block,:module => t_module }
|
117
130
|
@read_ios << t_socket
|
@@ -124,7 +137,8 @@ module Packet
|
|
124
137
|
loop do
|
125
138
|
check_for_timer_events
|
126
139
|
@on_next_tick.call if @on_next_tick
|
127
|
-
|
140
|
+
|
141
|
+
ready_read_fds,ready_write_fds,read_error_fds = select(read_ios,write_ios,[],0.005)
|
128
142
|
|
129
143
|
if ready_read_fds && !ready_read_fds.empty?
|
130
144
|
handle_read_event(ready_read_fds)
|
@@ -135,23 +149,25 @@ module Packet
|
|
135
149
|
|
136
150
|
end
|
137
151
|
|
138
|
-
def schedule_write(t_sock)
|
152
|
+
def schedule_write(t_sock,internal_instance = nil)
|
139
153
|
fileno = t_sock.fileno
|
140
154
|
if UNIXSocket === t_sock && internal_scheduled_write[fileno].nil?
|
141
155
|
write_ios << t_sock
|
142
|
-
internal_scheduled_write[t_sock.fileno] ||=
|
143
|
-
elsif write_scheduled[fileno].nil?
|
156
|
+
internal_scheduled_write[t_sock.fileno] ||= internal_instance
|
157
|
+
elsif write_scheduled[fileno].nil? && !(t_sock.is_a?(UNIXSocket))
|
144
158
|
write_ios << t_sock
|
145
|
-
write_scheduled[fileno] ||= connections[fileno]
|
159
|
+
write_scheduled[fileno] ||= connections[fileno][:instance]
|
146
160
|
end
|
147
161
|
end
|
148
162
|
|
149
163
|
def cancel_write(t_sock)
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
164
|
+
if !t_sock.closed?
|
165
|
+
fileno = t_sock.fileno
|
166
|
+
if UNIXSocket === t_sock
|
167
|
+
internal_scheduled_write.delete(fileno)
|
168
|
+
else
|
169
|
+
write_scheduled.delete(fileno)
|
170
|
+
end
|
155
171
|
end
|
156
172
|
write_ios.delete(t_sock)
|
157
173
|
end
|
@@ -159,12 +175,12 @@ module Packet
|
|
159
175
|
def handle_write_event(p_ready_fds)
|
160
176
|
p_ready_fds.each do |sock_fd|
|
161
177
|
fileno = sock_fd.fileno
|
162
|
-
if UNIXSocket === sock_fd && internal_scheduled_write[fileno]
|
163
|
-
write_and_schedule(sock_fd)
|
178
|
+
if UNIXSocket === sock_fd && (internal_instance = internal_scheduled_write[fileno])
|
179
|
+
internal_instance.write_and_schedule(sock_fd)
|
164
180
|
elsif extern_opts = connection_completion_awaited[fileno]
|
165
181
|
complete_connection(sock_fd,extern_opts)
|
166
182
|
elsif handler_instance = write_scheduled[fileno]
|
167
|
-
handler_instance.
|
183
|
+
handler_instance.write_and_schedule(sock_fd)
|
168
184
|
end
|
169
185
|
end
|
170
186
|
end
|
@@ -172,7 +188,7 @@ module Packet
|
|
172
188
|
def handle_read_event(p_ready_fds)
|
173
189
|
ready_fds = p_ready_fds.flatten.compact
|
174
190
|
ready_fds.each do |t_sock|
|
175
|
-
if(
|
191
|
+
if(t_sock.is_a?(UNIXSocket))
|
176
192
|
handle_internal_messages(t_sock)
|
177
193
|
else
|
178
194
|
handle_external_messages(t_sock)
|
@@ -206,11 +222,12 @@ module Packet
|
|
206
222
|
end
|
207
223
|
|
208
224
|
def read_external_socket(t_sock)
|
209
|
-
handler_instance = connections[t_sock.fileno]
|
225
|
+
handler_instance = connections[t_sock.fileno][:instance]
|
210
226
|
begin
|
211
227
|
t_data = read_data(t_sock)
|
212
|
-
handler_instance.receive_data(t_data)
|
228
|
+
handler_instance.receive_data(t_data)
|
213
229
|
rescue DisconnectError => sock_error
|
230
|
+
handler_instance.receive_data(sock_error.data) unless (sock_error.data).empty?
|
214
231
|
handler_instance.close_connection
|
215
232
|
end
|
216
233
|
end
|
@@ -275,7 +292,7 @@ module Packet
|
|
275
292
|
end
|
276
293
|
end
|
277
294
|
end
|
278
|
-
|
295
|
+
|
279
296
|
# close the connection with internal specified socket
|
280
297
|
def close_connection(sock = nil)
|
281
298
|
begin
|
@@ -289,28 +306,38 @@ module Packet
|
|
289
306
|
return p_module if(!p_module.is_a?(Class) and !p_module.is_a?(Module))
|
290
307
|
handler =
|
291
308
|
if(p_module and p_module.is_a?(Class))
|
292
|
-
p_module
|
309
|
+
p_module and p_module.send(:include,Connection)
|
293
310
|
else
|
294
|
-
Class.new
|
311
|
+
Class.new { include Connection; include p_module; }
|
295
312
|
end
|
296
313
|
return handler.new
|
297
314
|
end
|
298
315
|
|
299
316
|
def decorate_handler(t_socket,actually_connected,sock_addr,t_module,&block)
|
300
317
|
handler_instance = initialize_handler(t_module)
|
301
|
-
connection_callbacks[:after_connection]
|
318
|
+
after_connection_callbacks = connection_callbacks ? connection_callbacks[:after_connection] : nil
|
319
|
+
after_connection_callbacks && after_connection_callbacks.each { |t_callback| self.send(t_callback,handler_instance,t_socket)}
|
320
|
+
handler_instance.worker = self
|
321
|
+
handler_instance.connection = t_socket
|
322
|
+
handler_instance.reactor = self
|
302
323
|
handler_instance.invoke_init unless handler_instance.initialized
|
303
324
|
unless actually_connected
|
304
|
-
handler_instance.unbind
|
325
|
+
handler_instance.unbind
|
305
326
|
return
|
306
327
|
end
|
307
328
|
handler_instance.signature = binding_str
|
308
|
-
|
309
|
-
|
329
|
+
# FIXME: An Struct is more fashionable, but will have some performance hit, can use a simple hash here
|
330
|
+
# klass = Struct.new(:socket,:instance,:signature,:sock_addr)
|
331
|
+
connection_data = { :socket => t_socket,:instance => handler_instance,:signature => binding_str,:sock_addr => sock_addr }
|
332
|
+
connections[t_socket.fileno] = connection_data
|
333
|
+
# connections[t_socket.fileno] = klass.new(t_socket,handler_instance,handler_instance.signature,sock_addr)
|
334
|
+
|
310
335
|
block.call(handler_instance) if block
|
311
|
-
handler_instance.connection_completed if handler_instance.respond_to?(:connection_completed)
|
336
|
+
handler_instance.connection_completed #if handler_instance.respond_to?(:connection_completed)
|
337
|
+
handler_instance
|
312
338
|
end
|
313
339
|
|
314
340
|
end # end of module#CommonMethods
|
315
341
|
end #end of module#Core
|
316
342
|
end #end of module#Packet
|
343
|
+
|
data/lib/packet/packet_event.rb
CHANGED
data/lib/packet/packet_guid.rb
CHANGED
data/lib/packet/packet_helper.rb
CHANGED
@@ -23,52 +23,24 @@ module Packet
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end # end of method iattr_accessor
|
26
|
-
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@@#{sym}
|
26
|
+
|
27
|
+
def inheritable_attribute *options_args
|
28
|
+
option_hash = options_args.last
|
29
|
+
args = options_args[0..-2]
|
30
|
+
args.each {|attr| instance_variable_set(:"@#{attr}",option_hash[:default] || nil )}
|
31
|
+
metaclass.instance_eval { attr_accessor *args }
|
32
|
+
args.each do |attr|
|
33
|
+
class_eval do
|
34
|
+
define_method(attr) do
|
35
|
+
self.class.send(attr)
|
36
|
+
end
|
37
|
+
define_method("#{attr}=") do |b_value|
|
38
|
+
self.class.send("#{attr}=",b_value)
|
39
|
+
end
|
41
40
|
end
|
42
|
-
EOS
|
43
41
|
end
|
44
42
|
end
|
45
|
-
|
46
|
-
def cattr_writer(*syms)
|
47
|
-
options = syms.last.is_a?(Hash) ? syms.pop : {}
|
48
|
-
syms.flatten.each do |sym|
|
49
|
-
class_eval(<<-EOS, __FILE__, __LINE__)
|
50
|
-
unless defined? @@#{sym}
|
51
|
-
@@#{sym} = nil
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.#{sym}=(obj)
|
55
|
-
@@#{sym} = obj
|
56
|
-
end
|
57
|
-
|
58
|
-
#{"
|
59
|
-
def #{sym}=(obj)
|
60
|
-
@@#{sym} = obj
|
61
|
-
end
|
62
|
-
" unless options[:instance_writer] == false }
|
63
|
-
EOS
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def cattr_accessor(*syms)
|
68
|
-
cattr_reader(*syms)
|
69
|
-
cattr_writer(*syms)
|
70
|
-
end
|
71
|
-
module_function :metaclass,:iattr_accessor, :cattr_writer, :cattr_reader, :cattr_accessor
|
43
|
+
module_function :metaclass,:iattr_accessor,:inheritable_attribute
|
72
44
|
end # end of module ClassHelpers
|
73
45
|
end
|
74
46
|
|
data/lib/packet/packet_master.rb
CHANGED
@@ -6,7 +6,7 @@ module Packet
|
|
6
6
|
attr_accessor :result_hash
|
7
7
|
|
8
8
|
attr_accessor :live_workers
|
9
|
-
after_connection :provide_workers
|
9
|
+
#after_connection :provide_workers
|
10
10
|
|
11
11
|
def self.server_logger= (log_file_name)
|
12
12
|
@@server_logger = log_file_name
|
@@ -30,62 +30,34 @@ module Packet
|
|
30
30
|
@result_hash[worker_key.to_sym] = result
|
31
31
|
end
|
32
32
|
|
33
|
-
def provide_workers(handler_instance,t_sock)
|
34
|
-
class << handler_instance
|
35
|
-
extend Forwardable
|
36
|
-
attr_accessor :workers,:connection,:reactor, :initialized,:signature
|
37
|
-
include NbioHelper
|
38
|
-
include Connection
|
39
|
-
def ask_worker(*args)
|
40
|
-
worker_name = args.shift
|
41
|
-
data_options = *args
|
42
|
-
worker_name_key = gen_worker_key(worker_name,data_options[:job_key])
|
43
|
-
data_options[:client_signature] = connection.fileno
|
44
|
-
reactor.live_workers[worker_name_key].send_request(data_options)
|
45
|
-
end
|
46
|
-
|
47
|
-
def_delegators(:@reactor, :start_server, :connect, :add_periodic_timer, \
|
48
|
-
:add_timer, :cancel_timer,:reconnect, :start_worker,:delete_worker)
|
49
|
-
|
50
|
-
end
|
51
|
-
handler_instance.workers = @live_workers
|
52
|
-
handler_instance.connection = t_sock
|
53
|
-
handler_instance.reactor = self
|
54
|
-
end
|
55
|
-
|
56
|
-
# FIXME: right now, each worker is tied to its connection and this can be problematic
|
57
|
-
# what if a worker wants to return results in a async manner
|
58
33
|
def handle_internal_messages(t_sock)
|
59
34
|
sock_fd = t_sock.fileno
|
60
35
|
worker_instance = @live_workers[sock_fd]
|
61
36
|
begin
|
62
37
|
raw_data = read_data(t_sock)
|
63
|
-
# t_data = Marshal.load(raw_data)
|
64
38
|
worker_instance.receive_data(raw_data) if worker_instance.respond_to?(:receive_data)
|
65
39
|
rescue DisconnectError => sock_error
|
40
|
+
worker_instance.receive_data(sock_error.data) if worker_instance.respond_to?(:receive_data)
|
66
41
|
remove_worker(t_sock)
|
67
42
|
end
|
68
43
|
end
|
69
|
-
|
44
|
+
|
70
45
|
|
71
46
|
def remove_worker(t_sock)
|
72
47
|
@live_workers.delete(t_sock.fileno)
|
73
48
|
read_ios.delete(t_sock)
|
74
49
|
end
|
75
|
-
|
50
|
+
|
76
51
|
def delete_worker(worker_options = {})
|
77
52
|
worker_name = worker_options[:worker]
|
78
|
-
worker_name_key = gen_worker_key(worker_name,worker_options[:
|
53
|
+
worker_name_key = gen_worker_key(worker_name,worker_options[:worker_key])
|
79
54
|
worker_options[:method] = :exit
|
80
55
|
@live_workers[worker_name_key].send_request(worker_options)
|
81
56
|
end
|
82
57
|
|
83
58
|
def load_workers
|
84
|
-
|
85
|
-
|
86
|
-
else
|
87
|
-
worker_root = "#{PACKET_APP}/worker"
|
88
|
-
end
|
59
|
+
worker_root = defined?(WORKER_ROOT) ? WORKER_ROOT : "#{PACKET_APP}/worker"
|
60
|
+
|
89
61
|
t_workers = Dir["#{worker_root}/**/*.rb"]
|
90
62
|
return if t_workers.empty?
|
91
63
|
t_workers.each do |b_worker|
|
@@ -99,7 +71,7 @@ module Packet
|
|
99
71
|
|
100
72
|
def start_worker(worker_options = { })
|
101
73
|
worker_name = worker_options[:worker].to_s
|
102
|
-
worker_name_key = gen_worker_key(worker_name,worker_options[:
|
74
|
+
worker_name_key = gen_worker_key(worker_name,worker_options[:worker_key])
|
103
75
|
return if @live_workers[worker_name_key]
|
104
76
|
worker_options.delete(:worker)
|
105
77
|
begin
|
@@ -107,15 +79,17 @@ module Packet
|
|
107
79
|
worker_klass = Object.const_get(packet_classify(worker_name))
|
108
80
|
fork_and_load(worker_klass,worker_options)
|
109
81
|
rescue LoadError
|
110
|
-
puts "no such worker #{worker_name}"
|
111
|
-
rescue MissingSourceFile
|
112
|
-
puts "no such worker #{worker_name}"
|
82
|
+
puts "no such worker #{worker_name}"
|
113
83
|
return
|
114
84
|
end
|
115
85
|
end
|
116
86
|
|
117
|
-
|
118
|
-
|
87
|
+
def enable_nonblock io
|
88
|
+
f = io.fcntl(Fcntl::F_GETFL,0)
|
89
|
+
io.fcntl(Fcntl::F_SETFL,Fcntl::O_NONBLOCK | f)
|
90
|
+
end
|
91
|
+
|
92
|
+
# method should use worker_key if provided in options hash.
|
119
93
|
def fork_and_load(worker_klass,worker_options = { })
|
120
94
|
t_worker_name = worker_klass.worker_name
|
121
95
|
worker_pimp = worker_klass.worker_proxy.to_s
|
@@ -124,18 +98,20 @@ module Packet
|
|
124
98
|
master_read_end,worker_write_end = UNIXSocket.pair(Socket::SOCK_STREAM)
|
125
99
|
# socket to which master process is going to write
|
126
100
|
worker_read_end,master_write_end = UNIXSocket.pair(Socket::SOCK_STREAM)
|
127
|
-
# worker_read_fd,master_write_fd = UNIXSocket.pair
|
128
101
|
|
129
|
-
|
130
|
-
|
131
|
-
|
102
|
+
option_dump = Marshal.dump(worker_options)
|
103
|
+
option_dump_length = option_dump.length
|
104
|
+
master_write_end.write(option_dump)
|
132
105
|
|
133
|
-
|
134
|
-
|
106
|
+
if(!(pid = fork))
|
107
|
+
[master_write_end,master_read_end].each { |x| x.close }
|
108
|
+
[worker_read_end,worker_write_end].each { |x| enable_nonblock(x) }
|
109
|
+
exec form_cmd_line(worker_read_end.fileno,worker_write_end.fileno,t_worker_name,option_dump_length)
|
135
110
|
end
|
136
111
|
Process.detach(pid)
|
112
|
+
[master_read_end,master_write_end].each { |x| enable_nonblock(x) }
|
137
113
|
|
138
|
-
worker_name_key = gen_worker_key(t_worker_name,worker_options[:
|
114
|
+
worker_name_key = gen_worker_key(t_worker_name,worker_options[:worker_key])
|
139
115
|
|
140
116
|
if worker_pimp && !worker_pimp.empty?
|
141
117
|
require worker_pimp
|
@@ -152,5 +128,12 @@ module Packet
|
|
152
128
|
worker_write_end.close
|
153
129
|
read_ios << master_read_end
|
154
130
|
end # end of fork_and_load method
|
131
|
+
|
132
|
+
def form_cmd_line *args
|
133
|
+
min_string = "packet_worker_runner #{args[0]}:#{args[1]}:#{args[2]}:#{args[3]}"
|
134
|
+
min_string << ":#{WORKER_ROOT}" if defined? WORKER_ROOT
|
135
|
+
min_string << ":#{WORKER_LOAD_ENV}" if defined? WORKER_LOAD_ENV
|
136
|
+
min_string
|
137
|
+
end
|
155
138
|
end # end of Reactor class
|
156
139
|
end # end of Packet module
|
@@ -10,7 +10,7 @@ class Packet::MetaPimp < Packet::Pimp
|
|
10
10
|
@worker_status = nil
|
11
11
|
@worker_result = nil
|
12
12
|
@worker_key = nil
|
13
|
-
@tokenizer = BinParser.new
|
13
|
+
@tokenizer = Packet::BinParser.new
|
14
14
|
end
|
15
15
|
|
16
16
|
# will be invoked whenever there is a response from the worker
|
@@ -44,7 +44,7 @@ class Packet::MetaPimp < Packet::Pimp
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def process_request(data_options = {})
|
47
|
-
if
|
47
|
+
if((requested_worker = data_options[:requested_worker]) && (reactor.live_workers[requested_worker]))
|
48
48
|
reactor.live_workers[requested_worker].send_request(data_options)
|
49
49
|
end
|
50
50
|
end
|
@@ -59,7 +59,7 @@ class Packet::MetaPimp < Packet::Pimp
|
|
59
59
|
end
|
60
60
|
elsif client_signature = data_options[:client_signature]
|
61
61
|
begin
|
62
|
-
reactor.connections[client_signature]
|
62
|
+
reactor.connections[client_signature][:instance].worker_receive(data_options)
|
63
63
|
rescue
|
64
64
|
end
|
65
65
|
end
|
data/lib/packet/packet_nbio.rb
CHANGED
@@ -5,16 +5,16 @@ module Packet
|
|
5
5
|
return word_parts.map { |x| x.capitalize}.join
|
6
6
|
end
|
7
7
|
|
8
|
-
def gen_worker_key(worker_name,
|
9
|
-
return worker_name if
|
10
|
-
return "#{worker_name}_#{
|
8
|
+
def gen_worker_key(worker_name,worker_key = nil)
|
9
|
+
return worker_name if worker_key.nil?
|
10
|
+
return "#{worker_name}_#{worker_key}".to_sym
|
11
11
|
end
|
12
12
|
|
13
13
|
def read_data(t_sock)
|
14
14
|
sock_data = []
|
15
15
|
begin
|
16
|
-
while(t_data = t_sock.
|
17
|
-
raise DisconnectError.new(t_sock,sock_data.join) if t_data.empty?
|
16
|
+
while(t_data = t_sock.read_nonblock((16*1024)-1))
|
17
|
+
#raise DisconnectError.new(t_sock,sock_data.join) if t_data.empty?
|
18
18
|
sock_data << t_data
|
19
19
|
end
|
20
20
|
rescue Errno::EAGAIN
|
@@ -45,22 +45,31 @@ module Packet
|
|
45
45
|
raise DisconnectError.new(p_sock)
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
# write the data in socket buffer and schedule the thing
|
50
50
|
def write_and_schedule sock
|
51
51
|
outbound_data.each_with_index do |t_data,index|
|
52
52
|
leftover = write_once(t_data,sock)
|
53
53
|
if leftover.empty?
|
54
|
-
outbound_data
|
54
|
+
outbound_data[index] = nil
|
55
55
|
else
|
56
56
|
outbound_data[index] = leftover
|
57
|
-
reactor.schedule_write(sock)
|
57
|
+
reactor.schedule_write(sock,self)
|
58
58
|
break
|
59
59
|
end
|
60
60
|
end
|
61
|
+
outbound_data.compact!
|
61
62
|
reactor.cancel_write(sock) if outbound_data.empty?
|
62
63
|
end
|
63
64
|
|
65
|
+
# returns Marshal dump of the specified object
|
66
|
+
def object_dump p_data
|
67
|
+
object_dump = Marshal.dump(p_data)
|
68
|
+
dump_length = object_dump.length.to_s
|
69
|
+
length_str = dump_length.rjust(9,'0')
|
70
|
+
final_data = length_str + object_dump
|
71
|
+
end
|
72
|
+
|
64
73
|
# method dumps the object in a protocol format which can be easily picked by a recursive descent parser
|
65
74
|
def dump_object(p_data,p_sock)
|
66
75
|
object_dump = Marshal.dump(p_data)
|
@@ -68,8 +77,8 @@ module Packet
|
|
68
77
|
length_str = dump_length.rjust(9,'0')
|
69
78
|
final_data = length_str + object_dump
|
70
79
|
outbound_data << final_data
|
71
|
-
begin
|
72
|
-
write_and_schedule(p_sock)
|
80
|
+
begin
|
81
|
+
write_and_schedule(p_sock)
|
73
82
|
rescue DisconnectError => sock
|
74
83
|
close_connection(sock)
|
75
84
|
end
|
data/lib/packet/packet_parser.rb
CHANGED
@@ -1,69 +1,75 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
module Packet
|
2
|
+
class BinParser
|
3
|
+
attr_accessor :data,:numeric_length,:length_string,:remaining
|
4
|
+
attr_accessor :parser_state
|
5
|
+
def initialize
|
6
|
+
@size = 0
|
7
|
+
@data = []
|
8
|
+
@remaining = ""
|
9
|
+
# 0 => reading length
|
10
|
+
# 1 => reading actual data
|
11
|
+
@parser_state = 0
|
12
|
+
@length_string = ""
|
13
|
+
@numeric_length = 0
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
if len_str.length < length_to_read
|
18
|
-
@length_string << len_str
|
19
|
-
return
|
20
|
-
else
|
21
|
-
@length_string << len_str
|
22
|
-
@numeric_length = @length_string.to_i
|
23
|
-
@parser_state = 1
|
24
|
-
if remaining.length < @numeric_length
|
25
|
-
@data << remaining
|
26
|
-
@numeric_length = @numeric_length - remaining.length
|
27
|
-
elsif remaining.length == @numeric_length
|
28
|
-
@data << remaining
|
29
|
-
extracter_block.call(@data.join)
|
30
|
-
@data = []
|
31
|
-
@parser_state = 0
|
32
|
-
@length_string = ""
|
33
|
-
@numeric_length = 0
|
34
|
-
else
|
35
|
-
pack_data,remaining = remaining.unpack("a#{@numeric_length}a*")
|
36
|
-
@data << pack_data
|
37
|
-
extracter_block.call(@data.join)
|
38
|
-
@data = []
|
39
|
-
@parser_state = 0
|
40
|
-
@length_string = ""
|
41
|
-
@numeric_length = 0
|
42
|
-
extract(remaining,&extracter_block)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
elsif @parser_state == 1
|
46
|
-
pack_data,remaining = new_data.unpack("a#{@numeric_length}a*")
|
47
|
-
if pack_data.length < @numeric_length
|
48
|
-
@data << pack_data
|
49
|
-
@numeric_length = @numeric_length - pack_data.length
|
50
|
-
elsif pack_data.length == @numeric_length
|
51
|
-
@data << pack_data
|
52
|
-
extracter_block.call(@data.join)
|
53
|
-
@data = []
|
54
|
-
@parser_state = 0
|
55
|
-
@length_string = ""
|
56
|
-
@numeric_length = 0
|
57
|
-
else
|
58
|
-
@data << pack_data
|
59
|
-
extracter_block.call(@data.join)
|
60
|
-
@data = []
|
61
|
-
@parser_state = 0
|
62
|
-
@length_string = ""
|
63
|
-
@numeric_length = 0
|
64
|
-
extract(remaining,&extracter_block)
|
65
|
-
end
|
16
|
+
def reset
|
17
|
+
@data = []
|
18
|
+
@parser_state = 0
|
19
|
+
@length_string = ""
|
20
|
+
@numeric_length = 0
|
66
21
|
end
|
67
|
-
|
68
|
-
|
22
|
+
|
23
|
+
def extract new_data
|
24
|
+
remaining = new_data
|
25
|
+
|
26
|
+
loop do
|
27
|
+
if @parser_state == 0
|
28
|
+
length_to_read = 9 - @length_string.length
|
29
|
+
len_str,remaining = remaining.unpack("a#{length_to_read}a*")
|
30
|
+
break if len_str !~ /^\d+$/
|
31
|
+
if len_str.length < length_to_read
|
32
|
+
@length_string << len_str
|
33
|
+
break
|
34
|
+
else
|
35
|
+
@length_string << len_str
|
36
|
+
@numeric_length = @length_string.to_i
|
37
|
+
@parser_state = 1
|
38
|
+
if remaining.length < @numeric_length
|
39
|
+
@data << remaining
|
40
|
+
@numeric_length = @numeric_length - remaining.length
|
41
|
+
break
|
42
|
+
elsif remaining.length == @numeric_length
|
43
|
+
@data << remaining
|
44
|
+
yield(@data.join)
|
45
|
+
reset
|
46
|
+
break
|
47
|
+
else
|
48
|
+
pack_data,remaining = remaining.unpack("a#{@numeric_length}a*")
|
49
|
+
@data << pack_data
|
50
|
+
yield(@data.join)
|
51
|
+
reset
|
52
|
+
end
|
53
|
+
end
|
54
|
+
elsif @parser_state == 1
|
55
|
+
pack_data,remaining = remaining.unpack("a#{@numeric_length}a*")
|
56
|
+
if pack_data.length < @numeric_length
|
57
|
+
@data << pack_data
|
58
|
+
@numeric_length = @numeric_length - pack_data.length
|
59
|
+
break
|
60
|
+
elsif pack_data.length == @numeric_length
|
61
|
+
@data << pack_data
|
62
|
+
yield(@data.join)
|
63
|
+
reset
|
64
|
+
break
|
65
|
+
else
|
66
|
+
@data << pack_data
|
67
|
+
yield(@data.join)
|
68
|
+
reset
|
69
|
+
end
|
70
|
+
end # end of beginning if condition
|
71
|
+
end # end of loop do
|
72
|
+
end # end of extract method
|
73
|
+
end # end of BinParser class
|
74
|
+
end # end of packet module
|
69
75
|
|
data/lib/packet/packet_pimp.rb
CHANGED
data/lib/packet/packet_worker.rb
CHANGED
@@ -7,13 +7,13 @@ module Packet
|
|
7
7
|
iattr_accessor :no_auto_load
|
8
8
|
|
9
9
|
attr_accessor :worker_started, :worker_options
|
10
|
-
after_connection :provide_workers
|
11
10
|
|
12
11
|
# method initializes the eventloop for the worker
|
13
12
|
def self.start_worker(messengers = {})
|
14
13
|
# @fd_reader = args.shift if args.length > 2
|
15
14
|
@msg_writer = messengers[:write_end]
|
16
15
|
@msg_reader = messengers[:read_end]
|
16
|
+
|
17
17
|
t_instance = new
|
18
18
|
t_instance.worker_options = messengers[:options]
|
19
19
|
t_instance.worker_init if t_instance.respond_to?(:worker_init)
|
@@ -21,6 +21,13 @@ module Packet
|
|
21
21
|
t_instance
|
22
22
|
end
|
23
23
|
|
24
|
+
# copy the inherited attribute in class thats inheriting this class
|
25
|
+
def self.inherited(subklass)
|
26
|
+
subklass.send(:"connection_callbacks=",connection_callbacks)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.is_worker?; true; end
|
30
|
+
|
24
31
|
def initialize
|
25
32
|
super
|
26
33
|
@read_ios << msg_reader
|
@@ -43,8 +50,13 @@ module Packet
|
|
43
50
|
|
44
51
|
# method handles internal requests from internal sockets
|
45
52
|
def handle_internal_messages(t_sock)
|
46
|
-
|
47
|
-
|
53
|
+
begin
|
54
|
+
t_data = read_data(t_sock)
|
55
|
+
receive_internal_data(t_data)
|
56
|
+
rescue DisconnectError => sock_error
|
57
|
+
# Means, when there is an error from sockets from which we are reading better just terminate
|
58
|
+
terminate_me()
|
59
|
+
end
|
48
60
|
end
|
49
61
|
|
50
62
|
def receive_internal_data data
|
@@ -54,21 +66,6 @@ module Packet
|
|
54
66
|
end
|
55
67
|
end
|
56
68
|
|
57
|
-
# FIXME: this method is being duplicated between packet and worker classes, may be its a
|
58
|
-
# good idea to merge them.
|
59
|
-
def provide_workers(handler_instance,connection)
|
60
|
-
class << handler_instance
|
61
|
-
extend Forwardable
|
62
|
-
attr_accessor :worker, :connection, :reactor, :initialized, :signature
|
63
|
-
include NbioHelper
|
64
|
-
include Connection
|
65
|
-
def_delegators :@reactor, :start_server, :connect, :add_periodic_timer, :add_timer, :cancel_timer,:reconnect
|
66
|
-
end
|
67
|
-
handler_instance.connection = connection
|
68
|
-
handler_instance.worker = self
|
69
|
-
handler_instance.reactor = self
|
70
|
-
end
|
71
|
-
|
72
69
|
def log log_data
|
73
70
|
send_data(:requested_worker => :log_worker,:data => log_data,:type => :request)
|
74
71
|
end
|
@@ -91,3 +88,4 @@ module Packet
|
|
91
88
|
end # end of class#Worker
|
92
89
|
end
|
93
90
|
|
91
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: packet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hemant Kumar
|
@@ -9,14 +9,14 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-07-12 00:00:00 +05:30
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description: Packet, A Pure Ruby library for Event Driven Network Programming.
|
17
17
|
email: mail@gnufied.org
|
18
|
-
executables:
|
19
|
-
|
18
|
+
executables:
|
19
|
+
- packet_worker_runner
|
20
20
|
extensions: []
|
21
21
|
|
22
22
|
extra_rdoc_files:
|
@@ -28,12 +28,10 @@ files:
|
|
28
28
|
- README
|
29
29
|
- Rakefile
|
30
30
|
- TODO
|
31
|
-
- spec/test_double_keyed_hash.rb
|
32
|
-
- spec/spec_helper.rb
|
33
|
-
- spec/test_packet_core.rb
|
34
31
|
- lib/packet
|
35
32
|
- lib/packet/disconnect_error.rb
|
36
33
|
- lib/packet/packet_pimp.rb
|
34
|
+
- lib/packet/packet_invalid_worker.rb
|
37
35
|
- lib/packet/packet_connection.rb
|
38
36
|
- lib/packet/packet_guid.rb
|
39
37
|
- lib/packet/double_keyed_hash.rb
|
@@ -50,7 +48,6 @@ files:
|
|
50
48
|
- lib/packet/packet_event.rb
|
51
49
|
- lib/packet/packet_nbio.rb
|
52
50
|
- lib/packet.rb
|
53
|
-
- lib/packet.rbc
|
54
51
|
- lib/packet_mongrel.rb
|
55
52
|
- examples/concurrent_thread.c
|
56
53
|
- examples/sample_server.rb
|
@@ -59,7 +56,6 @@ files:
|
|
59
56
|
- examples/persistent_print.rb
|
60
57
|
- examples/use_stuff.rb
|
61
58
|
- examples/extconf.h
|
62
|
-
- examples/netbeans.jpg
|
63
59
|
- examples/asteroid.c
|
64
60
|
- examples/extconf.rb
|
65
61
|
has_rdoc: true
|
@@ -84,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
84
80
|
requirements: []
|
85
81
|
|
86
82
|
rubyforge_project:
|
87
|
-
rubygems_version:
|
83
|
+
rubygems_version: 1.2.0
|
88
84
|
signing_key:
|
89
85
|
specification_version: 2
|
90
86
|
summary: Packet, A Pure Ruby library for Event Driven Network Programming.
|
data/examples/netbeans.jpg
DELETED
Binary file
|
data/lib/packet.rbc
DELETED
Binary file
|
data/spec/spec_helper.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__) + "/spec_helper")
|
2
|
-
context "Double Keyed Hash in general" do
|
3
|
-
xspecify "should allow muliple keys while storing the value in hash" do
|
4
|
-
end
|
5
|
-
|
6
|
-
xspecify "should return correct value when either of the keys is used" do
|
7
|
-
end
|
8
|
-
|
9
|
-
xspecify "should return nil if nither of keys match" do
|
10
|
-
end
|
11
|
-
|
12
|
-
xspecify "should allow deletion of value from hash based on either of keys" do
|
13
|
-
end
|
14
|
-
end
|
data/spec/test_packet_core.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__) + "/spec_helper")
|
2
|
-
|
3
|
-
context "Packet Core in general when mixed inside a class" do
|
4
|
-
xspecify "allow the class to act as a reactor" do
|
5
|
-
end
|
6
|
-
|
7
|
-
xspecify "should start a server on specified port" do
|
8
|
-
end
|
9
|
-
|
10
|
-
xspecify "should let clients connect to the server" do
|
11
|
-
end
|
12
|
-
|
13
|
-
xspecify "should be able to connect to external servers" do
|
14
|
-
end
|
15
|
-
|
16
|
-
xspecify "should be able to read data from clients when socket is ready" do
|
17
|
-
end
|
18
|
-
|
19
|
-
xspecify "should be able to write data to clients when socket is ready for write" do
|
20
|
-
end
|
21
|
-
|
22
|
-
xspecify "should invoke receive_data method data is receieved from clients" do
|
23
|
-
end
|
24
|
-
|
25
|
-
xspecify "should invoke post_init when client connects" do
|
26
|
-
end
|
27
|
-
|
28
|
-
xspecify "should invoke unbind when a client disconnects" do
|
29
|
-
end
|
30
|
-
|
31
|
-
xspecify "should invoke connection_completed when connection to external server is connected." do
|
32
|
-
end
|
33
|
-
|
34
|
-
xspecify "should check for ready timers on each iteration" do
|
35
|
-
end
|
36
|
-
|
37
|
-
xspecify "should run proper timer on each iteration." do
|
38
|
-
end
|
39
|
-
end
|