bayserver-core 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +7 -0
  2. data/lib/baykit/bayserver/agent/accept_handler.rb +97 -0
  3. data/lib/baykit/bayserver/agent/channel_listener.rb +35 -0
  4. data/lib/baykit/bayserver/agent/command_receiver.rb +75 -0
  5. data/lib/baykit/bayserver/agent/grand_agent.rb +319 -0
  6. data/lib/baykit/bayserver/agent/grand_agent_monitor.rb +217 -0
  7. data/lib/baykit/bayserver/agent/next_socket_action.rb +14 -0
  8. data/lib/baykit/bayserver/agent/non_blocking_handler.rb +433 -0
  9. data/lib/baykit/bayserver/agent/package.rb +3 -0
  10. data/lib/baykit/bayserver/agent/signal/signal_agent.rb +165 -0
  11. data/lib/baykit/bayserver/agent/signal/signal_proxy.rb +18 -0
  12. data/lib/baykit/bayserver/agent/signal/signal_sender.rb +99 -0
  13. data/lib/baykit/bayserver/agent/spin_handler.rb +140 -0
  14. data/lib/baykit/bayserver/agent/transporter/data_listener.rb +38 -0
  15. data/lib/baykit/bayserver/agent/transporter/package.rb +3 -0
  16. data/lib/baykit/bayserver/agent/transporter/plain_transporter.rb +55 -0
  17. data/lib/baykit/bayserver/agent/transporter/secure_transporter.rb +81 -0
  18. data/lib/baykit/bayserver/agent/transporter/spin_read_transporter.rb +111 -0
  19. data/lib/baykit/bayserver/agent/transporter/spin_write_transporter.rb +125 -0
  20. data/lib/baykit/bayserver/agent/transporter/transporter.rb +466 -0
  21. data/lib/baykit/bayserver/agent/upgrade_exception.rb +11 -0
  22. data/lib/baykit/bayserver/bay_dockers.rb +60 -0
  23. data/lib/baykit/bayserver/bay_exception.rb +12 -0
  24. data/lib/baykit/bayserver/bay_log.rb +148 -0
  25. data/lib/baykit/bayserver/bay_message.rb +20 -0
  26. data/lib/baykit/bayserver/bayserver.rb +529 -0
  27. data/lib/baykit/bayserver/bcf/bcf_document.rb +44 -0
  28. data/lib/baykit/bayserver/bcf/bcf_element.rb +30 -0
  29. data/lib/baykit/bayserver/bcf/bcf_key_val.rb +19 -0
  30. data/lib/baykit/bayserver/bcf/bcf_object.rb +15 -0
  31. data/lib/baykit/bayserver/bcf/bcf_parser.rb +180 -0
  32. data/lib/baykit/bayserver/bcf/package.rb +6 -0
  33. data/lib/baykit/bayserver/bcf/parse_exception.rb +15 -0
  34. data/lib/baykit/bayserver/config_exception.rb +25 -0
  35. data/lib/baykit/bayserver/constants.rb +8 -0
  36. data/lib/baykit/bayserver/docker/base/club_base.rb +117 -0
  37. data/lib/baykit/bayserver/docker/base/docker_base.rb +66 -0
  38. data/lib/baykit/bayserver/docker/base/inbound_data_listener.rb +89 -0
  39. data/lib/baykit/bayserver/docker/base/inbound_handler.rb +42 -0
  40. data/lib/baykit/bayserver/docker/base/inbound_ship.rb +341 -0
  41. data/lib/baykit/bayserver/docker/base/inbound_ship_store.rb +65 -0
  42. data/lib/baykit/bayserver/docker/base/port_base.rb +228 -0
  43. data/lib/baykit/bayserver/docker/base/reroute_base.rb +28 -0
  44. data/lib/baykit/bayserver/docker/built_in/built_in_city_docker.rb +303 -0
  45. data/lib/baykit/bayserver/docker/built_in/built_in_harbor_docker.rb +226 -0
  46. data/lib/baykit/bayserver/docker/built_in/built_in_log_docker.rb +302 -0
  47. data/lib/baykit/bayserver/docker/built_in/built_in_permission_docker.rb +242 -0
  48. data/lib/baykit/bayserver/docker/built_in/built_in_secure_docker.rb +157 -0
  49. data/lib/baykit/bayserver/docker/built_in/built_in_town_docker.rb +117 -0
  50. data/lib/baykit/bayserver/docker/built_in/built_in_trouble_docker.rb +57 -0
  51. data/lib/baykit/bayserver/docker/built_in/log_boat.rb +71 -0
  52. data/lib/baykit/bayserver/docker/built_in/log_item.rb +18 -0
  53. data/lib/baykit/bayserver/docker/built_in/log_item_factory.rb +18 -0
  54. data/lib/baykit/bayserver/docker/built_in/log_items.rb +287 -0
  55. data/lib/baykit/bayserver/docker/built_in/write_file_taxi.rb +101 -0
  56. data/lib/baykit/bayserver/docker/city.rb +22 -0
  57. data/lib/baykit/bayserver/docker/club.rb +45 -0
  58. data/lib/baykit/bayserver/docker/docker.rb +8 -0
  59. data/lib/baykit/bayserver/docker/harbor.rb +34 -0
  60. data/lib/baykit/bayserver/docker/log.rb +17 -0
  61. data/lib/baykit/bayserver/docker/package.rb +12 -0
  62. data/lib/baykit/bayserver/docker/permission.rb +18 -0
  63. data/lib/baykit/bayserver/docker/port.rb +39 -0
  64. data/lib/baykit/bayserver/docker/reroute.rb +17 -0
  65. data/lib/baykit/bayserver/docker/secure.rb +22 -0
  66. data/lib/baykit/bayserver/docker/send_file/directory_train.rb +123 -0
  67. data/lib/baykit/bayserver/docker/send_file/file_content_handler.rb +43 -0
  68. data/lib/baykit/bayserver/docker/send_file/send_file_docker.rb +71 -0
  69. data/lib/baykit/bayserver/docker/town.rb +30 -0
  70. data/lib/baykit/bayserver/docker/trouble.rb +17 -0
  71. data/lib/baykit/bayserver/docker/warp/package.rb +4 -0
  72. data/lib/baykit/bayserver/docker/warp/warp_data.rb +84 -0
  73. data/lib/baykit/bayserver/docker/warp/warp_data_listener.rb +112 -0
  74. data/lib/baykit/bayserver/docker/warp/warp_docker.rb +273 -0
  75. data/lib/baykit/bayserver/docker/warp/warp_handler.rb +38 -0
  76. data/lib/baykit/bayserver/docker/warp/warp_ship.rb +166 -0
  77. data/lib/baykit/bayserver/docker/warp/warp_ship_store.rb +111 -0
  78. data/lib/baykit/bayserver/http_exception.rb +33 -0
  79. data/lib/baykit/bayserver/mem_usage.rb +104 -0
  80. data/lib/baykit/bayserver/protocol/command.rb +21 -0
  81. data/lib/baykit/bayserver/protocol/command_handler.rb +9 -0
  82. data/lib/baykit/bayserver/protocol/command_packer.rb +49 -0
  83. data/lib/baykit/bayserver/protocol/command_unpacker.rb +13 -0
  84. data/lib/baykit/bayserver/protocol/package.rb +15 -0
  85. data/lib/baykit/bayserver/protocol/packet.rb +63 -0
  86. data/lib/baykit/bayserver/protocol/packet_factory.rb +13 -0
  87. data/lib/baykit/bayserver/protocol/packet_packer.rb +30 -0
  88. data/lib/baykit/bayserver/protocol/packet_part_accessor.rb +122 -0
  89. data/lib/baykit/bayserver/protocol/packet_store.rb +139 -0
  90. data/lib/baykit/bayserver/protocol/packet_unpacker.rb +17 -0
  91. data/lib/baykit/bayserver/protocol/protocol_exception.rb +17 -0
  92. data/lib/baykit/bayserver/protocol/protocol_handler.rb +64 -0
  93. data/lib/baykit/bayserver/protocol/protocol_handler_factory.rb +14 -0
  94. data/lib/baykit/bayserver/protocol/protocol_handler_store.rb +109 -0
  95. data/lib/baykit/bayserver/sink.rb +22 -0
  96. data/lib/baykit/bayserver/taxi/taxi.rb +38 -0
  97. data/lib/baykit/bayserver/taxi/taxi_runner.rb +31 -0
  98. data/lib/baykit/bayserver/tours/content_consume_listener.rb +20 -0
  99. data/lib/baykit/bayserver/tours/package.rb +4 -0
  100. data/lib/baykit/bayserver/tours/read_file_taxi.rb +102 -0
  101. data/lib/baykit/bayserver/tours/req_content_handler.rb +37 -0
  102. data/lib/baykit/bayserver/tours/send_file_train.rb +65 -0
  103. data/lib/baykit/bayserver/tours/send_file_yacht.rb +93 -0
  104. data/lib/baykit/bayserver/tours/tour.rb +195 -0
  105. data/lib/baykit/bayserver/tours/tour_req.rb +251 -0
  106. data/lib/baykit/bayserver/tours/tour_res.rb +400 -0
  107. data/lib/baykit/bayserver/tours/tour_store.rb +121 -0
  108. data/lib/baykit/bayserver/train/train.rb +54 -0
  109. data/lib/baykit/bayserver/train/train_runner.rb +32 -0
  110. data/lib/baykit/bayserver/util/byte_array.rb +54 -0
  111. data/lib/baykit/bayserver/util/byte_buffer.rb +13 -0
  112. data/lib/baykit/bayserver/util/cgi_util.rb +165 -0
  113. data/lib/baykit/bayserver/util/char_util.rb +22 -0
  114. data/lib/baykit/bayserver/util/cities.rb +45 -0
  115. data/lib/baykit/bayserver/util/class_util.rb +17 -0
  116. data/lib/baykit/bayserver/util/counter.rb +23 -0
  117. data/lib/baykit/bayserver/util/data_consume_listener.rb +13 -0
  118. data/lib/baykit/bayserver/util/executor_service.rb +81 -0
  119. data/lib/baykit/bayserver/util/groups.rb +110 -0
  120. data/lib/baykit/bayserver/util/gzip_compressor.rb +55 -0
  121. data/lib/baykit/bayserver/util/headers.rb +194 -0
  122. data/lib/baykit/bayserver/util/host_matcher.rb +48 -0
  123. data/lib/baykit/bayserver/util/http_status.rb +60 -0
  124. data/lib/baykit/bayserver/util/http_util.rb +157 -0
  125. data/lib/baykit/bayserver/util/io_util.rb +32 -0
  126. data/lib/baykit/bayserver/util/ip_matcher.rb +67 -0
  127. data/lib/baykit/bayserver/util/key_val.rb +15 -0
  128. data/lib/baykit/bayserver/util/key_val_list_parser.rb +53 -0
  129. data/lib/baykit/bayserver/util/locale.rb +30 -0
  130. data/lib/baykit/bayserver/util/md5_password.rb +24 -0
  131. data/lib/baykit/bayserver/util/message.rb +56 -0
  132. data/lib/baykit/bayserver/util/mimes.rb +27 -0
  133. data/lib/baykit/bayserver/util/object_factory.rb +13 -0
  134. data/lib/baykit/bayserver/util/object_store.rb +74 -0
  135. data/lib/baykit/bayserver/util/postman.rb +35 -0
  136. data/lib/baykit/bayserver/util/reusable.rb +13 -0
  137. data/lib/baykit/bayserver/util/selector.rb +141 -0
  138. data/lib/baykit/bayserver/util/simple_buffer.rb +53 -0
  139. data/lib/baykit/bayserver/util/simple_inspect.rb +12 -0
  140. data/lib/baykit/bayserver/util/string_util.rb +73 -0
  141. data/lib/baykit/bayserver/util/sys_util.rb +138 -0
  142. data/lib/baykit/bayserver/util/url_decoder.rb +42 -0
  143. data/lib/baykit/bayserver/util/url_encoder.rb +19 -0
  144. data/lib/baykit/bayserver/util/valve.rb +15 -0
  145. data/lib/baykit/bayserver/version.rb +7 -0
  146. data/lib/baykit/bayserver/watercraft/boat.rb +43 -0
  147. data/lib/baykit/bayserver/watercraft/ship.rb +104 -0
  148. data/lib/baykit/bayserver/watercraft/yacht.rb +42 -0
  149. metadata +189 -0
