bayserver-core 2.2.2 → 2.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3384e309df7bc1a51935394fa90199ec3037f2a40978a6612e5c4a8ae826cdbf
4
- data.tar.gz: 0dd2baf7f2cf5878eda0fcace793d50f3dce873962c983e3d49fe899542cf158
3
+ metadata.gz: f41f9fb4f873cb31dc74958aa960ea25631f97b3c247ec19e79610e7c7401891
4
+ data.tar.gz: 9399102f0b30b1ad6dfe92439707ec97e6b678593855b5a3c0d933253f1d0744
5
5
  SHA512:
6
- metadata.gz: 3a84b96eba136c9bf08ec77ced8300289967bbe4a55d0aa9bdf66a4ceaad72dc0e27409878b92faf9f594ea11ed48dcff58fbc669b38daad37ef163c6d7b7bae
7
- data.tar.gz: 64f1d19b52431b7f0986be35723231ea56ed17941314ce44ecab9d4a26296dc89e60f7a179f1eb71a4e5e3719de7d6630ac38a01f97a63ec20b2655707fba5f2
6
+ metadata.gz: 5eaa95c017ca683078c214ba13700b3b99735a4883a74433b1a9654342930d2d5e297d7ab9fdcac3291da1ca51629e17315a88cd4a89b34124e5b76a3e8da05e
7
+ data.tar.gz: dc9635c29598928060361e0ec733c3af899bc211486256b806f0d7ca00b38a6d4f73982d16a94624db3463ed23319105d59dbe03f2f4100f732b1506be55219d
@@ -1,4 +1,5 @@
1
1
  require 'socket'
2
+ require 'objspace'
2
3
 
3
4
  require 'baykit/bayserver/sink'
4
5
  require 'baykit/bayserver/agent/accept_handler'
@@ -23,15 +24,6 @@ module Baykit
23
24
  include Baykit::BayServer::Agent::Signal
24
25
  include Baykit::BayServer::Util
25
26
 
26
- module GrandAgentLifecycleListener
27
- #
28
- # interface
29
- #
30
- # void add(int agentId);
31
- # void remove(int agentId);
32
- #
33
- end
34
-
35
27
  SELECT_TIMEOUT_SEC = 10
36
28
 
37
29
  CMD_OK = 0
@@ -54,6 +46,7 @@ module Baykit
54
46
  attr :unanchorable_transporters
55
47
  attr :aborted
56
48
  attr :command_receiver
49
+ attr :timer_handlers
57
50
 
58
51
  class << self
59
52
  attr :agents
@@ -83,6 +76,7 @@ module Baykit
83
76
  @agent_id = agent_id
84
77
  @anchorable = anchorable
85
78
 
79
+ @timer_handlers = []
86
80
  if @anchorable
87
81
  @accept_handler = AcceptHandler.new(self, GrandAgent.anchorable_port_map)
88
82
  else
@@ -102,7 +96,7 @@ module Baykit
102
96
 
103
97
 
104
98
  def to_s()
105
- return "Agt#" + @agent_id.to_s
99
+ return "agt#" + @agent_id.to_s
106
100
  end
107
101
 
108
102
 
@@ -185,8 +179,9 @@ module Baykit
185
179
 
186
180
  if not processed
187
181
  # timeout check
188
- @non_blocking_handler.close_timeout_sockets()
189
- @spin_handler.stop_timeout_spins()
182
+ @timer_handlers.each do |h|
183
+ h.on_timer()
184
+ end
190
185
  end
191
186
 
192
187
  rescue => e
@@ -204,7 +199,6 @@ module Baykit
204
199
  end
205
200
 
206
201
  def shutdown()
207
- BayLog.debug("%s shutdown", self)
208
202
  if @accept_handler != nil
209
203
  @accept_handler.shutdown()
210
204
  end
@@ -213,6 +207,11 @@ module Baykit
213
207
  end
214
208
 
215
209
  def abort_agent(err = nil, status = 1)
210
+ BayLog.info("%s abort aborted=%s", self, @aborted)
211
+ if @aborted
212
+ return
213
+ end
214
+
216
215
  if err
217
216
  BayLog.fatal("%s abort", self)
218
217
  BayLog.fatal_e(err)
@@ -225,13 +224,13 @@ module Baykit
225
224
 
226
225
  GrandAgent.agents.delete(@agent_id)
227
226
 
227
+ @aborted = true
228
228
  if BayServer.harbor.multi_core
229
229
  exit(1)
230
230
  else
231
231
  clean()
232
232
  end
233
233
 
234
- @aborted = true
235
234
  end
236
235
 
237
236
  def reload_cert()
@@ -248,8 +247,15 @@ module Baykit
248
247
 
249
248
  def print_usage()
250
249
  # print memory usage
251
- BayLog.info("Agent#%d MemUsage", @agent_id);
252
- MemUsage.get(@agent_id).print_usage(1);
250
+ BayLog.info("%s MemUsage", self)
251
+ BayLog.info(" Ruby version: %s", RUBY_VERSION)
252
+ memsize = ObjectSpace.memsize_of_all
253
+ # formatted by comma
254
+ msize_comma = memsize.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse.then do |str|
255
+ str[0] == ',' ? str[1..-1] : str
256
+ end
257
+ BayLog.info(" Total object size: %s bytes", msize_comma)
258
+ MemUsage.get(@agent_id).print_usage(1)
253
259
  end
254
260
 
255
261
  def wakeup
@@ -261,6 +267,14 @@ module Baykit
261
267
  @command_receiver = CommandReceiver.new(self, com_channel)
