bayserver-core 3.0.3 → 3.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/lib/baykit/bayserver/agent/command_receiver.rb +2 -0
  3. data/lib/baykit/bayserver/agent/grand_agent.rb +101 -93
  4. data/lib/baykit/bayserver/agent/letters/accepted_letter.rb +2 -2
  5. data/lib/baykit/bayserver/agent/letters/closed_letter.rb +2 -2
  6. data/lib/baykit/bayserver/agent/letters/connected_letter.rb +2 -2
  7. data/lib/baykit/bayserver/agent/letters/error_letter.rb +2 -2
  8. data/lib/baykit/bayserver/agent/letters/letter.rb +7 -3
  9. data/lib/baykit/bayserver/agent/letters/read_letter.rb +2 -2
  10. data/lib/baykit/bayserver/agent/letters/wrote_letter.rb +2 -2
  11. data/lib/baykit/bayserver/agent/monitor/grand_agent_monitor.rb +20 -22
  12. data/lib/baykit/bayserver/agent/multiplexer/job_multiplexer.rb +44 -31
  13. data/lib/baykit/bayserver/agent/multiplexer/job_multiplexer_base.rb +5 -0
  14. data/lib/baykit/bayserver/agent/multiplexer/multiplexer_base.rb +4 -4
  15. data/lib/baykit/bayserver/agent/multiplexer/plain_transporter.rb +2 -3
  16. data/lib/baykit/bayserver/agent/multiplexer/spider_multiplexer.rb +113 -59
  17. data/lib/baykit/bayserver/agent/multiplexer/spin_multiplexer.rb +22 -17
  18. data/lib/baykit/bayserver/agent/multiplexer/taxi_multiplexer.rb +17 -13
  19. data/lib/baykit/bayserver/bay_log.rb +20 -16
  20. data/lib/baykit/bayserver/bayserver.rb +8 -15
  21. data/lib/baykit/bayserver/common/cities.rb +1 -1
  22. data/lib/baykit/bayserver/common/inbound_ship.rb +1 -1
  23. data/lib/baykit/bayserver/common/inbound_ship_store.rb +0 -1
  24. data/lib/baykit/bayserver/{agent/multiplexer → common}/rudder_state.rb +43 -7
  25. data/lib/baykit/bayserver/common/rudder_state_store.rb +63 -0
  26. data/lib/baykit/bayserver/{agent/multiplexer → common}/transporter.rb +1 -3
  27. data/lib/baykit/bayserver/common/warp_ship.rb +4 -3
  28. data/lib/baykit/bayserver/{agent/multiplexer → common}/write_unit.rb +1 -3
  29. data/lib/baykit/bayserver/docker/base/inbound_data_listener.rb +0 -1
  30. data/lib/baykit/bayserver/docker/base/port_base.rb +5 -5
  31. data/lib/baykit/bayserver/docker/base/warp_base.rb +7 -4
  32. data/lib/baykit/bayserver/docker/built_in/built_in_harbor_docker.rb +25 -2
  33. data/lib/baykit/bayserver/docker/built_in/built_in_log_docker.rb +42 -26
  34. data/lib/baykit/bayserver/docker/harbor.rb +14 -0
  35. data/lib/baykit/bayserver/docker/send_file/file_content.rb +66 -0
  36. data/lib/baykit/bayserver/docker/send_file/file_content_handler.rb +113 -29
  37. data/lib/baykit/bayserver/docker/send_file/file_store.rb +117 -0
  38. data/lib/baykit/bayserver/docker/send_file/send_file_docker.rb +13 -5
  39. data/lib/baykit/bayserver/docker/send_file/send_file_ship.rb +11 -2
  40. data/lib/baykit/bayserver/docker/send_file/wait_file_ship.rb +92 -0
  41. data/lib/baykit/bayserver/mem_usage.rb +2 -0
  42. data/lib/baykit/bayserver/protocol/packet.rb +2 -1
  43. data/lib/baykit/bayserver/protocol/packet_part_accessor.rb +5 -5
  44. data/lib/baykit/bayserver/protocol/protocol_exception.rb +7 -1
  45. data/lib/baykit/bayserver/rudders/io_rudder.rb +2 -2
  46. data/lib/baykit/bayserver/rudders/rudder.rb +4 -0
  47. data/lib/baykit/bayserver/rudders/rudder_base.rb +21 -0
  48. data/lib/baykit/bayserver/tours/req_content_handler.rb +13 -13
  49. data/lib/baykit/bayserver/tours/tour.rb +1 -6
  50. data/lib/baykit/bayserver/tours/tour_req.rb +4 -8
  51. data/lib/baykit/bayserver/tours/tour_res.rb +1 -8
  52. data/lib/baykit/bayserver/util/cgi_util.rb +7 -2
  53. data/lib/baykit/bayserver/util/headers.rb +2 -2
  54. data/lib/baykit/bayserver/util/http_status.rb +7 -0
  55. data/lib/baykit/bayserver/util/http_util.rb +16 -0
  56. data/lib/baykit/bayserver/util/nio_selector.rb +103 -0
  57. data/lib/baykit/bayserver/util/rb_selector.rb +55 -0
  58. data/lib/baykit/bayserver/util/selector.rb +43 -80
  59. data/lib/baykit/bayserver/util/simple_buffer.rb +1 -1
  60. data/lib/baykit/bayserver/version.rb +1 -1
  61. metadata +16 -20
  62. data/lib/baykit/bayserver/agent/accept_handler.rb +0 -71
  63. data/lib/baykit/bayserver/agent/channel_listener.rb +0 -35
  64. data/lib/baykit/bayserver/agent/transporter/data_listener.rb +0 -38
  65. data/lib/baykit/bayserver/agent/transporter/package.rb +0 -0
  66. data/lib/baykit/bayserver/agent/transporter/spin_read_transporter.rb +0 -111
  67. data/lib/baykit/bayserver/agent/transporter/spin_write_transporter.rb +0 -125
  68. data/lib/baykit/bayserver/agent/transporter/transporter.rb +0 -332
  69. data/lib/baykit/bayserver/docker/built_in/log_boat.rb +0 -71
  70. data/lib/baykit/bayserver/tours/send_file_yacht.rb +0 -97
  71. data/lib/baykit/bayserver/watercraft/boat.rb +0 -43
  72. data/lib/baykit/bayserver/watercraft/yacht.rb +0 -42
