bayserver-core 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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