262
268
  end
263
269
 
270
+ def add_timer_handler(handler)
271
+ @timer_handlers << handler
272
+ end
273
+
274
+ def remove_timer_handler(handler)
275
+ @timer_handlers.delete(handler)
276
+ end
277
+
264
278
  private
265
279
  def on_waked_up(pipe_fd)
266
280
  #BayLog.debug("%s waked up", self)
@@ -69,6 +69,7 @@ module Baykit
69
69
  def print_usage()
70
70
  BayLog.debug("%s Send mem_usage command", self)
71
71
  send(GrandAgent::CMD_MEM_USAGE)
72
+ sleep(0.5) # Lazy implementation
72
73
  end
73
74
 
74
75
  def send(cmd)
@@ -0,0 +1,16 @@
1
+
2
+ module Baykit
3
+ module BayServer
4
+ module Agent
5
+ module LifecycleListener
6
+ #
7
+ # interface
8
+ #
9
+ # void add(int agentId);
10
+ # void remove(int agentId);
11
+ #
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -11,6 +11,7 @@ module Baykit
11
11
  # Sockets or file descriptors are kinds of channel
12
12
  #
13
13
  class NonBlockingHandler
14
+ include Baykit::BayServer::Agent::TimerHandler # implements
14
15
  include Baykit::BayServer::Agent
15
16
  include Baykit::BayServer::Util
16
17
 
@@ -78,6 +79,8 @@ module Baykit
78
79
  @ch_count = 0
79
80
  @operations = []
80
81
  @operations_lock = Monitor.new()
82
+
83
+ @agent.add_timer_handler(self)
81
84
  end
82
85
 
83
86
 
@@ -85,6 +88,18 @@ module Baykit
85
88
  return @agent.to_s()
86
89
  end
87
90
 
91
+ ######################################################
92
+ # Implements TimerHandler
93
+ ######################################################
94
+
95
+ def on_timer()
96
+ self.close_timeout_sockets()
97
+ end
98
+
99
+ ######################################################
100
+ # Custom methods
101
+ ######################################################
102
+
88
103
  def handle_channel(ch, op)
89
104
 
90
105
  ch_state = find_channel_state(ch)
@@ -106,8 +121,15 @@ module Baykit
106
121
  next_action = ch_state.listener.on_connectable(ch)
107
122
  if next_action == nil
108
123
  raise Sink.new("unknown next action")
109
- elsif next_action == NextSocketAction::CONTINUE
110
- ask_to_read(ch)
124
+ elsif next_action == NextSocketAction::READ
125
+ # "Write-OP Off"
126
+ op = @agent.selector.get_op(ch)
127
+ op = op & ~Selector::OP_WRITE
128
+ if op == 0
129
+ @agent.selector.unregister(ch)
130
+ else
131
+ @agent.selector.modify(ch, op)
132
+ end
111
133
  end
112
134
 
113
135
  else
@@ -253,9 +275,14 @@ module Baykit
253
275
  now = DateTime.now
254
276
  @ch_map.values.each do |ch_state|
255
277
  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)
278
+ begin
279
+ duration = ((now - ch_state.last_access_time) * 86400).to_i
280
+ if ch_state.listener.check_timeout(ch_state.channel, duration)
281
+ BayLog.debug("%s timeout: ch=%s", @agent, ch_state.channel)
282
+ close_list << ch_state
283
+ end
284
+ rescue IOError => e
285
+ BayLog.error_e(e)
259
286
  close_list << ch_state
260
287
  end
261
288
  end
@@ -283,7 +310,7 @@ module Baykit
283
310
 
284
311
  def ask_to_connect(ch, addr)
285
312
  ch_state = find_channel_state(ch)
286
- BayLog.debug("%s askToConnect addr=%s skt=%s chState=%s", @agent, addr, ch, ch_state)
313
+ BayLog.debug("%s askToConnect addr=%s skt=%s chState=%s", @agent, addr.ip_address, ch, ch_state)
287
314
 
288
315
  begin
289
316
  ch.connect_nonblock(addr)
@@ -292,7 +319,7 @@ module Baykit
292
319
  end
293
320
 
294
321
  ch_state.connecting = true
295
- add_operation(ch, Selector::OP_READ, true)
322
+ add_operation(ch, Selector::OP_WRITE, true)
296
323
  end
297
324
 
298
325
  def ask_to_read(ch)
@@ -379,9 +406,12 @@ module Baykit
379
406
  def close_channel(ch, ch_state)
380
407
  BayLog.debug("%s Close chState=%s", @agent, ch_state)
381
408
 
409
+ ch.close()
410
+
382
411
  if ch_state == nil
383
412
  ch_state = find_channel_state(ch)
384
413
  end
414
+
385
415
  if ch_state.accepted and @agent.accept_handler
386
416
  agent.accept_handler.on_closed
387
417
  end
@@ -398,7 +428,6 @@ module Baykit
398
428
  BayLog.warn_e(e)
399
429
  end
400
430
 
401
- ch.close()
402
431
  end
403
432
 
404
433
  def add_channel_state(ch, ch_state)
@@ -68,6 +68,7 @@ module Baykit
68
68
  begin
69
69
  a = Addrinfo.tcp(host, port)
70
70
  s = Socket.new(a.ipv4? ? Socket::AF_INET : Socket::AF_INET6, Socket::SOCK_STREAM)
71
+ s.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, [60, 0].pack("l_2"))
71
72
  s.connect(a)
72
73
  s.write(cmd + "\n")
73
74
  s.flush();