@@ -1,12 +1,11 @@
1
1
  require 'baykit/bayserver/agent/grand_agent'
2
2
  require 'baykit/bayserver/agent/lifecycle_listener'
3
3
  require 'baykit/bayserver/agent/multiplexer/plain_transporter'
4
- require 'baykit/bayserver/agent/multiplexer/rudder_state'
4
+ require 'baykit/bayserver/common/rudder_state'
5
5
  require 'baykit/bayserver/rudders/io_rudder'
6
6
  require 'baykit/bayserver/docker/built_in/write_file_taxi'
7
7
  require 'baykit/bayserver/docker/log'
8
8
  require 'baykit/bayserver/docker/built_in/log_items'
9
- require 'baykit/bayserver/docker/built_in/log_boat'
10
9
  require 'baykit/bayserver/util/string_util'
11
10
 
12
11
  module Baykit
@@ -20,11 +19,20 @@ module Baykit
20
19
  include Baykit::BayServer::Util
21
20
  include Baykit::BayServer::Bcf
22
21
  include Baykit::BayServer::Agent
22
+ include Baykit::BayServer::Common
23
+
24
+ class LoggerInfo
25
+ attr_accessor :file_name
26
+ attr_accessor :file_size
27
+ attr_accessor :rudder
28
+ attr_accessor :multiplexer
29
+ attr_accessor :rudder_state
30
+ attr_accessor :registered
31
+ end
23
32
 
24
33
  class AgentListener
25
34
  include Baykit::BayServer::Agent::Multiplexer
26
35
  include Baykit::BayServer::Agent::LifecycleListener # implements
27
- include Baykit::BayServer::Agent::Transporter
28
36
  include Baykit::BayServer::Agent
29
37
  include Baykit::BayServer::Rudders
30
38
 
@@ -35,17 +43,19 @@ module Baykit
35
43
  end
36
44
 
37
45
  def add(agt_id)