@@ -0,0 +1,217 @@
1
+ require 'fcntl'
2
+ require 'baykit/bayserver/agent/grand_agent'
3
+ require 'baykit/bayserver/util/io_util'
4
+
5
+ module Baykit
6
+ module BayServer
7
+ module Agent
8
+ class GrandAgentMonitor
9
+ include Baykit::BayServer::Util
10
+
11
+ class << self
12
+ attr :num_agents
13
+ attr :cur_id
14
+ attr :anchored_port_map
15
+ attr :monitors
16
+ attr :finale
17
+ end
18
+
19
+ @num_agents = 0
20
+ @cur_id = 0
21
+ @anchored_port_map = []
22
+ @monitors = {}
23
+ @finale = false
24
+
25
+ attr :agent_id
26
+ attr :anchorable
27
+ attr :communication_channel
28
+
29
+ def initialize(agt_id, anchorable, com_channel)
30
+ @agent_id = agt_id
31
+ @anchorable = anchorable
32
+ @communication_channel = com_channel
33
+ end
34
+
35
+ def to_s()
36
+ return "Monitor##{@agent_id}"
37
+ end
38
+
39
+ def on_readable()
40
+ begin
41
+ res = IOUtil.read_int32(@communication_channel)
42
+ if res == nil || res == GrandAgent::CMD_CLOSE
43
+ BayLog.debug("%s read Close", self)
44
+ close()
45
+ GrandAgentMonitor.agent_aborted(@agent_id, @anchorable)
46
+ else
47
+ BayLog.debug("%s read OK: %d", self, res)
48
+ end
49
+ rescue IO::WaitReadable
50
+ #BayLog.debug("%s no data", self)
51
+ end
52
+ end
53
+
54
+ def shutdown()
55
+ BayLog.debug("%s send shutdown command", self)
56
+ send(GrandAgent::CMD_SHUTDOWN)
57
+ end
58
+
59
+ def abort()
60
+ BayLog.debug("%s Send abort command", self)
61
+ send(GrandAgent::CMD_ABORT)
62
+ end
63
+
64
+ def reload_cert()
65
+ BayLog.debug("%s Send reload command", self)
66
+ send(GrandAgent::CMD_RELOAD_CERT)
67
+ end
68
+
69
+ def print_usage()
70
+ BayLog.debug("%s Send mem_usage command", self)
71
+ send(GrandAgent::CMD_MEM_USAGE)
72
+ end
73
+
74
+ def send(cmd)
75
+ BayLog.debug("%s send command %s ch=%s", self, cmd, @communication_channel)
76
+ IOUtil.write_int32(@communication_channel, cmd)
77
+ end
78
+
79
+ def close()
80
+ @communication_channel.close()
81
+ end
82
+
83
+ ########################################
84
+ # Class methods
85
+ ########################################
86
+
87
+ def self.init(num_agents, anchored_port_map)
88
+ @num_agents = num_agents
89
+ @anchored_port_map = anchored_port_map
90
+ @num_agents.times do
91
+ add(true)
92
+ end
93
+ end
94
+
95
+ def self.add(anchoroable)
96
+ @cur_id = @cur_id + 1
97
+ agt_id = @cur_id
98
+ if agt_id > 100
99
+ BayLog.error("Too many agents started")
100
+ exit(1)
101
+ end
102
+
103
+ if BayServer.harbor.multi_core
104
+ new_argv = BayServer.commandline_args.dup
105
+ new_argv.insert(0, "ruby")
106
+ new_argv << "-agentid=" + agt_id.to_s
107
+
108
+ ports = ""
109
+
110
+ no_close_io = {} # Port list not to close on spawned
111
+ @anchored_port_map.each_key do |ch|
112
+ no_close_io[ch] = ch
113
+ if ports != ""
114
+ ports +=","
115
+ end
116
+ ports += ch.fileno.to_s
117
+ end
118
+ new_argv << "-ports=" + ports
119
+
120
+ server = TCPServer.open("localhost", 0)
121
+ #BayLog.info("port=%d", server.local_address.ip_port)
122
+ new_argv << "-monitor_port=" + server.local_address.ip_port.to_s
123
+
124
+ if SysUtil.run_on_windows()
125
+ child = spawn(ENV, new_argv.join(" "))
126
+ else
127
+ child = spawn(ENV, new_argv.join(" "), no_close_io)
128
+ end
129
+
130
+ BayLog.debug("Process spawned cmd=%s pid=%d", new_argv, child)
131
+
132
+ client_socket = server.accept()
133
+ server.close()
134
+
135
+ else
136
+
137
+ if SysUtil::run_on_windows()
138
+ pair = Socket.socketpair(Socket::AF_INET, Socket::SOCK_STREAM, 0)
139
+ else
140
+ pair = Socket.socketpair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0)
141
+ end
142
+
143
+ client_socket = pair[0]
144
+ GrandAgent.add(agt_id, anchoroable)
145
+
146
+ # Agents run on single core (thread mode)
147
+ Thread.new() do
148
+ agt = GrandAgent.get(agt_id)
149
+ agt.run_command_receiver(pair[1])
150
+ agt.run()
151
+ end
152
+
153
+ end
154
+
155
+ @monitors[agt_id] =
156
+ GrandAgentMonitor.new(
157
+ agt_id,
158
+ anchoroable,
159
+ client_socket)
160
+ end
161
+
162
+ def self.agent_aborted(agt_id, anchorable)
163
+ BayLog.info(BayMessage.get(:MSG_GRAND_AGENT_SHUTDOWN, agt_id))
164
+
165
+ @monitors.delete(agt_id)
166
+
167
+ if not @finale
168
+ if @monitors.length < @num_agents
169
+ begin
170
+ if !BayServer.harbor.multi_core
171
+ GrandAgent.add(-1, anchorable)
172
+ end
173
+ add(anchorable)
174
+ rescue => e
175
+ BayLog.error_e(e)
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ def self.reload_cert_all()
182
+ @monitors.values.each { |mon| mon.reload_cert() }
183
+ end
184
+
185
+ def self.restart_all()
186
+ old_monitors = @monitors.dup()
187
+
188
+ #@agent_count.times {add()}
189
+
190
+ old_monitors.values.each { |mon| mon.shutdown() }
191
+ end
192
+
193
+ def self.shutdown_all()
194
+ @finale = true
195
+ @monitors.dup().values.each do |mon|
196
+ mon.shutdown()
197
+ end
198
+ end
199
+
200
+ def self.abort_all()
201
+ @finale = true
202
+ @monitors.dup().values.each do |mon|
203
+ mon.abort()
204
+ end
205
+ exit(1)
206
+ end
207
+
208
+ def self.print_usage_all()
209
+ @monitors.values.each do |mon|
210
+ mon.print_usage()
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
217
+
@@ -0,0 +1,14 @@
1
+ module Baykit
2
+ module BayServer
3
+ module Agent
4
+ class NextSocketAction
5
+ CONTINUE = 1
6
+ SUSPEND = 2
7
+ READ = 3
8
+ WRITE = 4
9
+ CLOSE = 5
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,433 @@
1
+ require 'date'
2
+ require 'baykit/bayserver/agent/next_socket_action'
3
+ require 'baykit/bayserver/util/selector'
4
+
5
+ module Baykit
6
+ module BayServer
7
+ module Agent
8
+
9
+ #
10
+ # Channel handler
11
+ # Sockets or file descriptors are kinds of channel
12
+ #
13
+ class NonBlockingHandler
14
+ include Baykit::BayServer::Agent
15
+ include Baykit::BayServer::Util
16
+
17
+ class ChannelState
18
+ attr_accessor :accepted
19
+ attr :channel
20
+ attr :listener
21
+ attr_accessor :connecting
22
+ attr_accessor :closing
23
+
24
+ attr :last_access_time
25
+
26
+ def initialize(ch, lis)
27
+ @channel = ch
28
+ @listener = lis
29
+ @accepted = false
30
+ @connecting = false
31
+ @closing = false
32
+ end
33
+
34
+ def access
35
+ @last_access_time = DateTime.now
36
+ end
37
+
38
+ def to_s
39
+ if @listener != nil
40
+ str = @listener.to_s
41
+ else
42
+ str = super.to_s
43
+ end
44
+ if @closing
45
+ str += " closing";
46
+ end
47
+ return str
48
+ end
49
+ end
50
+
51
+ class ChannelOperation
52
+
53
+ attr :ch
54
+ attr_accessor :op
55
+ attr_accessor :to_connect
56
+ attr_accessor :to_close
57
+
58
+
59
+ def initialize(ch, op, to_connect, to_close)
60
+ @ch = ch
61
+ @op = op
62
+ @to_connect = to_connect
63
+ @to_close = to_close
64
+ end
65
+
66
+
67
+ end
68
+
69
+ attr :agent
70
+ attr :ch_map
71
+ attr :ch_count
72
+ attr :operations
73
+ attr :operations_lock
74
+
75
+ def initialize(ship_agent)
76
+ @agent = ship_agent
77
+ @ch_map = {}
78
+ @ch_count = 0
79
+ @operations = []
80
+ @operations_lock = Monitor.new()
81
+ end
82
+
83
+
84
+ def to_s()
85
+ return @agent.to_s()
86
+ end
87
+
88
+ def handle_channel(ch, op)
89
+
90
+ ch_state = find_channel_state(ch)
91
+ if ch_state == nil
92
+ BayLog.error("Cannot find fd state (Maybe file is closed)")
93
+ @agent.selector.unregister(ch)
94
+ return
95
+ end
96
+
97
+ next_action = nil
98
+ begin
99
+
100
+ if ch_state.closing
101
+ next_action = NextSocketAction::CLOSE
102
+
103
+ elsif ch_state.connecting
104
+ ch_state.connecting = false
105
+ # connectable
106
+ next_action = ch_state.listener.on_connectable(ch)
107
+ if next_action == nil
108
+ raise Sink.new("unknown next action")
109
+ elsif next_action == NextSocketAction::CONTINUE
110
+ ask_to_read(ch)
111
+ end
112
+
113
+ else
114
+ if op & Selector::OP_READ != 0
115
+ # readable
116
+ next_action = ch_state.listener.on_readable(ch)
117
+ if next_action == nil
118
+ raise Sink.new("unknown next action")
119
+ elsif next_action == NextSocketAction::WRITE
120
+ op = @agent.selector.get_op(ch)
121
+ op = op | Selector::OP_WRITE
122
+ @agent.selector.modify(ch, op)
123
+ end
124
+ end
125
+
126
+ if (next_action != NextSocketAction::CLOSE) && (op & Selector::OP_WRITE != 0)
127
+ # writable
128
+ next_action = ch_state.listener.on_writable(ch)
129
+ if next_action == nil
130
+ raise Sink.new("unknown next action")
131
+ elsif next_action == NextSocketAction::READ
132
+ # Handle as "Write Off"
133
+ op = @agent.selector.get_op(ch)
134
+ op = op & ~Selector::OP_WRITE
135
+ if op == 0
136
+ @agent.selector.unregister(ch)
137
+ else
138
+ @agent.selector.modify(ch, op)
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+
145
+ if next_action == nil
146
+ raise Sink.new("unknown next action")
147
+ end
148
+
149
+ rescue Sink => e
150
+ raise e
151
+
152
+ rescue => e
153
+ if e.kind_of? EOFError
154
+ BayLog.debug("%s Socket closed by peer: skt=%s", @agent, ch.inspect)
155
+ elsif e.kind_of? SystemCallError
156
+ BayLog.debug("%s O/S error: %s (skt=%s)", @agent, e.message, ch.inspect)
157
+ elsif e.kind_of? IOError
158
+ BayLog.debug("%s IO error: %s (skt=%s)", @agent, e.message, ch.inspect)
159
+ elsif e.kind_of? OpenSSL::SSL::SSLError
160
+ BayLog.debug("%s SSL error: %s (skt=%s)", @agent, e.message, ch.inspect)
161
+ else
162
+ BayLog.error("%s Unhandled error error: %s (skt=%s)", @agent, e, ch.inspect)
163
+ throw e
164
+ end
165
+ # Cannot handle Exception any more
166
+ ch_state.listener.on_error(ch, e)
167
+ next_action = NextSocketAction::CLOSE
168
+ end
169
+
170
+ cancel = false
171
+ ch_state.access()
172
+ BayLog.trace("%s next=%d", ch_state, next_action)
173
+ case next_action
174
+ when NextSocketAction::CLOSE
175
+ close_channel(ch, ch_state)
176
+ cancel = false # already canceled in close_channel method
177
+
178
+ when NextSocketAction::SUSPEND
179
+ cancel = true
180
+
181
+ when NextSocketAction::CONTINUE, NextSocketAction::READ, NextSocketAction::WRITE
182
+ # do nothing
183
+
184
+ else
185
+ raise RuntimeError.new("IllegalState:: #{next_action}")
186
+ end
187
+
188
+ if cancel
189
+ BayLog.trace("%s cancel key chState=%s", @agent, ch_state)
190
+ @agent.selector.unregister(ch)
191
+ end
192
+ end
193
+
194
+ def register_channel_ops()
195
+ if @operations.empty?
196
+ return 0
197
+ end
198
+
199
+ @operations_lock.synchronize do
200
+ nch = @operations.length
201
+ @operations.each do |ch_op|
202
+ st = self.find_channel_state(ch_op.ch)
203
+ if ch_op.ch.closed?
204
+ # Channel is closed before register operation
205
+ BayLog.debug("%s Try to register closed socket (Ignore)", @agent)
206
+ next
207
+ end
208
+
209
+ begin
210
+ BayLog.trace("%s register op=%s chState=%s", @agent, self.class.op_mode(ch_op.op), st)
211
+ op = @agent.selector.get_op(ch_op.ch)
212
+ if op == nil
213
+ @agent.selector.register(ch_op.ch, ch_op.op)
214
+ else
215
+ new_op = op | ch_op.op
216
+ BayLog.debug("%s Already registered ch=%s op=%s update to %s", @agent, ch_op.ch, self.class.op_mode(op), self.class.op_mode(new_op))
217
+ @agent.selector.modify(ch_op.ch, new_op)
218
+ end
219
+
220
+ if ch_op.to_connect
221
+ if st == nil
222
+ BayLog.warn("%s register connect but ChannelState is null", @agent);
223
+ else
224
+ st.connecting = true
225
+ end
226
+
227
+ elsif ch_op.to_close
228
+ if st == nil
229
+ BayLog.warn("%s chState=%s register close but ChannelState", self.agent);
230
+ else
231
+ st.closing = true
232
+ end
233
+ end
234
+
235
+ rescue => e
236
+ cst = find_channel_state(ch_op.ch)
237
+ BayLog.error_e(e, "%s Cannot register operation: %s", self.agent, cst != nil ? cst.listener : nil)
238
+ end
239
+ end
240
+
241
+ @operations.clear()
242
+ return nch
243
+
244
+ end
245
+ end
246
+
247
+ def close_timeout_sockets()
248
+ if @ch_map.empty?
249
+ return
250
+ end
251
+
252
+ close_list = []
253
+ now = DateTime.now
254
+ @ch_map.values.each do |ch_state|
255
+ if ch_state.listener != nil
256
+ duration = ((now - ch_state.last_access_time) * 86400).to_i
257
+ if ch_state.listener.check_timeout(ch_state.channel, duration)
258
+ BayLog.debug("%s timeout: skt=%s", @agent, ch_state.channel)
259
+ close_list << ch_state
260
+ end
261
+ end
262
+ end
263
+
264
+ close_list.each do |ch_state|
265
+ close_channel ch_state.channel, ch_state
266
+ end
267
+ end
268
+
269
+ def add_channel_listener(ch, lis)
270
+ ch_state = ChannelState.new(ch, lis)
271
+ add_channel_state(ch, ch_state)
272
+ ch_state.access()
273
+ return ch_state
274
+ end
275
+
276
+ def ask_to_start(ch)
277
+ BayLog.debug("%s askToStart: ch=%s", @agent, ch)
278
+
279
+ ch_state = find_channel_state(ch)
280
+ ch_state.accepted = true
281
+
282
+ end
283
+
284
+ def ask_to_connect(ch, addr)
285
+ ch_state = find_channel_state(ch)
286
+ BayLog.debug("%s askToConnect addr=%s skt=%s chState=%s", @agent, addr, ch, ch_state)
287
+
288
+ begin
289
+ ch.connect_nonblock(addr)
290
+ rescue IO::WaitWritable => e
291
+ #BayLog.error_e(e)
292
+ end
293
+
294
+ ch_state.connecting = true
295
+ add_operation(ch, Selector::OP_READ, true)
296
+ end
297
+
298
+ def ask_to_read(ch)
299
+ ch_state = find_channel_state(ch)
300
+ BayLog.debug("%s askToRead chState=%s", @agent, ch_state);
301
+
302
+ if ch.closed?
303
+ raise IOError.new("Channel is closed")
304
+ end
305
+
306
+ add_operation(ch, Selector::OP_READ)
307
+
308
+ if ch_state != nil
309
+ ch_state.access()
310
+ end
311
+ end
312
+
313
+ def ask_to_write(ch)
314
+ ch_state = find_channel_state(ch)
315
+ BayLog.debug("%s askToWrite chState=%s", @agent, ch_state);
316
+
317
+ if ch.closed?
318
+ BayLog.warn("%s Channel is closed: %s", @agent, ch)
319
+ return
320
+ end
321
+
322
+ add_operation(ch, Selector::OP_WRITE)
323
+
324
+ if ch_state == nil
325
+ BayLog.error("Unknown socket (or closed)")
326
+ return
327
+ end
328
+
329
+ ch_state.access()
330
+ end
331
+
332
+ def ask_to_close(ch)
333
+ ch_state = find_channel_state(ch)
334
+ BayLog.debug("%s askToClose chState=%s", @agent, ch_state);
335
+
336
+ if ch_state == nil
337
+ BayLog.warn("%s channel state not found: %s", @agent, ch)
338
+ return
339
+ end
340
+
341
+ ch_state.closing = true
342
+ add_operation(ch, Selector::OP_WRITE, false, true)
343
+
344
+ ch_state.access
345
+ end
346
+
347
+
348
+ private
349
+
350
+ def add_operation(ch, op, to_connect=false, to_close=false)
351
+ @operations_lock.synchronize do
352
+ found = false
353
+ @operations.each do |ch_op|
354
+ if ch_op.ch == ch
355
+ ch_op.op |= op
356
+ ch_op.to_close = (ch_op.to_close or to_close)
357
+ ch_op.to_connect = (ch_op.to_connect or to_connect)
358
+ found = true
359
+ BayLog.trace("%s Update operation: %s con=%s close=%s ch=%s", @agent, self.class.op_mode(ch_op.op), ch_op.to_connect, ch_op.to_close, ch_op.ch.inspect())
360
+ end
361
+ end
362
+
363
+ if not found
364
+ BayLog.trace("%s New operation: %s con=%s close=%s ch=%s", @agent, self.class.op_mode(op), to_connect, to_close, ch.inspect());
365
+ @operations << ChannelOperation.new(ch, op, to_connect, to_close)
366
+ end
367
+ end
368
+
369
+ @agent.wakeup
370
+ end
371
+
372
+ def close_channel(ch, ch_state)
373
+ BayLog.debug("%s Close chState=%s", @agent, ch_state)
374
+
375
+ if ch_state == nil
376
+ ch_state = find_channel_state(ch)
377
+ end
378
+ if ch_state.accepted and @agent.accept_handler
379
+ agent.accept_handler.on_closed
380
+ end
381
+
382
+ if ch_state.listener
383
+ ch_state.listener.on_closed(ch)
384
+ end
385
+
386
+ remove_channel_state(ch)
387
+
388
+ begin
389
+ @agent.selector.unregister(ch)
390
+ rescue IOError => e
391
+ BayLog.warn_e(e)
392
+ end
393
+
394
+ ch.close()
395
+ end
396
+
397
+ def add_channel_state(ch, ch_state)
398
+ BayLog.trace("%s add skt %s chState=%s", @agent, ch, ch_state);
399
+
400
+ @ch_map[ch] = ch_state
401
+ @ch_count += 1
402
+ end
403
+
404
+ def remove_channel_state(ch)
405
+ BayLog.trace("%s remove skt %s", @agent, ch);
406
+
407
+ @ch_map.delete(ch)
408
+ @ch_count -= 1
409
+ end
410
+
411
+ def find_channel_state(ch)
412
+ @ch_map[ch]
413
+ end
414
+
415
+ def NonBlockingHandler.op_mode(mode)
416
+ mode_str = ""
417
+ if (mode & Selector::OP_READ) != 0
418
+ mode_str = "OP_READ"
419
+ end
420
+
421
+ if (mode & Selector::OP_WRITE) != 0
422
+ if mode_str != ""
423
+ mode_str += "|"
424
+ end
425
+ mode_str += "OP_WRITE"
426
+ end
427
+
428
+ return mode_str
429
+ end
430
+ end
431
+ end
432
+ end
433
+ end
@@ -0,0 +1,3 @@
1
+ require 'baykit/bayserver/agent/spin_handler'
2
+ require 'baykit/bayserver/agent/next_socket_action'
3
+