@@ -1,9 +1,12 @@
1
+ require 'baykit/bayserver/agent/timer_handler'
1
2
 
2
3
  module Baykit
3
4
  module BayServer
4
5
  module Agent
5
6
  class SpinHandler
6
7
 
8
+ include Baykit::BayServer::Agent::TimerHandler # implements
9
+
7
10
  module SpinListener
8
11
  #
9
12
  # interface
@@ -35,12 +38,25 @@ module Baykit
35
38
  @lock = Mutex.new
36
39
  @agent = agt
37
40
  @spin_count = 0
41
+ @agent.add_timer_handler(self)
38
42
  end
39
43
 
40
44
  def to_s()
41
45
  return @agent.to_s()
42
46
  end
43
47
 
48
+ ######################################################
49
+ # Implements TimerHandler
50
+ ######################################################
51
+
52
+ def on_timer()
53
+ stop_timeout_spins()
54
+ end
55
+
56
+ ######################################################
57
+ # Custom methods
58
+ ######################################################
59
+ #
44
60
  def process_data()
45
61
  if @listeners.empty?
46
62
  return false
@@ -0,0 +1,15 @@
1
+
2
+ module Baykit
3
+ module BayServer
4
+ module Agent
5
+ module TimerHandler # interface
6
+
7
+ def on_timer()
8
+ raise NotImplementedError()
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
15
+
@@ -65,13 +65,13 @@ module Baykit
65
65
  # Other methods
66
66
  ######################################################
67
67
 
68
- def get_tour(tur_key)
68
+ def get_tour(tur_key, force=false, rent=true)
69
69
  tur = nil
70
70
  store_key = InboundShip.uniq_key(@ship_id, tur_key)
71
71
  @lock.synchronize do
72
72
  tur = @tour_store.get(store_key)
73
- if tur == nil
74
- tur = @tour_store.rent(store_key, false)
73
+ if tur == nil && rent
74
+ tur = @tour_store.rent(store_key, force)
75
75
  if tur == nil
76
76
  return nil
77
77
  end
@@ -135,13 +135,7 @@ module Baykit
135
135
  @port_docker.additional_headers.each do |nv|
136
136
  tur.res.headers.add(nv[0], nv[1])
137
137
  end
138
- begin
139
- @protocol_handler.send_res_headers(tur)
140
- rescue IOError => e
141
- BayLog.debug_e(e, "%s abort: %s", tur, e)
142
- tur.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
143
- raise e
144
- end
138
+ @protocol_handler.send_res_headers(tur)
145
139
  end
146
140
  end
147
141
 
@@ -163,28 +157,12 @@ module Baykit
163
157
 
164
158
  check_ship_id(check_id)
165
159
 
166
- if tur.zombie? || tur.aborted?
167
- # Don't send peer any data
168
- BayLog::debug("%s Aborted or zombie tour. do nothing: %s state=%s", self, tur, tur.state)
169
- tur.change_state(Tour::TOUR_ID_NOCHECK, TourState::ENDED)
170
- if callback != nil
171
- callback.call()
172
- end
173
- return
174
- end
175
-
176
160
  max_len = @protocol_handler.max_res_packet_data_size();
177
161
  if len > max_len
178
162
  send_res_content(Ship::SHIP_ID_NOCHECK, tur, bytes, ofs, max_len)
179
163
  send_res_content(Ship::SHIP_ID_NOCHECK, tur, bytes, ofs + max_len, len - max_len, &callback)
180
164
  else
181
- begin
182
- @protocol_handler.send_res_content(tur, bytes, ofs, len, &callback)
183
- rescue IOError => e
184
- BayLog.debug_e(e, "%s abort: %s", tur, e)
185
- tur.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
186
- raise e
187
- end
165
+ @protocol_handler.send_res_content(tur, bytes, ofs, len, &callback)
188
166
  end
189
167
  end
190
168
 
@@ -193,34 +171,25 @@ module Baykit
193
171
  check_ship_id(chk_ship_id)
194
172
  BayLog.debug("%s sendEndTour: %s state=%s", self, tur, tur.state)
195
173
 
196
- if tur.zombie? || tur.aborted?
197
- # Don't send peer any data. Do nothing
198
- BayLog.debug("%s Aborted or zombie tour. do nothing: %s state=%s", self, tur, tur.state)
199
- tur.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ENDED)
200
- callback.call()
201
- else
202
- if !tur.valid?
203
- raise Sink.new("Tour is not valid")
174
+ if !tur.valid?
175
+ raise Sink.new("Tour is not valid")
176
+ end
177
+ keep_alive = false
178
+ if tur.req.headers.get_connection() == Headers::CONNECTION_KEEP_ALIVE
179
+ keep_alive = true
180
+ if keep_alive
181
+ res_conn = tur.res.headers.get_connection()
182
+ keep_alive = (res_conn == Headers::CONNECTION_KEEP_ALIVE) ||
183
+ (res_conn == Headers::CONNECTION_UNKOWN)
204
184
  end
205
- keep_alive = false
206
- if tur.req.headers.get_connection() == Headers::CONNECTION_KEEP_ALIVE
207
- keep_alive = true
208
- if keep_alive
209
- res_conn = tur.res.headers.get_connection()
210
- keep_alive = (res_conn == Headers::CONNECTION_KEEP_ALIVE) ||
211
- (res_conn == Headers::CONNECTION_UNKOWN)
212
- end
213
- if keep_alive
214
- if tur.res.headers.content_length() < 0
215
- keep_alive = false
216
- end
185
+ if keep_alive
186
+ if tur.res.headers.content_length() < 0
187
+ keep_alive = false
217
188
  end