38
- file_name = "#{@log_docker.file_prefix}_#{agt_id}.#{@log_docker.file_ext}"
39
- size = 0
40
- if ::File.exist?(file_name)
41
- size = ::File.size(file_name)
46
+ info = LoggerInfo.new()
47
+ info.file_name = "#{@log_docker.file_prefix}_#{agt_id}.#{@log_docker.file_ext}"
48
+ info.file_size = 0
49
+
50
+ if ::File.exist?(info.file_name)
51
+ info.file_size = ::File.size(info.file_name)
42
52
  end
43
53
  agt = GrandAgent.get(agt_id)
44
54
 
45
55
  begin
46
- f = File.open(file_name, "a")
56
+ f = File.open(info.file_name, "a")
47
57
  rescue => e
48
- BayLog.fatal(BayMessage.get(:INT_CANNOT_OPEN_LOG_FILE, file_name))
58
+ BayLog.fatal(BayMessage.get(:INT_CANNOT_OPEN_LOG_FILE, info.file_name))
49
59
  BayLog.fatal_e(e);
50
60
  end
51
61
 
@@ -68,20 +78,21 @@ module Baykit
68
78
  raise Sink.new
69
79
  end
70
80
 
71
- st = RudderState.new(rd)
72
- st.bytes_wrote = size
73
- mpx.add_rudder_state(rd, st)
81
+ info.multiplexer = mpx
82
+ info.rudder = rd
83
+ info.registered = false
74
84
 
75
- @log_docker.multiplexers[agt_id] = mpx
76
- @log_docker.rudders[agt_id] = rd
85
+ @log_docker.loggers[agt_id] = info
77
86
  end
78
87
 
79
88
 
80
89
  def remove(agt_id)
81
- rd = @log_docker.rudders[agt_id]
82
- @log_docker.multiplexers[agt_id].req_close(rd)
83
- @log_docker.multiplexers[agt_id] = nil
84
- @log_docker.rudders[agt_id] = nil
90
+ info = @log_docker.loggers[agt_id]
91
+ rd = info.rudder
92
+ if info.registered
93
+ info.multiplexer.req_close(rd)
94
+ end
95
+ @log_docker.loggers[agt_id] = nil
85
96
  end
86
97
  end
87
98
 
@@ -101,16 +112,12 @@ module Baykit
101
112
  # Log items
102
113
  attr :log_items
103
114
 
104
- attr :rudders
105
-
106
- # Multiplexer to write to file
107
- attr :multiplexers
115
+ attr :loggers
108
116
 
109
117
  def initialize
110
118
  @format = nil
111
119
  @log_items = []
112
- @rudders = {}
113
- @multiplexers = {}
120
+ @loggers = {}
114
121
  end
115
122
 
116
123
  def init(elm, parent)
@@ -167,8 +174,17 @@ module Baykit
167
174
 
168
175
  # If threre are message to write, write it
169
176
  if sb.length > 0
