bayserver-core 2.2.2 → 2.3.1

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/baykit/bayserver/agent/command_receiver.rb +1 -1
  3. data/lib/baykit/bayserver/agent/grand_agent.rb +89 -76
  4. data/lib/baykit/bayserver/agent/grand_agent_monitor.rb +1 -0
  5. data/lib/baykit/bayserver/agent/lifecycle_listener.rb +16 -0
  6. data/lib/baykit/bayserver/agent/non_blocking_handler.rb +37 -8
  7. data/lib/baykit/bayserver/agent/signal/signal_sender.rb +1 -0
  8. data/lib/baykit/bayserver/agent/spin_handler.rb +16 -0
  9. data/lib/baykit/bayserver/agent/timer_handler.rb +15 -0
  10. data/lib/baykit/bayserver/docker/base/inbound_ship.rb +20 -51
  11. data/lib/baykit/bayserver/docker/base/inbound_ship_store.rb +2 -1
  12. data/lib/baykit/bayserver/docker/built_in/built_in_log_docker.rb +3 -2
  13. data/lib/baykit/bayserver/docker/built_in/write_file_taxi.rb +8 -2
  14. data/lib/baykit/bayserver/docker/warp/warp_data.rb +8 -0
  15. data/lib/baykit/bayserver/docker/warp/warp_data_listener.rb +9 -9
  16. data/lib/baykit/bayserver/docker/warp/warp_docker.rb +2 -1
  17. data/lib/baykit/bayserver/docker/warp/warp_ship.rb +32 -3
  18. data/lib/baykit/bayserver/mem_usage.rb +2 -1
  19. data/lib/baykit/bayserver/protocol/packet_store.rb +2 -1
  20. data/lib/baykit/bayserver/protocol/protocol_handler_store.rb +2 -1
  21. data/lib/baykit/bayserver/taxi/taxi.rb +1 -0
  22. data/lib/baykit/bayserver/taxi/taxi_runner.rb +94 -5
  23. data/lib/baykit/bayserver/tours/read_file_taxi.rb +46 -23
  24. data/lib/baykit/bayserver/tours/send_file_yacht.rb +5 -1
  25. data/lib/baykit/bayserver/tours/tour.rb +5 -6
  26. data/lib/baykit/bayserver/tours/tour_req.rb +28 -28
  27. data/lib/baykit/bayserver/tours/tour_res.rb +93 -31
  28. data/lib/baykit/bayserver/tours/tour_store.rb +2 -1
  29. data/lib/baykit/bayserver/util/executor_service.rb +27 -10
  30. data/lib/baykit/bayserver/version.rb +1 -1
  31. metadata +4 -2
@@ -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
@@ -66,17 +66,17 @@ module Baykit
66
66
  tur = pair[1]
67
67
  tur.check_tour_id pair[0]
68
68
 
69
- if !tur.res.header_sent
70
- BayLog.error("%s Send ServiceUnavailable: tur=%s", self, tur);
71
- tur.res.send_error(Tour::TOUR_ID_NOCHECK, HttpStatus::SERVICE_UNAVAILABLE, "Server closed on reading headers")
72
- else
73
- # NOT treat EOF as Error
74
- BayLog.debug("%s EOF is not an error: tur=%s", self, tur);
75
- begin
69
+ begin
70
+ if !tur.res.header_sent
71
+ BayLog.debug("%s Send ServiceUnavailable: tur=%s", self, tur)
72
+ tur.res.send_error(Tour::TOUR_ID_NOCHECK, HttpStatus::SERVICE_UNAVAILABLE, "Server closed on reading headers")
73
+ else
74
+ # NOT treat EOF as Error
75
+ BayLog.debug("%s EOF is not an error: tur=%s", self, tur)
76
76
  tur.res.end_content(Tour::TOUR_ID_NOCHECK)
77
- rescue IOError => e
78
- BayLog::debug_e(e, "%s end content error: tur=%s", self, tur);
79
77
  end
78
+ rescue IOError => e
79
+ BayLog::debug_e(e)
80
80
  end
81
81
  end
82
82
 
@@ -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) }
@@ -8,6 +8,7 @@ module Baykit
8
8
  # abstract method
9
9
  #
10
10
  # depart()
11
+ # on_timer()
11
12
  #
12
13
 
13
14
  class << self
@@ -1,23 +1,112 @@
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()
46
+ end
47
+
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
+ @exe.shutdown
67
+ end
68
+
69
+ def submit(txi)
70
+ @exe.submit() do
71
+ if @agent.aborted
72
+ BayLog.error("Agent is aborted")
73
+ return
74
+ end
75
+
76
+ @lock.synchronize do
77
+ @running_taxis << txi
78
+ end
79
+
80
+ begin
81
+ txi.run()
82
+ rescue => e
83
+ BayLog.fatal_e(e)
84
+ @agent.req_shutdown
85
+ ensure
86
+ @lock.synchronize do
87
+ @running_taxis.delete(txi)
88
+ end
89
+ end
90
+ end
12
91
  end
13
92
 
14
- def TaxiRunner.init(num_agents)
15
- @exe = ExecutorService.new("TaxiRunner", num_agents)
93
+ ######################################################
94
+ # Class methods
95
+ ######################################################
96
+
97
+ def TaxiRunner.init(max_taxis)
98
+ if(max_taxis <= 0)
99
+ raise Sink.new()
100
+ end
101
+ @max_taxis = max_taxis
102
+ @runners = []
103
+ GrandAgent.add_lifecycle_listener(AgentListener.new())
16
104
  end
17
105
 
18
- def TaxiRunner.post(taxi)
106
+ def TaxiRunner.post(agt_id, txi)
107
+ BayLog.debug("agt#%d post taxi: thread=%s taxi=%s", agt_id, Thread.current.name, txi);
19
108
  begin