218
189
  end
219
-
220
- tur.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ENDED)
221
-
222
- @protocol_handler.send_end_tour(tur, keep_alive, &callback)
223
190
  end
191
+
192
+ @protocol_handler.send_end_tour(tur, keep_alive, &callback)
224
193
  end
225
194
  end
226
195
 
@@ -1,4 +1,5 @@
1
1
  require 'baykit/bayserver/agent/grand_agent'
2
+ require 'baykit/bayserver/agent/lifecycle_listener'
2
3
 
3
4
  require 'baykit/bayserver/docker/base/inbound_ship'
4
5
  require 'baykit/bayserver/docker/base/inbound_ship_store'
@@ -16,7 +17,7 @@ module Baykit
16
17
  include Baykit::BayServer::Agent
17
18
 
18
19
  class AgentListener
19
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener # implements
20
+ include Baykit::BayServer::Agent::LifecycleListener # implements
20
21
 
21
22
  def add(agt)
22
23
  InboundShipStore.stores[agt.agent_id] = InboundShipStore.new();
@@ -1,4 +1,5 @@
1
1
  require 'baykit/bayserver/agent/grand_agent'
2
+ require 'baykit/bayserver/agent/lifecycle_listener'
2
3
  require 'baykit/bayserver/agent/transporter/plain_transporter'
3
4
  require 'baykit/bayserver/agent/transporter/spin_write_transporter'
4
5
  require 'baykit/bayserver/docker/built_in/write_file_taxi'
@@ -20,7 +21,7 @@ module Baykit
20
21
  include Baykit::BayServer::Bcf
21
22
 
22
23
  class AgentListener
23
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener # implements
24
+ include Baykit::BayServer::Agent::LifecycleListener # implements
24
25
  include Baykit::BayServer::Agent::Transporter
25
26
 
26
27
  attr :log_docker
@@ -45,7 +46,7 @@ module Baykit
45
46
 
46
47
  when LOG_WRITE_METHOD_TAXI
47
48
  tp = WriteFileTaxi.new()
48
- tp.init(File.open(file_name, "a"), boat)
49
+ tp.init(agt.agent_id, File.open(file_name, "a"), boat)
49
50
 
50
51
  end
51
52
 
@@ -19,6 +19,7 @@ module Baykit
19
19
  attr :data_listener
20
20
  attr :write_queue
21
21
  attr :lock
22
+ attr :agent_id
22
23
 
23
24
  def initialize()
24
25
  super
@@ -26,7 +27,8 @@ module Baykit
26
27
  @lock = Mutex.new()
27
28
  end
28
29
 
29
- def init(out, data_listener)
30
+ def init(agt_id, out, data_listener)
31
+ @agent_id = agt_id
30
32
  @outfile = out
31
33
  @data_listener = data_listener
32
34
  @ch_valid = true
@@ -92,7 +94,7 @@ module Baykit
92
94
  end
93
95
 
94
96
  def next_run()
95
- TaxiRunner.post(self)
97
+ TaxiRunner.post(@agent_id, self)
96
98
  end
97
99
  end
98
100
  end
@@ -38,6 +38,12 @@ module Baykit
38
38
  end
39
39
 
40
40
  tur_id = tur.id()
