bayserver-core 2.2.2 → 2.3.1

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