20
- @exe.submit(taxi)
109
+ @runners[agt_id - 1].submit(txi)
21
110
  return true
22
111
  rescue => e
23
112
  BayLog.error_e(e)
@@ -23,12 +23,15 @@ module Baykit
23
23
  attr :buf_size
24
24
  attr :running
25
25
  attr :lock
26
+ attr :agent_id
27
+ attr :start_time
26
28
 
27
- def initialize(buf_size)
29
+ def initialize(agt_id, buf_size)
28
30
  super()
29
31
  @buf_size = buf_size
30
32
  @buf = StringUtil.alloc(buf_size)
31
33
  @lock = Monitor.new()
34
+ @agent_id = agt_id
32
35
  end
33
36
 
34
37
  def to_s()
@@ -56,28 +59,36 @@ module Baykit
56
59
  ######################################################
57
60
 
58
61
  def depart()
59
- @lock.synchronize do
60
- begin
61
- @buf.clear()
62
- @infile.read(@buf_size, @buf)
63
-
64
- if @buf.length == 0
65
- @data_listener.notify_eof()
66
- close()
67
- return
68
- end
62
+ @start_time = Time.now.to_i
63
+ begin
64
+ @buf.clear()
65
+ @infile.read(@buf_size, @buf)
69
66
 
70
- act = @data_listener.notify_read(@buf, nil)
67
+ if @buf.length == 0
68
+ close()
69
+ return
70
+ end
71
71
 
72
- @running = false
73
- if act == NextSocketAction::CONTINUE
74
- next_run()
75
- end
72
+ act = @data_listener.notify_read(@buf, nil)
76
73
 
77
- rescue Exception => e
78
- BayLog.error_e(e)
79
- close()
74
+ @running = false
75
+ if act == NextSocketAction::CONTINUE
76
+ next_run()
80
77
  end
78
+
79
+ rescue IOError => e
80
+ BayLog.debug_e(e)
81
+ close()
82
+ rescue Exception => e
83
+ close()
84
+ raise e
85
+ end
86
+ end
87
+
88
+ def on_timer()
89
+ duration_sec = Time.now.to_i - @start_time
90
+ if (@data_listener.check_timeout(duration_sec))
91
+ close()
81
92
  end
82
93
  end
83
94
 
@@ -88,13 +99,25 @@ module Baykit
88
99
  return
89
100
  end
90
101
  @running = true
91
- TaxiRunner.post(self)
102
+ TaxiRunner.post(@agent_id, self)
92
103
  end
93
104
 
94
105
  def close()
95
- @ch_valid = false
96
- @infile.close()
97
- @data_listener.notify_close()
106
+ @lock.synchronize do
107
+ if !@ch_valid
108
+ return
109
+ end
110
+
111
+ @ch_valid = false
112
+ @data_listener.notify_eof()
113
+
114
+ begin
115
+ @infile.close()
116
+ rescue IOError => e
117
+ end
118
+
119
+ @data_listener.notify_close()
120
+ end
98
121
  end
99
122
  end
100
123
  end
@@ -57,7 +57,11 @@ module Baykit
57
57
 
58
58
  def notify_eof()
59
59
  BayLog.trace("%s EOF(^o^) %s", self, @file_name)
60
- @tour.res.end_content(@tour_id)
60
+ begin
61
+ @tour.res.end_content(@tour_id)
62
+ rescue IOError => e
63
+ BayLog.debug_e(e)
64
+ end
61
65
  return NextSocketAction::CLOSE
62
66
  end
63
67
 
@@ -123,14 +123,9 @@ module Baykit
123
123
  else
124
124
  begin
125
125
  city.enter(self)
126
- rescue Sink => e
127
- raise e
128
126
  rescue HttpException => e
129
- BayLog.error_e(e)
127
+ change_state(TOUR_ID_NOCHECK, TourState::ABORTED)
130
128
  raise e
131
- rescue => e
132
- BayLog.error_e(e)
133
- raise HttpException.new(HttpStatus::INTERNAL_SERVER_ERROR, e.message)
134
129
  end
135
130
  end
136
131
  end
@@ -155,6 +150,10 @@ module Baykit
155
150
  return @state == TourState::ABORTED
156
151
  end
157
152
 
153
+ def ended?()
154
+ return @state == TourState::ENDED
155
+ end
156
+
158
157
  def initialized?()
159
158
  return state != TourState::UNINITIALIZED
160
159
  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
 
@@ -209,26 +208,27 @@ module Baykit
209
208
  end
210
209
 
211
210
  def abort()
212
- if !@tour.preparing?
213
- BayLog.debug("%s cannot abort non-preparing tour", @tour)
214
- return false
215
- end
216
-
217
211
  BayLog.debug("%s abort", @tour)
218
- if @tour.aborted?
219
- raise Sink.new("tour has already aborted")
220
- end
212
+ if @tour.preparing?
213
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
214
+ return true
221
215
 
222
- aborted = true
223
- if @tour.running? && @content_handler != nil
224
- aborted = @content_handler.on_abort(@tour)
225
- end
216
+ elsif @tour.running?
217
+ aborted = true
218
+ if @content_handler != nil
219
+ aborted = @content_handler.on_abort(@tour)
220
+ end
226
221
 
227
- if aborted
228
- @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
222
+ if aborted
223
+ @tour.change_state(Tour::TOUR_ID_NOCHECK, Tour::TourState::ABORTED)
224
+ end
225
+
226
+ return aborted
227
+ else
228
+ BayLog.debug("%s tour is not preparing or not running", @tour)
229
+ return false
229
230
  end
230
231
 
231
- return aborted
232
232
  end
233
233
 
234
234
  def set_content_handler(hnd)