41
+
42
+ if !@started
43
+ # The buffer will become corrupted due to reuse.
44
+ buf = buf.dup()
45
+ end
46
+
41
47
  @warp_ship.warp_handler.post_warp_contents(
42
48
  tur,
43
49
  buf,
@@ -51,6 +57,7 @@ module Baykit
51
57
 
52
58
  def on_end_content(tur)
53
59
  BayLog.debug("%s End req content tur=%s", @warp_ship, tur)
60
+ @warp_ship.check_ship_id(@warp_ship_id)
54
61
  @warp_ship.warp_handler.post_warp_end(tur)
55
62
  end
56
63
 
@@ -66,6 +73,7 @@ module Baykit
66
73
  if !@started
67
74
  @warp_ship.protocol_handler.command_packer.flush(@warp_ship)
68
75
  BayLog.debug("%s Start Warp tour", self)
76
+ @warp_ship.flush()
69
77
  @started = true
70
78
  end
71
79
  end
@@ -1,6 +1,7 @@
1
1
  require 'uri'
2
2
 
3
3
  require 'baykit/bayserver/agent/grand_agent'
4
+ require 'baykit/bayserver/agent/lifecycle_listener'
4
5
  require 'baykit/bayserver/docker/base/club_base'
5
6
  require 'baykit/bayserver/docker/warp/warp_data'
6
7
  require 'baykit/bayserver/docker/warp/warp_data_listener'
@@ -19,7 +20,7 @@ module Baykit
19
20
  include Baykit::BayServer::Docker::Warp
20
21
 
21
22
  class AgentListener
22
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener
23
+ include Baykit::BayServer::Agent::LifecycleListener
23
24
 
24
25
  attr :warp_docker
25
26
 
@@ -18,7 +18,7 @@ module Baykit
18
18
  attr_accessor :connected
19
19
  attr :socket_timeout_sec
20
20
  attr :lock
21
-
21
+ attr :cmd_buf
22
22
 
23
23
  def initialize()
24
24
  super
@@ -27,12 +27,17 @@ module Baykit
27
27
  @tour_map = {}
28
28
  @lock = Mutex.new()
29
29
  @connected = false
30
+ @cmd_buf = []
30
31
  end
31
32
 
32
33
  def to_s()
33
34
  return "warp##{@ship_id}/#{@object_id}[#{protocol}]"
34
35
  end
35
36
 
37
+ def inspect
38
+ to_s
39
+ end
40
+
36
41
  ######################################################
37
42
  # Implements Reusable
38
43
  ######################################################
@@ -43,6 +48,8 @@ module Baykit
43
48
  BayLog.error("BUG: Some tours is active: %s", @tour_map)
44
49
  end
45
50
  @connected = false
51
+ @tour_map = {}
52
+ @cmd_buf = []
46
53
  end
47
54
 
48
55
 
@@ -129,6 +136,8 @@ module Baykit
129
136
  rescue Exception => e
130
137
  BayLog.error_e(e)
131
138
  end
139
+ else
140
+ tur.res.end_content(Tour::TOUR_ID_NOCHECK)
132
141
  end
133
142
  end
134
143
  @tour_map.clear
@@ -161,8 +170,28 @@ module Baykit
161
170
  return timeout
162
171
  end
163
172
 
164
- def inspect
165
- to_s
173
+ def post(cmd, listener=nil)
174
+ if !@connected
175
+ @cmd_buf << [cmd, listener]
176
+ else
177
+ if cmd == nil
178
+ listener.call()
179
+ else
180
+ @protocol_handler.command_packer.post(self, cmd, &listener)
181
+ end
182
+ end
183
+ end
184
+ def flush()
185
+ @cmd_buf.each do | cmd_and_lis |
186
+ cmd = cmd_and_lis[0]
187
+ lis = cmd_and_lis[1]
188
+ if cmd == nil
189
+ lis.call()
190
+ else
191
+ @protocol_handler.command_packer.post(self, cmd, &lis)
192
+ end
193
+ end
194
+ @cmd_buf = []
166
195
  end
167
196
  end
168
197
  end
@@ -1,5 +1,6 @@
1
1
  require 'baykit/bayserver/bayserver'
2
2
  require 'baykit/bayserver/agent/grand_agent'
3
+ require 'baykit/bayserver/agent/lifecycle_listener'
3
4
  require 'baykit/bayserver/protocol/protocol_handler_store'
4
5
  require 'baykit/bayserver/protocol/packet_store'
5
6
  require 'baykit/bayserver/tours/tour_store'
@@ -20,7 +21,7 @@ module Baykit
20
21
  include Baykit::BayServer::Util
21
22
 
22
23
  class AgentListener
23
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener
24
+ include Baykit::BayServer::Agent::LifecycleListener
24
25
 
25
26
  def add(agt)
26
27
  MemUsage.mem_usages[agt.agent_id] = MemUsage.new(agt.agent_id);
@@ -1,4 +1,5 @@
1
1
  require 'baykit/bayserver/agent/grand_agent'
2
+ require 'baykit/bayserver/agent/lifecycle_listener'
2
3
  require 'baykit/bayserver/util/object_store'
3
4
  require 'baykit/bayserver/protocol/packet_factory'
4
5
 
@@ -12,7 +13,7 @@ module Baykit
12
13
  include Baykit::BayServer::Util
13
14
 
14
15
  class AgentListener
15
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener # implements
16
+ include Baykit::BayServer::Agent::LifecycleListener # implements
16
17
 
17
18
  def add(agt)
18
19
  PacketStore.proto_map.values().each do |ifo|
@@ -1,4 +1,5 @@
1
1
  require 'baykit/bayserver/agent/grand_agent'
2
+ require 'baykit/bayserver/agent/lifecycle_listener'
2
3
  require 'baykit/bayserver/util/object_store'
3
4
  require 'baykit/bayserver/util/string_util'
4
5
 
@@ -10,7 +11,7 @@ module Baykit
10
11
  include Baykit::BayServer::Util
11
12
 
12
13
  class AgentListener
13
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener # implements
14
+ include Baykit::BayServer::Agent::LifecycleListener # implements
14
15
 
15
16
  def add(agt)
16
17
  ProtocolHandlerStore.proto_map.values().each {|ifo| ifo.add_agent(agt) }
@@ -1,23 +1,97 @@
1
+ require 'baykit/bayserver/bayserver'
2
+ require 'baykit/bayserver/agent/grand_agent'
3
+ require 'baykit/bayserver/agent/lifecycle_listener'
1
4
  require 'baykit/bayserver/util/executor_service'
5
+ require 'baykit/bayserver/sink'
2
6
 
3
7
  module Baykit
4
8
  module BayServer
5
9
  module Taxi
6
10
  class TaxiRunner
11
+ include Baykit::BayServer
12
+ include Baykit::BayServer::Agent
7
13
  include Baykit::BayServer::Util
8
14
 
15
+ class AgentListener
16
+ include Baykit::BayServer::Agent::LifecycleListener # implements
17
+
18
+ def add(agt)
19
+ TaxiRunner.runners[agt.agent_id - 1] = TaxiRunner.new(agt)
20
+ end
21
+
22
+ def remove(agt)
23
+ TaxiRunner.runners[agt.agent_id - 1].terminate()
24
+ TaxiRunner.runners[agt.agent_id - 1] = nil
25
+ end
26
+ end
27
+
28
+
9
29
  # define class instance accessor
10
30
  class << self
11
- attr :exe
31
+ attr :max_taxis
32
+ attr :runners
33
+ end
34
+
35
+ attr :agent
36
+ attr :exe
37
+ attr :running_taxis
38
+ attr :lock
39
+
40
+ def initialize(agt)
41
+ @agent = agt
42
+ @exe = ExecutorService.new("TaxiRunner", TaxiRunner.max_taxis)
43
+ @agent.add_timer_handler(self)
44
+ @running_taxis = []
45
+ @lock = Monitor.new()
12
46
  end
13
47
 
14
- def TaxiRunner.init(num_agents)
15
- @exe = ExecutorService.new("TaxiRunner", num_agents)
48
+ ######################################################
49
+ # Implements TimerHandler
50
+ ######################################################
51
+
52
+ def on_timer()
53
+ @lock.synchronize do
54
+ @running_taxis.each do |txi|
55
+ txi.on_timer()
56
+ end
57
+ end
58
+ end
59
+
60
+ ######################################################
61
+ # Custom methods
62
+ ######################################################
63
+
64
+ def terminate()
65
+ @agent.remove_timer_handler(self)
66
+ end
67
+
68
+ def submit(txi)
69
+ @lock.synchronize do
70
+ @running_taxis << txi
71
+ end
72
+ @exe.submit(txi)
73
+ @lock.synchronize do
74
+ @running_taxis.delete(txi)
75
+ end
76
+ end
77
+
78
+ ######################################################
79
+ # Class methods
80
+ ######################################################
81
+
82
+ def TaxiRunner.init(max_taxis)
83
+ if(max_taxis <= 0)
84
+ raise Sink.new()
85
+ end
86
+ @max_taxis = max_taxis
87
+ @runners = []
88
+ GrandAgent.add_lifecycle_listener(AgentListener.new())
16
89
  end
17
90
 
18
- def TaxiRunner.post(taxi)
91
+ def TaxiRunner.post(agt_id, txi)
92
+ BayLog.debug("agt#%d post taxi: thread=%s taxi=%s", agt_id, Thread.current.name, txi);
19
93
  begin
20
- @exe.submit(taxi)
94
+ @runners[agt_id - 1].submit(txi)
21
95
  return true
22
96
  rescue => e
23
97
  BayLog.error_e(e)
@@ -23,12 +23,14 @@ module Baykit
23
23
  attr :buf_size
24
24
  attr :running
25
25
  attr :lock
26
+ attr :agent_id
26
27
 
27
- def initialize(buf_size)
28
+ def initialize(agt_id, buf_size)
28
29
  super()
29
30
  @buf_size = buf_size
30
31
  @buf = StringUtil.alloc(buf_size)
31
32
  @lock = Monitor.new()
33
+ @agent_id = agt_id
32
34
  end
33
35
 
34
36
  def to_s()
@@ -88,7 +90,7 @@ module Baykit
88
90
  return
89
91
  end
90
92
  @running = true
91
- TaxiRunner.post(self)
93
+ TaxiRunner.post(@agent_id, self)
92
94
  end
93
95
 
94
96
  def close()
@@ -124,12 +124,15 @@ module Baykit
124
124
  begin
125
125
  city.enter(self)
126
126
  rescue Sink => e
127
+ change_state(TOUR_ID_NOCHECK, TourState::ABORTED)
127
128
  raise e
128
129
  rescue HttpException => e
129
130
  BayLog.error_e(e)
131
+ change_state(TOUR_ID_NOCHECK, TourState::ABORTED)
130
132
  raise e
131
133
  rescue => e
132
134
  BayLog.error_e(e)
135
+ change_state(TOUR_ID_NOCHECK, TourState::ABORTED)
133
136
  raise HttpException.new(HttpStatus::INTERNAL_SERVER_ERROR, e.message)
134
137
  end
135
138
  end
@@ -155,6 +158,10 @@ module Baykit
155
158
  return @state == TourState::ABORTED
156
159
  end
157
160
 
161
+ def ended?()
162
+ return @state == TourState::ENDED
163
+ end
164
+
158
165
  def initialized?()
159
166
  return state != TourState::UNINITIALIZED
160
167
  end
@@ -125,34 +125,33 @@ module Baykit
125
125
  def post_content(check_id, data, start, len)
126
126
  @tour.check_tour_id(check_id)
127
127
 
128
+ data_passed = false
128
129
  if !@tour.running?
129
130
  BayLog.debug("%s tour is not running.", @tour)
130
- return true
131
- end
132
131
 
133
- if @content_handler == nil
132
+ elsif @content_handler == nil
134
133
  BayLog.warn("%s content read, but no content handler", tour)
135
- return true
136
- end
137
134
 
138
- if @consume_listener == nil
135
+ elsif @consume_listener == nil
139
136
  raise Sink.new("Request consume listener is null")
140
- end
141
137
 
142
- if @bytes_posted + len > @bytes_limit
138
+ elsif @bytes_posted + len > @bytes_limit
143
139
  raise ProtocolException.new("Read data exceed content-length: %d/%d", @bytes_posted + len, @bytes_limit)
144
- end
145
140
 
146
- # If has error, only read content. (Do not call content handler)
147
- if @tour.error == nil
141
+ elsif @tour.error != nil
142
+ # If has error, only read content. (Do not call content handler)
143
+ BayLog.debug("%s tour has error.", @tour)
144
+
145
+ else
148
146
  @content_handler.on_read_content(@tour, data, start, len)
147
+ data_passed = true
149
148
  end
150
- @bytes_posted += len
151
149
 
150
+ @bytes_posted += len
152
151
  BayLog.debug("%s read content: len=%d posted=%d limit=%d consumed=%d",
153
152
  @tour, len, @bytes_posted, @bytes_limit, @bytes_consumed)
154
153
 
155
- if @tour.error == nil
154
+ if !data_passed
156
155
  return true
157
156
  end
158
157
 
@@ -47,11 +47,13 @@ module Baykit
47
47
  attr :bytes_consumed
48
48
  attr :bytes_limit
49
49
  attr :buffer_size
50
+ attr :tour_returned
50
51
 
51
52
  def initialize(tur)
52
53
  @headers = Headers.new()
53
54
  @tour = tur
54
55
  @buffer_size = BayServer.harbor.tour_buffer_size
56
+ @tour_returned = false
55
57
  end
56
58
 
57
59
  def init()
@@ -82,6 +84,7 @@ module Baykit
82
84
  @bytes_posted = 0
83
85
  @bytes_consumed = 0
84
86
  @bytes_limit = 0
87
+ @tour_returned = false
85
88
  end
86
89
 
87
90
  ######################################################
@@ -121,8 +124,16 @@ module Baykit
121
124
  end
122
125
  end
123
126
 
124
- @tour.ship.send_headers(@tour.ship_id, @tour)
125
- @header_sent = true
127
+ begin
128
+ @tour.ship.send_headers(@tour.ship_id, @tour)
129
+ rescue IOError => e
130
+ BayLog.debug_e(e, "%s abort: %s", @tour, e)
131
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
132
+ raise e
133
+ ensure
134
+ @header_sent = true
135
+ end
136
+
126
137
  end
127
138
 
128
139
  def send_redirect(chk_tour_id, status, location)
@@ -132,9 +143,15 @@ module Baykit
132
143
  BayLog.error("Try to redirect after response header is sent (Ignore)")
133
144
  else
134
145
  set_consume_listener(&ContentConsumeListener::DEV_NULL)
135
- @tour.ship.send_redirect(@tour.ship_id, @tour, status, location)
136
- @header_sent = true
137
- end_content(chk_tour_id)
146
+ begin
147
+ @tour.ship.send_redirect(@tour.ship_id, @tour, status, location)
148
+ rescue IOError => e
149
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
150
+ raise e
151
+ ensure
152
+ @header_sent = true
153
+ end_content(chk_tour_id)
154
+ end
138
155
  end
139
156
 
140
157
  end
@@ -176,14 +193,21 @@ module Baykit
176
193
  raise ProtocolException.new("Post data exceed content-length: " + @bytes_posted + "/" + @bytes_limit)
177
194
  end
178
195
 
179
- if @can_compress
180
- get_compressor().compress(buf, ofs, len, &done_lis)
196
+ if @tour.zombie? || @tour.aborted?
197
+ # Don't send peer any data
198
+ BayLog::debug("%s Aborted or zombie tour. do nothing: %s state=%s", self, @tour, @tour.state)
199
+ done_lis.call()
181
200
  else
182
- begin
183
- @tour.ship.send_res_content(@tour.ship_id, @tour, buf, ofs, len, &done_lis)
184
- rescue IOError => e
185
- done_lis.call()
186
- raise e
201
+ if @can_compress
202
+ get_compressor().compress(buf, ofs, len, &done_lis)
203
+ else
204
+ begin
205
+ @tour.ship.send_res_content(@tour.ship_id, @tour, buf, ofs, len, &done_lis)
206
+ rescue IOError => e
207
+ done_lis.call()
208
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
209
+ raise e
210
+ end
187
211
  end
188
212
  end
189
213
 
@@ -208,6 +232,10 @@ module Baykit
208
232
  @tour.check_tour_id(chk_tour_id)
209
233
 
210
234
  BayLog.debug("%s end ResContent", self)
235
+ if @tour.ended?
236
+ BayLog.debug("%s Tour is already ended (Ignore).", self)
237
+ return
238
+ end
211
239
 
212
240
  if !@tour.zombie? && @tour.city != nil
213
241
  @tour.city.log(@tour)
@@ -221,14 +249,31 @@ module Baykit
221
249
 
222
250
  # Done listener
223
251
  done_lis = Proc.new() do
252
+ @tour.check_tour_id(chk_tour_id)
224
253
  @tour.ship.return_tour(@tour)
254
+ @tour_returned = true
225
255
  end
226
256
 
227
257
  begin
228
- @tour.ship.send_end_tour(@tour.ship_id, @tour, &done_lis)
229
- rescue IOError => e
230
- done_lis.call()
231
- raise e
258
+ if @tour.zombie? || @tour.aborted?
259
+ # Don't send peer any data. Do nothing
260
+ BayLog.debug("%s Aborted or zombie tour. do nothing: %s state=%s", self, @tour, @tour.state)
261
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ENDED)
262
+ done_lis.call()
263
+ else
264
+ begin
265
+ @tour.ship.send_end_tour(@tour.ship_id, @tour, &done_lis)
266
+ rescue IOError => e
267
+ BayLog.debug("%s Error on sending end tour", self)
268
+ done_lis.call()
269
+ raise e
270
+ end
271
+ end
272
+ ensure
273
+ BayLog.debug("%s Tour is returned: %s", self, @tour_returned)
274
+ if !@tour_returned
275
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ENDED)
276
+ end
232
277
  end