170
- @multiplexers[tour.ship.agent_id].req_write(
171
- @rudders[tour.ship.agent_id],
177
+ info = @loggers[tour.ship.agent_id]
178
+ if info.rudder_state == nil
179
+ info.rudder_state = RudderStateStore.get_store(tour.ship.agent_id).rent()
180
+ info.rudder_state.init(info.rudder)
181
+ info.rudder_state.bytes_wrote = info.file_size
182
+ info.multiplexer.add_rudder_state(info.rudder, info.rudder_state)
183
+ info.registered = true
184
+ end
185
+
186
+ info.multiplexer.req_write(
187
+ info.rudder,
172
188
  sb,
173
189
  nil,
174
190
  "log"
@@ -121,6 +121,20 @@ module Baykit
121
121
  raise NotImplementedError
122
122
  end
123
123
 
124
+ # True if cache is enabled
125
+ def enable_cache
126
+ raise NotImplementedError
127
+ end
128
+
129
+ # Lifespan seconds of cache
130
+ def cache_lifespan_sec
131
+ raise NotImplementedError
132
+ end
133
+
134
+ # Cache size
135
+ def cache_size_mb
136
+ raise NotImplementedError
137
+ end
124
138
 
125
139
  def self.get_multiplexer_type_name(type)
126
140
  case type
@@ -0,0 +1,66 @@
1
+ require 'baykit/bayserver/rudders/rudder'
2
+ require 'baykit/bayserver/util/simple_buffer'
3
+
4
+ module Baykit
5
+ module BayServer
6
+ module Docker
7
+ module SendFile
8
+ class FileContent
9
+
10
+ attr :path
11
+ attr :content
12
+ attr :content_length
13
+ attr_accessor :bytes_loaded
14
+ attr :loaded_time
15
+ attr :waiters
16
+ attr :lock
17
+
18
+ include Baykit::BayServer::Rudders
19
+ include Baykit::BayServer::Util
20
+
21
+
22
+ def initialize(path, length)
23
+ @path = path
24
+ @content = ""
25
+ @content_length = length
26
+ @bytes_loaded = 0
27
+ @loaded_time = Time.now.to_i
28
+ @waiters = []
29
+ @lock = Mutex.new
30
+ end
31
+
32
+ def is_loaded()
33
+ return @bytes_loaded == @content_length
34
+ end
35
+
36
+ def add_waiter(waiter)
37
+ @lock.synchronize do
38
+ if is_loaded
39
+ wakeup_waiter(waiter)
40
+ else
41
+ waiters << waiter
42
+ end
43
+ end
44
+ end
45
+
46
+ def complete()
47
+ @lock.synchronize do
48
+ @waiters.each do |waiter|
49
+ wakeup_waiter(waiter)
50
+ end
51
+ waiters.clear
52
+ end
53
+ end
54
+
55
+ def wakeup_waiter(waiter)
56
+ begin
57
+ waiter.write(" ")
58
+ rescue IOError => e
59
+ BayLog.error_e(e, "Write error: %s", e)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -4,6 +4,7 @@ require 'baykit/bayserver/rudders/io_rudder'
4
4
  require 'baykit/bayserver/agent/multiplexer/plain_transporter'
5
5
  require 'baykit/bayserver/util/mimes'
6
6
  require 'baykit/bayserver/docker/send_file/send_file_ship'
7
+ require 'baykit/bayserver/docker/send_file/wait_file_ship'
7
8
 
8
9
  module Baykit
9
10
  module BayServer
@@ -16,13 +17,39 @@ module Baykit
16
17
  include Baykit::BayServer::Tours
17
18
  include Baykit::BayServer::Rudders
18
19
  include Baykit::BayServer::Util
20
+ include Baykit::BayServer::Common
19
21
 
22
+ attr :tour
20
23
  attr :path
24
+ attr :charset
25
+ attr :mime_type
21
26
  attr :abortable
27
+ attr :store
28
+ attr :file_content
29
+ attr :lock
22
30
 
23
- def initialize(path)
31
+ def initialize(tur, store, path, charset)
32
+ @tour = tur
33
+ @store = store
24
34
  @path = path
35
+ @charset = charset
25
36
  @abortable = true
37
+ @lock = Mutex.new
38
+
39
+ rname = File.basename(path)
40
+ pos = rname.rindex('.')
41
+ if pos
42
+ ext = rname[pos + 1 .. -1].downcase
43
+ @mime_type = Mimes.type(ext)
44
+ end
45
+
46
+ if @mime_type == nil
47
+ @mime_type = "application/octet-stream"
48
+ end
49
+
50
+ if @mime_type.start_with?("text/") && charset != nil
51
+ @mime_type = @mime_type + "; charset=" + charset
52
+ end
26
53
  end
27
54
 
28
55
  ######################################################
@@ -36,7 +63,7 @@ module Baykit
36
63
 
37
64
  def on_end_req_content(tur)
38
65
  BayLog.debug("%s endReqContent", tur)
39
- send_file_async(tur, path, tur.res.charset)
66
+ req_start_tour()
40
67
  @abortable = false
41
68
  end
42
69
 
@@ -49,43 +76,82 @@ module Baykit
49
76
  # Sending file methods
50
77
  ######################################################
51
78
 
52
- def send_file_async(tur, file, charset)
79
+ def req_start_tour
53
80
 
54
- if File.directory?(file)
55
- raise HttpException.new HttpStatus::FORBIDDEN, file
56
- elsif !File.exist?(file)
57
- raise HttpException.new HttpStatus::NOT_FOUND, file
58
- end
81
+ @lock.synchronize do
82
+ if @store == nil
83
+ status = FileStore::FileContentStatus.new(nil, FileStore::FileContentStatus::EXCEEDED)
84
+ else
85
+ status = @store.get(path)
86
+ end
87
+ @file_content = status.file_content
88
+
89
+ BayLog.debug("%s file content status: %d", @tour, status.status)
90
+ case status.status
91
+ when FileStore::FileContentStatus::STARTED, FileStore::FileContentStatus::EXCEEDED
92
+ send_file_async
93
+
94
+ when FileStore::FileContentStatus::READING
95
+ # Wait file loaded
96
+ BayLog.debug("%s Cannot start tour (file reading)", @tour)
97
+
98
+ agt = GrandAgent.get(@tour.ship.agent_id)
99
+ wait_file_ship = WaitFileShip.new()
100
+ tp = PlainTransporter.new(
101
+ agt.spider_multiplexer,
102
+ wait_file_ship,
103
+ true,
104
+ 8192,
105
+ false)
106
+
107
+ begin
108
+ pipe = IO::pipe
109
+ source_rd = IORudder.new(pipe[0])
110
+ source_rd.set_non_blocking()
111
+ wait_rd = IORudder.new(pipe[1])
112
+ rescue IOError => e
113
+ raise Sink.new("Fatal error: %s", e)
114
+ end
59
115
 
60
- mime_type = nil
116
+ wait_file_ship.init(source_rd, tp, @tour, @file_content, self)
117
+ @tour.res.set_consume_listener(&ContentConsumeListener::DEV_NULL)
61
118
 
62
- rname = File.basename(file)
63
- pos = rname.rindex('.')
64
- if pos
65
- ext = rname[pos + 1 .. -1].downcase
66
- mime_type = Mimes.type(ext)
67
- end
119
+ st = RudderStateStore.get_store(agt.agent_id).rent()
120
+ st.init(source_rd, tp)
121
+ agt.spider_multiplexer.add_rudder_state(source_rd, st)
122
+ agt.spider_multiplexer.req_read(source_rd)
123
+
124
+ @file_content.add_waiter(wait_rd)
125
+
126
+ when FileStore::FileContentStatus::COMPLETED
127
+ send_file_from_cache
68
128
 
69
- if !mime_type
70
- mime_type = "application/octet-stream"
129
+ else
130
+ raise Sink.new("Unknown file content status: %d", status.status)
131
+ end
71
132
  end
133
+ end
72
134
 
73
- if mime_type.start_with?("text/") && charset != nil
74
- mime_type = mime_type + "; charset=" + charset
135
+ def send_file_async()
136
+
137
+ if File.directory?(@path)
138
+ raise HttpException.new(HttpStatus::FORBIDDEN, @path)
139
+ elsif !File.exist?(@path)
140
+ raise HttpException.new(HttpStatus::NOT_FOUND, @path)
75
141
  end
76
142
 
77
- file_len = ::File.size(file)
143
+ file_len = ::File.size(@path)
78
144
 
79
- tur.res.headers.set_content_type(mime_type)
80
- tur.res.headers.set_content_length(file_len)
145
+ @tour.res.headers.set_content_type(@mime_type)
146
+ @tour.res.headers.set_content_length(File.size(@path))
81
147
 
82
148
  begin
83
- tur.res.send_headers(Tour::TOUR_ID_NOCHECK)
149
+ @tour.res.send_headers(Tour::TOUR_ID_NOCHECK)
84
150
 
85
- bufsize = tur.ship.protocol_handler.max_res_packet_data_size
86
- agt = GrandAgent.get(tur.ship.agent_id)
151
+ bufsize = @tour.ship.protocol_handler.max_res_packet_data_size
152
+ agt = GrandAgent.get(@tour.ship.agent_id)
87
153
 
88
- f = File.open(file, "rb")
154
+ f = File.open(@path, "rb")
89
155
  rd = IORudder.new(f)
90
156
 
91
157
  case(BayServer.harbor.file_multiplexer)
@@ -93,6 +159,9 @@ module Baykit
93
159
  when Harbor::MULTIPLEXER_TYPE_SPIDER
94
160
  mpx = agt.spider_multiplexer
95
161
 
162
+ when Harbor::MULTIPLEXER_TYPE_JOB
163
+ mpx = agt.job_multiplexer
164
+
96
165
  when Harbor::MULTIPLEXER_TYPE_SPIN
97
166
  mpx = agt.spin_multiplexer
98
167
 
@@ -111,16 +180,18 @@ module Baykit
111
180
  8195,
112
181
  false)
113
182
 
114
- send_file_ship.init(rd, tp, tur)
183
+ send_file_ship.init(rd, tp, @tour, @file_content)
115
184
  sid = send_file_ship.ship_id
116
185
 
117
- tur.res.set_consume_listener do |len, resume|
186
+ @tour.res.set_consume_listener do |len, resume|
118
187
  if resume
119
188
  send_file_ship.resume_read(sid)
120
189
  end
121
190
  end
122
191
 
123
- mpx.add_rudder_state(rd, RudderState.new(rd, tp))
192
+ st = RudderStateStore.get_store(agt.agent_id).rent()
193
+ st.init(rd, tp)
194
+ mpx.add_rudder_state(rd, st)
124
195
  mpx.req_read(rd)
125
196
 
126
197
  rescue IOError => e
@@ -130,6 +201,19 @@ module Baykit
130
201
 
131
202
  end
132
203
 
204
+ def send_file_from_cache
205
+ @tour.res.set_consume_listener(&ContentConsumeListener::DEV_NULL)
206
+ @tour.res.headers.set_content_type(@mime_type)
207
+ @tour.res.headers.set_content_length(File.size(@path))
208
+ begin
209
+ @tour.res.send_headers(Tour::TOUR_ID_NOCHECK)
210
+ @tour.res.send_res_content(Tour::TOUR_ID_NOCHECK, @file_content.content, 0, @file_content.content_length)
211
+ @tour.res.end_res_content(Tour::TOUR_ID_NOCHECK)
212
+ rescue IOError => e
213
+ BayLog.error_e(e)
214
+ raise HttpException.new(HttpStatus::INTERNAL_SERVER_ERROR, @file_content.path)
215
+ end
216
+ end
133
217
 
134
218
  end
135
219
  end
@@ -0,0 +1,117 @@
1
+ require 'baykit/bayserver/rudders/rudder'
2
+ require 'baykit/bayserver/util/simple_buffer'
3
+
4
+ require 'baykit/bayserver/docker/send_file/file_content'
5
+
6
+ module Baykit
7
+ module BayServer
8
+ module Docker
9
+ module SendFile
10
+ class FileStore
11
+
12
+ class FileContentStatus
13
+ STARTED = 1
14
+ READING = 2
15
+ COMPLETED = 3
16
+ EXCEEDED = 4
17
+
18
+ attr :file_content
19
+ attr :status
20
+
21
+ def initialize(file_content, status)
22
+ @file_content = file_content
23
+ @status = status
24
+ end
25
+ end
26
+
27
+ attr :contents
28
+ attr :limit_bytes
29
+ attr :total_bytes
30
+ attr :lifespan_seconds
31
+ attr :lock
32
+
33
+ def initialize(timeout_sec, limit_bytes)
34
+ @lifespan_seconds = timeout_sec
35
+ @limit_bytes = limit_bytes
36
+ @total_bytes = 0
37
+ @contents = {}
38
+ @lock = Mutex.new
39
+ end
40
+
41
+ def get(path)
42
+ @lock.synchronize do
43
+ status = 0
44
+ file_content = @contents[path]
45
+
46
+ if file_content != nil
47
+ now = Time.now.to_i
48
+
49
+ if file_content.loaded_time + @lifespan_seconds < Time.now.to_i
50
+ @total_bytes -= file_content.length
51
+ BayLog.debug("Remove expired content: %s", path)
52
+ @contents.delete(path)
53
+ file_content = nil
54
+ else
55
+ if file_content.is_loaded
56
+ status = FileContentStatus::COMPLETED
57
+ else
58
+ status = FileContentStatus::READING
59
+ end
60
+ end
61
+ end
62
+
63
+ if file_content == nil
64
+ length = File.size(path)
65
+ exceeded = false
66
+ if length <= @limit_bytes
67
+ if @total_bytes + length > @limit_bytes
68
+ if !evict()
69
+ exceeded = true
70
+ end
71
+ end
72
+ else
73
+ exceeded = true
74
+ end
75
+
76
+ if exceeded
77
+ status = FileContentStatus::EXCEEDED
78
+ else
79
+ file_content = FileContent.new(path, length)
80
+ @contents[path] = file_content
81
+ @total_bytes += length
82
+ status = FileContentStatus::STARTED
83
+ end
84
+ end
85
+ return FileContentStatus.new(file_content, status)
86
+
87
+ end
88
+ end
89
+
90
+ def evict()
91
+ evict_list = []
92
+ @contents.each do | path, content |
93
+ if content.is_loaded
94
+ next
95
+ end
96
+
97
+ if content.loaded_time + @lifespan_seconds < Time.now.to_i
98
+ # Timed out content
99
+ BayLog.debug("Remove expired content: %s", path)
100
+ @total_bytes -= content.length
101
+ evict_list << path
102
+ else
103
+ break
104
+ end
105
+ end
106
+
107
+ evict_list.each do | path |
108
+ @contents.delete(path)
109
+ end
110
+
111
+ return !evict_list.empty?
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -3,6 +3,7 @@ require 'baykit/bayserver/tours/package'
3
3
  require 'baykit/bayserver/docker/base/club_base'
4
4
  require 'baykit/bayserver/docker/send_file/file_content_handler'
5
5
  require 'baykit/bayserver/docker/send_file/directory_train'
6
+ require 'baykit/bayserver/docker/send_file/file_store'
6
7
 
7
8
  require 'baykit/bayserver/util/string_util'
8
9
 
@@ -17,6 +18,7 @@ module Baykit
17
18
  include Baykit::BayServer::Tours
18
19
 
19
20
  attr :list_files
21
+ attr :file_store
20
22
 
21
23
  ######################################################
22
24
  # Implements DockerBase
@@ -57,14 +59,20 @@ module Baykit
57
59
 
58
60
  real = "#{tur.town.location}/#{rel_path}"
59
61
 
60
- if File.directory?(real) && @list_files
61
- train = DirectoryTrain.new(tur, real)
62
- train.start_tour()
62
+ if File.directory?(real)
63
+ if @list_files
64
+ train = DirectoryTrain.new(tur, real)
65
+ train.start_tour()
66
+ else
67
+ raise HttpException.new(HttpStatus::FORBIDDEN, "Directory scan is prohibited")
68
+ end
63
69
  else
64
- handler = FileContentHandler.new(real)
70
+ if BayServer.harbor.enable_cache() && @file_store == nil
71
+ @file_store = FileStore.new(BayServer.harbor.cache_lifespan_sec, BayServer.harbor.cache_size_mb * 1024 * 1024)
72
+ end
73
+ handler = FileContentHandler.new(tur, @file_store, real, tur.res.charset)
65
74
  tur.req.set_content_handler(handler)
66
75
  end
67
-
68
76
  end
69
77
 
70
78
  end
@@ -8,6 +8,8 @@ module Baykit
8
8
  include Baykit::BayServer::Tours::ReqContentHandler # implements
9
9
 
10
10
  attr :file_wrote_len
11
+
12
+ attr :file_content
11
13
  attr :tour
12
14
  attr :tour_id
13
15
 
@@ -19,11 +21,12 @@ module Baykit
19
21
  attr :path
20
22
  attr :abortable
21
23
 
22
- def init(rd, tp, tur)
24
+ def init(rd, tp, tur, file_content)
23
25
  super(tur.ship.agent_id, rd, tp)
24
26
  @file_wrote_len = 0
25
27
  @tour = tur
26
28
  @tour_id = tur.tour_id
29
+ @file_content = file_content
27
30
  end
28
31
 
29
32
  ######################################################
@@ -48,6 +51,12 @@ module Baykit
48
51
  begin
49
52
  available = @tour.res.send_res_content(@tour_id, buf, 0, buf.length)
50
53
 
54
+ if @file_content != nil
55
+ #BayLog.debug("buf=%s target=%s", buf, @file_content.content)
56
+ @file_content.content << buf
57
+ @file_content.bytes_loaded += buf.length
58
+ end
59
+
51
60
  if available
52
61
  return NextSocketAction::CONTINUE
53
62
  else
@@ -73,7 +82,7 @@ module Baykit
73
82
  begin
74
83
  @tour.res.end_res_content(@tour_id)
75
84
  rescue IOError => e
76
- BayLog.debug_e(ex)
85
+ BayLog.debug_e(e)
77
86
  end
78
87
  return NextSocketAction::CLOSE
79
88
  end