roma 0.8.2
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/LICENSE.rdoc +675 -0
- data/README.rdoc +0 -0
- data/Rakefile +70 -0
- data/bin/mkrecent +7 -0
- data/bin/mkroute +7 -0
- data/bin/recoverlost +8 -0
- data/bin/recoverlost_alist +8 -0
- data/bin/romad +7 -0
- data/bin/sample_watcher +8 -0
- data/bin/sample_watcher2 +8 -0
- data/bin/simple_bench +8 -0
- data/bin/ssroute +7 -0
- data/bin/tribunus +7 -0
- data/lib/roma/async_process.rb +696 -0
- data/lib/roma/command/bg_command_receiver.rb +188 -0
- data/lib/roma/command/mh_command_receiver.rb +117 -0
- data/lib/roma/command/receiver.rb +287 -0
- data/lib/roma/command/rt_command_receiver.rb +147 -0
- data/lib/roma/command/st_command_receiver.rb +564 -0
- data/lib/roma/command/util_command_receiver.rb +67 -0
- data/lib/roma/command/vn_command_receiver.rb +143 -0
- data/lib/roma/command_plugin.rb +11 -0
- data/lib/roma/config.rb +64 -0
- data/lib/roma/event/con_pool.rb +140 -0
- data/lib/roma/event/handler.rb +159 -0
- data/lib/roma/plugin/plugin_alist.rb +1572 -0
- data/lib/roma/plugin/plugin_debug.rb +19 -0
- data/lib/roma/plugin/plugin_test.rb +14 -0
- data/lib/roma/romad.rb +582 -0
- data/lib/roma/routing/cb_rttable.rb +326 -0
- data/lib/roma/routing/merkle_tree.rb +54 -0
- data/lib/roma/routing/rttable.rb +148 -0
- data/lib/roma/stats.rb +112 -0
- data/lib/roma/storage/basic_storage.rb +510 -0
- data/lib/roma/storage/dbm_storage.rb +80 -0
- data/lib/roma/storage/dummy_storage.rb +44 -0
- data/lib/roma/storage/rh_storage.rb +35 -0
- data/lib/roma/storage/sqlite3_storage.rb +73 -0
- data/lib/roma/storage/tc_storage.rb +133 -0
- data/lib/roma/tools/mkrecent.rb +138 -0
- data/lib/roma/tools/mkroute.rb +52 -0
- data/lib/roma/tools/recoverlost.rb +9 -0
- data/lib/roma/tools/recoverlost_alist.rb +9 -0
- data/lib/roma/tools/recoverlost_lib.rb +217 -0
- data/lib/roma/tools/sample_watcher.rb +38 -0
- data/lib/roma/tools/sample_watcher2.rb +38 -0
- data/lib/roma/tools/simple_bench.rb +57 -0
- data/lib/roma/tools/ssroute.rb +23 -0
- data/lib/roma/tools/tribunus.rb +299 -0
- data/lib/roma/version.rb +4 -0
- data/lib/roma/write_behind.rb +179 -0
- data/test/rcirb.rb +16 -0
- data/test/roma-test-utils.rb +65 -0
- data/test/run-test.rb +16 -0
- data/test/t_cpdata.rb +277 -0
- data/test/t_listplugin.rb +592 -0
- data/test/t_rclient.rb +318 -0
- data/test/t_routing_data.rb +100 -0
- data/test/t_storage.rb +644 -0
- data/test/t_writebehind.rb +200 -0
- metadata +134 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'roma/messaging/con_pool'
|
2
|
+
|
3
|
+
module Roma
|
4
|
+
module Command
|
5
|
+
|
6
|
+
module UtilCommandReceiver
|
7
|
+
|
8
|
+
def send_cmd(nid, cmd)
|
9
|
+
con = get_connection(nid)
|
10
|
+
con.send(cmd)
|
11
|
+
res = con.gets
|
12
|
+
if res
|
13
|
+
res.chomp!
|
14
|
+
@rttable.proc_succeed(nid)
|
15
|
+
return_connection(nid, con)
|
16
|
+
else
|
17
|
+
@rttable.proc_failed(nid)
|
18
|
+
end
|
19
|
+
res
|
20
|
+
rescue => e
|
21
|
+
@rttable.proc_failed(nid)
|
22
|
+
@log.error("#{e}\n#{$@}")
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def broadcast_cmd(cmd)
|
27
|
+
res={}
|
28
|
+
@rttable.nodes.each{|nid|
|
29
|
+
res[nid] = send_cmd(nid,cmd) if nid != @stats.ap_str
|
30
|
+
}
|
31
|
+
res
|
32
|
+
end
|
33
|
+
|
34
|
+
def async_send_cmd(nid, cmd)
|
35
|
+
con = Roma::Messaging::ConPool.instance.get_connection(nid)
|
36
|
+
con.write(cmd)
|
37
|
+
res = con.gets
|
38
|
+
Roma::Messaging::ConPool.instance.return_connection(nid, con)
|
39
|
+
if res
|
40
|
+
res.chomp!
|
41
|
+
@rttable.proc_succeed(nid)
|
42
|
+
else
|
43
|
+
@rttable.proc_failed(nid)
|
44
|
+
end
|
45
|
+
res
|
46
|
+
rescue => e
|
47
|
+
@rttable.proc_failed(nid)
|
48
|
+
@log.error("#{e}\n#{$@}")
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def async_broadcast_cmd(cmd,without_nids=nil)
|
53
|
+
without_nids=[@stats.ap_str] unless without_nids
|
54
|
+
res = {}
|
55
|
+
@rttable.nodes.each{ |nid|
|
56
|
+
res[nid] = async_send_cmd(nid,cmd) unless without_nids.include?(nid)
|
57
|
+
}
|
58
|
+
res
|
59
|
+
rescue => e
|
60
|
+
@log.error("#{e}\n#{$@}")
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
|
64
|
+
end # module UtilCommandReceiver
|
65
|
+
|
66
|
+
end # module Command
|
67
|
+
end # module Roma
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'roma/messaging/con_pool'
|
2
|
+
require 'roma/async_process'
|
3
|
+
|
4
|
+
module Roma
|
5
|
+
module Command
|
6
|
+
|
7
|
+
module VnodeCommandReceiver
|
8
|
+
|
9
|
+
# pushv <hash-name> <vnode-id>
|
10
|
+
# src dst
|
11
|
+
# | ['pushv' <hname> <vn>\r\n]->|
|
12
|
+
# |<-['READY'\r\n] |
|
13
|
+
# | [<length>\r\n]->|
|
14
|
+
# | [<dump>\r\n]->|
|
15
|
+
# | ['END'\r\n]->|
|
16
|
+
# |<-['STORED'\r\n] |
|
17
|
+
def ev_pushv(s)
|
18
|
+
send_data("READY\r\n")
|
19
|
+
len = gets
|
20
|
+
res = em_receive_dump(s[1], len.to_i)
|
21
|
+
if res == true
|
22
|
+
send_data("STORED\r\n")
|
23
|
+
else
|
24
|
+
send_data("SERVER_ERROR #{res}\r\n")
|
25
|
+
end
|
26
|
+
rescue => e
|
27
|
+
@log.error("#{e}\n#{$@}")
|
28
|
+
end
|
29
|
+
|
30
|
+
# spushv <hash-name> <vnode-id>
|
31
|
+
# src dst
|
32
|
+
# | ['spushv' <hname> <vn>\r\n]->|
|
33
|
+
# |<-['READY'\r\n] |
|
34
|
+
# | [<dumpdata>]->|
|
35
|
+
# | : |
|
36
|
+
# | : |
|
37
|
+
# | [<end of dump>]->|
|
38
|
+
# |<-['STORED'\r\n] |
|
39
|
+
def ev_spushv(s)
|
40
|
+
send_data("READY\r\n")
|
41
|
+
@stats.run_receive_a_vnode = true
|
42
|
+
count = rcount = 0
|
43
|
+
@log.debug("#{__method__}:#{s.inspect} received.")
|
44
|
+
loop {
|
45
|
+
context_bin = read_bytes(20, 100)
|
46
|
+
vn, last, clk, expt, klen = context_bin.unpack('NNNNN')
|
47
|
+
break if klen == 0 # end of dump ?
|
48
|
+
k = read_bytes(klen)
|
49
|
+
vlen_bin = read_bytes(4, 100)
|
50
|
+
vlen, = vlen_bin.unpack('N')
|
51
|
+
if vlen != 0
|
52
|
+
v = read_bytes(vlen, 100)
|
53
|
+
|
54
|
+
if @storages[s[1]].load_stream_dump(vn, last, clk, expt, k, v)
|
55
|
+
count += 1
|
56
|
+
# @log.debug("#{__method__}:[#{vn} #{last} #{clk} #{expt} #{k}] was stored.")
|
57
|
+
else
|
58
|
+
rcount += 1
|
59
|
+
# @log.warn("#{__method__}:[#{vn} #{last} #{clk} #{expt} #{k}] was rejected.")
|
60
|
+
end
|
61
|
+
else
|
62
|
+
if @storages[s[1]].load_stream_dump(vn, last, clk, expt, k, nil)
|
63
|
+
# @log.debug("#{__method__}:[#{vn} #{last} #{clk} #{expt} #{k}] was stored.")
|
64
|
+
count += 1
|
65
|
+
else
|
66
|
+
rcount += 1
|
67
|
+
# @log.warn("#{__method__}:[#{vn} #{last} #{clk} #{expt} #{k}] was rejected.")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
}
|
71
|
+
send_data("STORED\r\n")
|
72
|
+
@log.debug("#{__method__}:#{s[2]} #{count} keys loaded. #{rcount} keys rejected.")
|
73
|
+
rescue => e
|
74
|
+
@log.error("#{e}\n#{$@}")
|
75
|
+
ensure
|
76
|
+
@stats.run_receive_a_vnode = false
|
77
|
+
end
|
78
|
+
|
79
|
+
# reqpushv <vnode-id> <node-id> <is primary?>
|
80
|
+
# src dst
|
81
|
+
# |<-['reqpushv <vn> <nid> <p?>\r\n'] |
|
82
|
+
# | ['PUSHED'\r\n]->|
|
83
|
+
def ev_reqpushv(s)
|
84
|
+
if s.length!=4
|
85
|
+
send_data("CLIENT_ERROR usage:reqpushv vnode-id node-id primary-flag(true/false)\r\n")
|
86
|
+
return
|
87
|
+
end
|
88
|
+
|
89
|
+
if @stats.run_iterate_storage == true
|
90
|
+
@log.warn("reqpushv rejected:#{s}")
|
91
|
+
send_data("REJECTED\r\n")
|
92
|
+
return
|
93
|
+
end
|
94
|
+
|
95
|
+
Roma::AsyncProcess::queue.push(Roma::AsyncMessage.new('reqpushv',[s[1],s[2],s[3]]))
|
96
|
+
send_data("PUSHED\r\n")
|
97
|
+
rescue =>e
|
98
|
+
@log.error("#{e}\n#{$@}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def req_push_a_vnode(vn, src_nid, is_primary)
|
102
|
+
con = Roma::Messaging::ConPool.instance.get_connection(src_nid)
|
103
|
+
con.write("reqpushv #{vn} #{@nid} #{is_primary}\r\n")
|
104
|
+
res = con.gets # receive 'PUSHED\r\n' | 'REJECTED\r\n'
|
105
|
+
Roma::Messaging::ConPool.instance.return_connection(src_nid,con)
|
106
|
+
# waiting for pushv
|
107
|
+
count = 0
|
108
|
+
while @rttable.search_nodes(vn).include?(@nid)==false && count < 300
|
109
|
+
sleep 0.1
|
110
|
+
count += 1
|
111
|
+
end
|
112
|
+
rescue =>e
|
113
|
+
@log.error("#{e}\n#{$@}")
|
114
|
+
@rttable.proc_failed(src_nid)
|
115
|
+
false
|
116
|
+
end
|
117
|
+
|
118
|
+
def em_receive_dump(hname, len)
|
119
|
+
dmp = read_bytes(len)
|
120
|
+
read_bytes(2)
|
121
|
+
if gets == "END\r\n"
|
122
|
+
if @storages.key?(hname)
|
123
|
+
n = @storages[hname].load(dmp)
|
124
|
+
@log.debug("#{dmp.length} bytes received.(#{n} keys loaded.)")
|
125
|
+
return true
|
126
|
+
else
|
127
|
+
@log.error("receive_dump:@storages[#{hname}] dose not found.")
|
128
|
+
return "@storages[#{hname}] dose not found."
|
129
|
+
end
|
130
|
+
else
|
131
|
+
@log.error("receive_dump:END was not able to be received.")
|
132
|
+
return "END was not able to be received."
|
133
|
+
end
|
134
|
+
rescue =>e
|
135
|
+
@log.error("#{e}\n#{$@}")
|
136
|
+
"#{e}"
|
137
|
+
end
|
138
|
+
private :em_receive_dump
|
139
|
+
|
140
|
+
end # module VnodeCommandReceiver
|
141
|
+
|
142
|
+
end # module Command
|
143
|
+
end # module Roma
|
data/lib/roma/config.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'roma/routing/rttable'
|
2
|
+
require 'roma/routing/cb_rttable'
|
3
|
+
require 'roma/storage/rh_storage'
|
4
|
+
|
5
|
+
module Roma
|
6
|
+
|
7
|
+
module Config
|
8
|
+
DEFAULT_PORT = 12000
|
9
|
+
DEFAULT_NAME = 'ROMA'
|
10
|
+
|
11
|
+
# :no_action | :auto_assign | :shutdown
|
12
|
+
DEFAULT_LOST_ACTION = :auto_assign
|
13
|
+
|
14
|
+
# log setting
|
15
|
+
LOG_SHIFT_AGE = 10
|
16
|
+
LOG_SHIFT_SIZE = 1024 * 1024 * 10
|
17
|
+
LOG_PATH = '.'
|
18
|
+
# :debug | :info | :warn | :error
|
19
|
+
LOG_LEVEL = :debug
|
20
|
+
|
21
|
+
# routing setting
|
22
|
+
RTTABLE_PATH = '.'
|
23
|
+
|
24
|
+
# storage setting
|
25
|
+
STORAGE_CLASS = Roma::Storage::RubyHashStorage
|
26
|
+
STORAGE_DIVNUM = 10
|
27
|
+
STORAGE_PATH = '.'
|
28
|
+
STORAGE_DUMP_PATH = '/tmp'
|
29
|
+
STORAGE_OPTION = ''
|
30
|
+
|
31
|
+
# 5 days ago
|
32
|
+
STORAGE_DELMARK_EXPTIME = 60 * 60 * 24 * 5
|
33
|
+
|
34
|
+
# data copy setting
|
35
|
+
DATACOPY_STREAM_COPY_WAIT_PARAM = 0.0001
|
36
|
+
|
37
|
+
# plugin setting
|
38
|
+
PLUGIN_FILES = []
|
39
|
+
|
40
|
+
# write-behind setting
|
41
|
+
WRITEBEHIND_PATH = './wb'
|
42
|
+
WRITEBEHIND_SHIFT_SIZE = 1024 * 1024 * 10
|
43
|
+
|
44
|
+
# redundant setting
|
45
|
+
REDUNDANT_ZREDUNDANT_SIZE = 0
|
46
|
+
|
47
|
+
def self.get_stat
|
48
|
+
ret = {}
|
49
|
+
ret['config.DEFAULT_LOST_ACTION'] = DEFAULT_LOST_ACTION
|
50
|
+
ret['config.LOG_SHIFT_AGE'] = LOG_SHIFT_AGE
|
51
|
+
ret['config.LOG_SHIFT_SIZE'] = LOG_SHIFT_SIZE
|
52
|
+
ret['config.LOG_PATH'] = File.expand_path(LOG_PATH)
|
53
|
+
ret['config.RTTABLE_PATH'] = File.expand_path(RTTABLE_PATH)
|
54
|
+
ret['config.STORAGE_DELMARK_EXPTIME'] = STORAGE_DELMARK_EXPTIME
|
55
|
+
ret['config.DATACOPY_STREAM_COPY_WAIT_PARAM'] = DATACOPY_STREAM_COPY_WAIT_PARAM
|
56
|
+
ret['config.PLUGIN_FILES'] = PLUGIN_FILES.inspect
|
57
|
+
ret['config.WRITEBEHIND_PATH'] = File.expand_path(WRITEBEHIND_PATH)
|
58
|
+
ret['config.WRITEBEHIND_SHIFT_SIZE'] = WRITEBEHIND_SHIFT_SIZE
|
59
|
+
ret
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#
|
2
|
+
# File: con_pool.rb
|
3
|
+
#
|
4
|
+
require 'singleton'
|
5
|
+
require 'eventmachine'
|
6
|
+
require 'roma/logging/rlogger'
|
7
|
+
|
8
|
+
module Roma
|
9
|
+
module Event
|
10
|
+
module EMConnection
|
11
|
+
attr_writer :fiber
|
12
|
+
attr_reader :connected
|
13
|
+
attr_accessor :ap
|
14
|
+
|
15
|
+
def post_init
|
16
|
+
@rbuf = ''
|
17
|
+
@connected = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def receive_data(data)
|
21
|
+
@rbuf << data
|
22
|
+
@fiber.resume
|
23
|
+
rescue =>e
|
24
|
+
Roma::Logging::RLogger.instance.error("#{__FILE__}:#{__LINE__}:#{e.inspect} #{$@}")
|
25
|
+
end
|
26
|
+
|
27
|
+
def unbind
|
28
|
+
@connected = nil
|
29
|
+
@fiber.resume
|
30
|
+
rescue FiberError
|
31
|
+
rescue =>e
|
32
|
+
Roma::Logging::RLogger.instance.warn("#{__FILE__}:#{__LINE__}:#{e.inspect} #{$@}")
|
33
|
+
end
|
34
|
+
|
35
|
+
def send(data)
|
36
|
+
send_data(data)
|
37
|
+
end
|
38
|
+
|
39
|
+
def pop(size)
|
40
|
+
if @rbuf.size >= size
|
41
|
+
r = @rbuf[0..size-1]
|
42
|
+
@rbuf = @rbuf[size..-1]
|
43
|
+
r
|
44
|
+
else
|
45
|
+
nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def read_bytes(size)
|
50
|
+
while(@connected) do
|
51
|
+
d = pop(size)
|
52
|
+
if d
|
53
|
+
return d
|
54
|
+
else
|
55
|
+
remain = size - @rbuf.size
|
56
|
+
Fiber.yield(remain)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def gets
|
63
|
+
while(@connected) do
|
64
|
+
if idx = @rbuf.index("\n")
|
65
|
+
return pop(idx+1)
|
66
|
+
else
|
67
|
+
Fiber.yield(@rbuf.size)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
|
73
|
+
end # module EMConnection
|
74
|
+
|
75
|
+
class EMConPool
|
76
|
+
include Singleton
|
77
|
+
attr :pool
|
78
|
+
attr_accessor :maxlength
|
79
|
+
|
80
|
+
def initialize
|
81
|
+
@pool = {}
|
82
|
+
@maxlength = 10
|
83
|
+
@lock = Mutex.new
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_connection(ap)
|
87
|
+
ret = @pool[ap].shift if @pool.key?(ap) && @pool[ap].length > 0
|
88
|
+
ret = create_connection(ap) if ret == nil || ret.connected != true
|
89
|
+
ret
|
90
|
+
end
|
91
|
+
|
92
|
+
def return_connection(ap, con)
|
93
|
+
return if con.connected == false
|
94
|
+
if @pool.key?(ap) && @pool[ap].length > 0
|
95
|
+
if @pool[ap].length > @maxlength
|
96
|
+
con.close_connection
|
97
|
+
else
|
98
|
+
@pool[ap] << con
|
99
|
+
end
|
100
|
+
else
|
101
|
+
@pool[ap] = [con]
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def create_connection(ap)
|
106
|
+
addr,port = ap.split(/[:_]/)
|
107
|
+
con = EventMachine::connect(addr, port, Roma::Event::EMConnection)
|
108
|
+
con.ap = ap
|
109
|
+
con
|
110
|
+
end
|
111
|
+
|
112
|
+
def close_all
|
113
|
+
@pool.each_key{|ap| close_at(ap) }
|
114
|
+
end
|
115
|
+
|
116
|
+
def close_same_host(ap)
|
117
|
+
host,port = ap.split(/[:_]/)
|
118
|
+
@pool.each_key{|eap|
|
119
|
+
close_at(eap) if eap.split(/[:_]/)[0] == host
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def close_at(ap)
|
124
|
+
return unless @pool.key?(ap)
|
125
|
+
@lock.synchronize {
|
126
|
+
while(@pool[ap].length > 0)
|
127
|
+
begin
|
128
|
+
@pool[ap].shift.close_connection
|
129
|
+
rescue =>e
|
130
|
+
Roma::Logging::RLogger.instance.error("#{__FILE__}:#{__LINE__}:#{e.inspect}")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
@pool.delete(ap)
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
end # class EMConPool
|
138
|
+
|
139
|
+
end # module Event
|
140
|
+
end # module Roma
|
@@ -0,0 +1,159 @@
|
|
1
|
+
#
|
2
|
+
# File: handler.rb
|
3
|
+
#
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'roma/event/con_pool'
|
6
|
+
require 'roma/logging/rlogger'
|
7
|
+
require 'socket'
|
8
|
+
|
9
|
+
module Roma
|
10
|
+
module Event
|
11
|
+
|
12
|
+
class Handler < EventMachine::Connection
|
13
|
+
@@ev_list={}
|
14
|
+
|
15
|
+
attr :stop_event_loop
|
16
|
+
attr :connected
|
17
|
+
attr :fiber
|
18
|
+
attr :rbuf
|
19
|
+
|
20
|
+
attr :storages
|
21
|
+
attr :rttable
|
22
|
+
attr_accessor :timeout
|
23
|
+
attr_reader :lastcmd
|
24
|
+
|
25
|
+
def initialize(storages, rttable)
|
26
|
+
@rbuf=''
|
27
|
+
unless has_event?
|
28
|
+
public_methods.each{|m|
|
29
|
+
if m.to_s.start_with?('ev_')
|
30
|
+
add_event(m.to_s[3..-1],m)
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
@storages = storages
|
36
|
+
@rttable = rttable
|
37
|
+
@timeout = 10
|
38
|
+
@log = Roma::Logging::RLogger.instance
|
39
|
+
end
|
40
|
+
|
41
|
+
def post_init
|
42
|
+
@addr = Socket.unpack_sockaddr_in(get_peername)
|
43
|
+
@log.info("Connected from #{@addr[1]}:#{@addr[0]}")
|
44
|
+
@connected = true
|
45
|
+
@fiber = Fiber.new { dispatcher }
|
46
|
+
end
|
47
|
+
|
48
|
+
def receive_data(data)
|
49
|
+
@rbuf << data
|
50
|
+
@fiber.resume
|
51
|
+
rescue =>e
|
52
|
+
@log.error("#{__FILE__}:#{__LINE__}:#{@addr[1]}:#{@addr[0]} #{e.inspect} #{$@}")
|
53
|
+
end
|
54
|
+
|
55
|
+
def unbind
|
56
|
+
@connected=false
|
57
|
+
@fiber.resume
|
58
|
+
EventMachine::stop_event_loop if @stop_event_loop
|
59
|
+
@log.info("Disconnected from #{@addr[1]}:#{@addr[0]}")
|
60
|
+
rescue =>e
|
61
|
+
@log.warn("#{__FILE__}:#{__LINE__}:#{@addr[1]}:#{@addr[0]} #{e.inspect} #{$@}")
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def has_event?
|
67
|
+
@@ev_list.length!=0
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_event(c,m)
|
71
|
+
@@ev_list[c]=m
|
72
|
+
end
|
73
|
+
|
74
|
+
def exit
|
75
|
+
EventMachine::stop_event_loop
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def get_connection(ap)
|
81
|
+
con=Roma::Event::EMConPool::instance.get_connection(ap)
|
82
|
+
con.fiber=@fiber
|
83
|
+
con
|
84
|
+
end
|
85
|
+
|
86
|
+
def return_connection(ap,con)
|
87
|
+
Roma::Event::EMConPool.instance.return_connection(ap,con)
|
88
|
+
end
|
89
|
+
|
90
|
+
def dispatcher
|
91
|
+
while(@connected) do
|
92
|
+
next unless s=gets
|
93
|
+
s=s.chomp.split(/ /)
|
94
|
+
if s[0] && @@ev_list.key?(s[0].downcase)
|
95
|
+
send(@@ev_list[s[0].downcase],s)
|
96
|
+
@lastcmd=s
|
97
|
+
elsif s.length==0
|
98
|
+
next
|
99
|
+
elsif s[0]=='!!'
|
100
|
+
send(@@ev_list[@lastcmd[0].downcase],@lastcmd)
|
101
|
+
else
|
102
|
+
@log.warn("command error:#{s}")
|
103
|
+
send_data("ERROR\r\n")
|
104
|
+
close_connection_after_writing
|
105
|
+
end
|
106
|
+
end
|
107
|
+
rescue =>e
|
108
|
+
@log.warn("#{__FILE__}:#{__LINE__}:#{@addr[1]}:#{@addr[0]} #{e} #{$@}")
|
109
|
+
close_connection
|
110
|
+
end
|
111
|
+
|
112
|
+
def pop(size)
|
113
|
+
if @rbuf.size >= size
|
114
|
+
r = @rbuf[0..size-1]
|
115
|
+
@rbuf = @rbuf[size..-1]
|
116
|
+
r
|
117
|
+
else
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def read_bytes(size, mult = 1)
|
123
|
+
t=Time.now.to_i
|
124
|
+
while(@connected) do
|
125
|
+
d = pop(size)
|
126
|
+
if d
|
127
|
+
return d
|
128
|
+
else
|
129
|
+
remain = size - @rbuf.size
|
130
|
+
Fiber.yield(remain)
|
131
|
+
if Time.now.to_i - t > @timeout * mult
|
132
|
+
@log.warn("#{__FILE__}:#{__LINE__}:#{@addr[1]}:#{@addr[0]} read_bytes time out");
|
133
|
+
close_connection
|
134
|
+
return nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
|
141
|
+
def gets
|
142
|
+
while(@connected) do
|
143
|
+
if idx=@rbuf.index("\n")
|
144
|
+
return pop(idx+1)
|
145
|
+
else
|
146
|
+
Fiber.yield(@rbuf.size)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
|
152
|
+
def detach_socket
|
153
|
+
@connected = false
|
154
|
+
Socket::for_fd(detach)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|