233
278
  end
234
279
 
@@ -288,8 +333,19 @@ module Baykit
288
333
  end
289
334
  else
290
335
  set_consume_listener(&ContentConsumeListener::DEV_NULL)
291
- @tour.ship.send_error(@tour.ship_id, @tour, status, msg, err)
292
- @header_sent = true
336
+
337
+ if @tour.zombie? || @tour.aborted?
338
+ # Don't send peer any data. Do nothing
339
+ BayLog.debug("%s Aborted or zombie tour. do nothing: %s state=%s", self, @tour, @tour.state)
340
+ else
341
+ begin
342
+ @tour.ship.send_error(@tour.ship_id, @tour, status, msg, err)
343
+ rescue IOError => e
344
+ BayLog.debug("%s Error on sending end tour", self)
345
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
346
+ end
347
+ @header_sent = true
348
+ end
293
349
  end
294
350
 
295
351
  end_content(chk_tour_id)
@@ -306,7 +362,7 @@ module Baykit
306
362
 
307
363
  if File.directory?(file)
308
364
  raise HttpException.new HttpStatus::FORBIDDEN, file
309
- elsif !File.exists?(file)
365
+ elsif !File.exist?(file)
310
366
  raise HttpException.new HttpStatus::NOT_FOUND, file
311
367
  end
