bayserver-core 2.2.0

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.
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
+