312
368
 
@@ -357,11 +413,11 @@ module Baykit
357
413
  tp.open_valve()
358
414
 
359
415
  when Harbor::FILE_SEND_METHOD_TAXI
360
- txi = ReadFileTaxi.new(bufsize)
416
+ txi = ReadFileTaxi.new(@tour.ship.agent.agent_id, bufsize)
361
417
  @yacht.init(@tour, file, txi)
362
418
  txi.init(File.open(file, "rb"), @yacht)
363
- if !TaxiRunner.post(txi)
364
- raise HttpException.new(HttpStatus.SERVICE_UNAVAILABLE, "Taxi is busy!");
419
+ if !TaxiRunner.post(@tour.ship.agent.agent_id, txi)
420
+ raise HttpException.new(HttpStatus::SERVICE_UNAVAILABLE, "Taxi is busy!");
365
421
  end
366
422
 
367
423
  else
@@ -382,9 +438,18 @@ module Baykit
382
438
 
383
439
  def get_compressor()
384
440
  if @compressor == nil
385
- @compressor = GzipCompressor.new(lambda do |new_buf, new_ofs, new_len, &lis|
386
- @tour.ship.send_res_content(@tour.ship_id, @tour, new_buf, new_ofs, new_len, &lis)
387
- end)
441
+ sip_id = @tour.ship.ship_id
442
+ tur_id = @tour.tour_id
443
+ gz_callback = lambda do |new_buf, new_ofs, new_len, &lis|
444
+ begin
445
+ @tour.ship.send_res_content(sip_id, @tour, new_buf, new_ofs, new_len, &lis)
446
+ rescue IOError => e
447
+ @tour.change_state(tur_id, Tour::TourState::ABORTED)
448
+ raise e
449
+ end
450
+ end
451
+
452
+ @compressor = GzipCompressor.new(gz_callback)
388
453
  end
389
454
 
390
455
  return @compressor
@@ -1,4 +1,5 @@
1
1
  require 'baykit/bayserver/agent/grand_agent'
2
+ require 'baykit/bayserver/agent/lifecycle_listener'
2
3
  require 'baykit/bayserver/tours/tour'
3
4
  require 'baykit/bayserver/util/string_util'
4
5
 
@@ -15,7 +16,7 @@ module Baykit
15
16
 
16
17
 
17
18
  class AgentListener
18
- include Baykit::BayServer::Agent::GrandAgent::GrandAgentLifecycleListener # implements
19
+ include Baykit::BayServer::Agent::LifecycleListener # implements
19
20
 
20
21
  def add(agt)
21
22
  TourStore.stores[agt.agent_id] = TourStore.new();
@@ -23,9 +23,9 @@ module Baykit
23
23
  def run
24
24
  while true
25
25
  tsk = @que.deq
26
- #BayLog.debug("%s Start task on: %s", tsk, @name)
26
+ BayLog.debug("%s Start task on: %s", tsk, @name)
27
27
  tsk.run
28
- #BayLog.debug("%s End task on: %s", tsk, @name)
28
+ BayLog.debug("%s End task on: %s", tsk, @name)
29
29
  end
30
30
  end
31
31
 
@@ -1,7 +1,7 @@
1
1
  module Baykit
2
2
  module BayServer
3
3
  class Version
4
- VERSION='2.2.2'
4
+ VERSION='2.3.0'
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bayserver-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michisuke-P
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-30 00:00:00.000000000 Z
11
+ date: 2023-11-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: BayServer is one of the high-speed web servers. It operates as a single-threaded,
14
14
  asynchronous server, which makes it exceptionally fast. It also supports multi-core
@@ -25,6 +25,7 @@ files:
25
25
  - lib/baykit/bayserver/agent/command_receiver.rb
26
26
  - lib/baykit/bayserver/agent/grand_agent.rb
27
27
  - lib/baykit/bayserver/agent/grand_agent_monitor.rb
28
+ - lib/baykit/bayserver/agent/lifecycle_listener.rb
28
29
  - lib/baykit/bayserver/agent/next_socket_action.rb
29
30
  - lib/baykit/bayserver/agent/non_blocking_handler.rb
30
31
  - lib/baykit/bayserver/agent/package.rb
@@ -32,6 +33,7 @@ files:
32
33
  - lib/baykit/bayserver/agent/signal/signal_proxy.rb
33
34
  - lib/baykit/bayserver/agent/signal/signal_sender.rb
34
35
  - lib/baykit/bayserver/agent/spin_handler.rb
36
+ - lib/baykit/bayserver/agent/timer_handler.rb
35
37
  - lib/baykit/bayserver/agent/transporter/data_listener.rb
36
38
  - lib/baykit/bayserver/agent/transporter/package.rb
37
39
  - lib/baykit/bayserver/agent/transporter/plain_transporter.rb