rest-ftp-daemon 0.213.0 → 0.214.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cdf3cbfd6993183cfe6410fc11ce2743f0d3ca2
4
- data.tar.gz: 07938cd1ed765a2939e8bdc2589069e9379dcd7b
3
+ metadata.gz: a453a7be5c87798246b4603a6787365b5829f58f
4
+ data.tar.gz: 3583043f7aa342bc2992fc5a8b0599a19acfe693
5
5
  SHA512:
6
- metadata.gz: 22536522c3a2cc04c73876305ce7f9217f9f8a12ec141c0d8ea8113c7908c94aa7569477051d179316afffb2efd2c836fb940418aa2d00acd74485b95e45238a
7
- data.tar.gz: 4835fa78f98b4ab22b57be1456e438c65687756ec919435e5dd6cbf5880c7795724ee336fb334ca71df0667b9a8aa681e4a199b12b45bdfc5f696f81378c96f2
6
+ metadata.gz: 94e64e9196678fa87b03d0ada12c1f7b4064e5c88d1996731b060a9703c901d858e2f0aab525f0b3ad5a12e15aad076e51d9b6e9fcd2292cad24788c78606368
7
+ data.tar.gz: 3933f23e1bbe6c039ef4f94c69e0bf682504514e8718a9df14d9c9c4f7466357dbf2a190170a8bc143975b5c1ff6543b52c15d4627f86f4afb360f11c87dd3ad
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rest-ftp-daemon (0.212.0)
4
+ rest-ftp-daemon (0.214.0)
5
5
  double-bag-ftps
6
6
  facter
7
7
  get_process_mem
data/config.ru CHANGED
@@ -3,8 +3,10 @@ load_path_libs = File.expand_path(File.join(File.dirname(__FILE__), 'lib'))
3
3
  $LOAD_PATH.unshift(load_path_libs) unless $LOAD_PATH.include?(load_path_libs)
4
4
  require 'rest-ftp-daemon'
5
5
 
6
- # Create queue and worker pool
6
+ # Create global queue
7
7
  $queue = RestFtpDaemon::JobQueue.new
8
+
9
+ # Initialize workers and conchita subsystem
8
10
  $pool = RestFtpDaemon::WorkerPool.new(Settings.workers || APP_WORKERS)
9
11
 
10
12
  # Rack reloader
@@ -14,10 +14,13 @@ require 'syslog'
14
14
  require 'net/ftp'
15
15
  require 'net/http'
16
16
  require 'double_bag_ftps'
17
+ require 'thread'
18
+ require 'securerandom'
17
19
 
18
20
  require 'newrelic_rpm'
19
21
  require 'get_process_mem'
20
22
 
23
+
21
24
  # Project's libs
22
25
  require 'rest-ftp-daemon/constants'
23
26
  require 'rest-ftp-daemon/settings'
@@ -27,6 +30,7 @@ require 'rest-ftp-daemon/paginate'
27
30
  require 'rest-ftp-daemon/uri'
28
31
  require 'rest-ftp-daemon/job_queue'
29
32
  # require 'rest-ftp-daemon/worker'
33
+ require 'rest-ftp-daemon/conchita'
30
34
  require 'rest-ftp-daemon/worker_pool'
31
35
  require 'rest-ftp-daemon/logger'
32
36
  require 'rest-ftp-daemon/logger_pool'
@@ -22,17 +22,17 @@ module RestFtpDaemon
22
22
  @only = params["only"].to_s
23
23
 
24
24
  # Get jobs for this view, order jobs by their weights
25
- result = $queue.filter_jobs @only
25
+ result = $queue.filter_jobs(@only).reverse
26
26
 
27
27
  # Provide queue only if no filtering set
28
28
  @queue = []
29
- @queue = $queue.queue if @only.empty?
29
+ @queue = $queue.queue.reverse if @only.empty?
30
30
 
31
31
  # Get workers status
32
32
  @worker_variables = $pool.worker_variables
33
33
 
34
34
  # Build paginator
35
- @paginate = Paginate.new result.reverse
35
+ @paginate = Paginate.new result
36
36
  @paginate.only = params["only"]
37
37
  @paginate.page = params["page"]
38
38
 
@@ -0,0 +1,65 @@
1
+ module RestFtpDaemon
2
+ class Conchita
3
+
4
+ def initialize
5
+ # Logger
6
+ @logger = RestFtpDaemon::LoggerPool.instance.get :workers
7
+
8
+ # Conchita configuration
9
+ @conchita = Settings.conchita
10
+ if @conchita.nil?
11
+ return info "conchita: missing conchita.* configuration"
12
+ elsif @conchita[:timer].nil?
13
+ return info "conchita: missing conchita.timer value"
14
+ end
15
+
16
+ # Start main loop
17
+ info "initialized #{@conchita.inspect}"
18
+ cleanup
19
+ end
20
+
21
+ protected
22
+
23
+ def maxage status
24
+ @conchita["clean_#{status.to_s}"] || 0
25
+ end
26
+
27
+ def cleanup
28
+ loop do
29
+ #info "cleanup"
30
+ # info "conchita_loop: cleanup "
31
+ $queue.expire JOB_STATUS_FINISHED, maxage(JOB_STATUS_FINISHED)
32
+ $queue.expire JOB_STATUS_FAILED, maxage(JOB_STATUS_FAILED)
33
+ $queue.expire JOB_STATUS_QUEUED, maxage(JOB_STATUS_QUEUED)
34
+
35
+ # Force garbage collector
36
+ GC.start if @conchita["garbage_collector"]
37
+
38
+ # Sleep for a few seconds
39
+ sleep @conchita[:timer]
40
+ end
41
+ end
42
+
43
+ # def conchita_gc
44
+ # # Read config state
45
+ # proceed = @conchita["clean_garbage"] || false
46
+ # #info "conchita_clean status[#{status.to_s}] \t maxage[#{maxage}] s"
47
+ # return unless proceed
48
+
49
+ # # Trig Ruby's garbage collector
50
+ # info "conchita_gc forced garbage collecting"
51
+ # GC.start
52
+ # end
53
+
54
+ def info message, lines = []
55
+ return if @logger.nil?
56
+
57
+ # Forward to logger
58
+ @logger.info_with_id message,
59
+ wid: :conchita,
60
+ lines: lines,
61
+ origin: self.class.to_s
62
+ end
63
+
64
+ end
65
+ end
@@ -1,7 +1,7 @@
1
1
  # Terrific constants
2
2
  APP_NAME = "rest-ftp-daemon"
3
3
  APP_NICK = "rftpd"
4
- APP_VER = "0.213.0"
4
+ APP_VER = "0.214.0"
5
5
 
6
6
 
7
7
  # Jobs and workers
@@ -17,10 +17,11 @@ JOB_STATUS_QUEUED = :queued
17
17
 
18
18
  # Logging and startup
19
19
  LOG_PIPE_LEN = 10
20
- LOG_COL_WID = 4
20
+ LOG_COL_WID = 8
21
21
  LOG_COL_JID = JOB_IDENT_LEN+3+2
22
22
  LOG_COL_ID = 6
23
23
  LOG_TRIM_LINE = 80
24
+ LOG_DUMPS = File.dirname(__FILE__) + '/../../log/'
24
25
 
25
26
 
26
27
  # Notifications
@@ -39,13 +40,14 @@ JOB_STYLES = {
39
40
  }
40
41
  WORKER_STYLES = {
41
42
  :waiting => :success,
42
- :processing => :info,
43
+ :working => :info,
43
44
  :crashed => :danger,
44
45
  :done => :success,
45
46
  :dead => :danger
46
47
  }
47
48
  PAGINATE_MAX = 30
48
49
 
50
+
49
51
  # Configuration defaults
50
52
  DEFAULT_WORKER_TIMEOUT = 3600
51
53
  DEFAULT_FTP_CHUNK = 2048
@@ -440,9 +440,10 @@ module RestFtpDaemon
440
440
  end
441
441
 
442
442
  def ftp_finished
443
- # Close FTP connexion
443
+ # Close FTP connexion and free up memory
444
444
  @ftp.close
445
445
  info "Job.ftp_finished closed"
446
+ @ftp = nil
446
447
 
447
448
  # FTP debug mode ?
448
449
  if @ftp_debug_enabled
@@ -1,10 +1,5 @@
1
- require 'thread'
2
- require 'securerandom'
3
-
4
1
  module RestFtpDaemon
5
2
  class JobQueue < Queue
6
- # attr_reader :queued
7
- # attr_reader :popped
8
3
 
9
4
  attr_reader :queue
10
5
  attr_reader :jobs
@@ -34,23 +29,6 @@ module RestFtpDaemon
34
29
  # Mutex for counters
35
30
  @counters = {}
36
31
  @mutex_counters = Mutex.new
37
-
38
- # Conchita configuration
39
- @conchita = Settings.conchita
40
- if @conchita.nil?
41
- info "conchita: missing conchita.* configuration"
42
- elsif @conchita[:timer].nil?
43
- info "conchita: missing conchita.timer value"
44
- else
45
- Thread.new {
46
- begin
47
- conchita_loop
48
- rescue Exception => e
49
- info "CONCHITA EXCEPTION: #{e.inspect}"
50
- end
51
- }
52
- end
53
-
54
32
  end
55
33
 
56
34
  def generate_id
@@ -187,69 +165,46 @@ module RestFtpDaemon
187
165
  @waiting.size
188
166
  end
189
167
 
190
- protected
191
-
192
- def prefixed_id id
193
- "#{@prefix}.#{id}"
194
- end
195
-
196
- def sort_queue!
197
- @mutex_counters.synchronize do
198
- @queue.sort_by! &:weight
199
- end
200
- end
201
-
202
- def conchita_loop
203
- info "conchita starting with: #{@conchita.inspect}"
204
- loop do
205
- # Do the cleanup locking the queues
206
- # info "conchita: cleanup expired jobs"
207
- @mutex.synchronize do
208
- conchita_clean JOB_STATUS_FINISHED
209
- conchita_clean JOB_STATUS_FAILED
210
- conchita_clean JOB_STATUS_QUEUED
211
- end
212
- sleep @conchita[:timer]
213
- end
214
- end
215
-
216
- def conchita_clean status # FIXME: clean both @jobs and @queue
168
+ def expire status, maxage
169
+ # FIXME: clean both @jobs and @queue
217
170
  # Init
218
- return if status.nil?
219
-
220
- # Read config state
221
- maxage = @conchita["clean_#{status.to_s}"] || 0
222
- #info "conchita_clean status[#{status.to_s}] \t maxage[#{maxage}] s"
223
- return unless maxage > 0
171
+ return if status.nil? || maxage <= 0
224
172
 
225
- # Delete jobs from the queue if their status is (status)
226
- @jobs.delete_if do |job|
173
+ # Compute oldest possible birthday
174
+ before = Time.now - maxage.to_i
175
+ # info "conchita_clean: SELECT status[#{status.to_s}] before[#{before}]"
227
176
 
228
- # Skip if wrong status
229
- next unless job.status == status.to_sym
230
-
231
- # Skip if updated_at invalid
232
- next if job.updated_at.nil?
177
+ @mutex.synchronize do
178
+ # Delete jobs from the queue when they match status and age limits
179
+ @jobs.delete_if do |job|
233
180
 
234
- # Skip if not aged enough yet
235
- age = Time.now - job.updated_at
236
- next if age < maxage
181
+ # Skip if wrong status, updated_at invalid, or too young
182
+ next unless job.status == status.to_sym
183
+ next if job.updated_at.nil?
184
+ next if job.updated_at > before
237
185
 
238
- # Ok, we have to clean it up ..
239
- info "conchita_clean status[#{status.to_s}] maxage[#{maxage}] job[#{job.id}] age[#{age}]"
186
+ # Ok, we have to clean it up ..
187
+ info "expire [#{status.to_s}] [#{maxage}] > [#{job.id}] [#{job.updated_at}]"
188
+ info " + unqueued" if @queue.delete(job)
240
189
 
241
- # Remove it from the queue if present
242
- job_in_queue = @queue.delete job
243
- info " removed queued job [#{job.id}]" unless job_in_queue.nil?
190
+ true
191
+ end
244
192
 
245
- # Accept to delete it from @jobs
246
- true
247
193
  end
248
194
 
249
195
  end
250
196
 
197
+ protected
198
+
199
+ def prefixed_id id
200
+ "#{@prefix}.#{id}"
201
+ end
251
202
 
252
- private
203
+ def sort_queue!
204
+ @mutex_counters.synchronize do
205
+ @queue.sort_by! &:weight
206
+ end
207
+ end
253
208
 
254
209
  def info message, lines = []
255
210
  return if @logger.nil?
@@ -264,6 +219,8 @@ module RestFtpDaemon
264
219
  if Settings.newrelic_enabled?
265
220
  add_transaction_tracer :push, :category => :task
266
221
  add_transaction_tracer :pop, :category => :task
222
+ add_transaction_tracer :sort_queue!, :category => :task
223
+ add_transaction_tracer :expire, :category => :task
267
224
  end
268
225
 
269
226
  end
@@ -24,9 +24,14 @@ module RestFtpDaemon
24
24
 
25
25
  # And the formatter
26
26
  logger.formatter = proc do |severity, datetime, progname, message|
27
- stamp = datetime.strftime("%Y-%m-%d %H:%M:%S")
28
- field_pipe = "%-#{LOG_PIPE_LEN.to_i}s" % progname
29
- "#{stamp}\t#{field_pipe}\t#{message}\n"
27
+ # stamp = datetime.strftime("%Y-%m-%d %H:%M:%S")
28
+ # field_pipe = "%-#{LOG_PIPE_LEN.to_i}s" % progname
29
+ # "#{stamp}\t#{field_pipe}\t#{message}\n"
30
+ "%s\t%-#{LOG_PIPE_LEN.to_i}s\t%s\n" % [
31
+ datetime.strftime("%Y-%m-%d %H:%M:%S"),
32
+ progname,
33
+ message,
34
+ ]
30
35
  end
31
36
 
32
37
  # Finally return this logger
@@ -14,8 +14,9 @@
14
14
  white-space: nowrap;
15
15
  }
16
16
 
17
- table tr td, .fixed {
18
- font-family: 'Inconsolata', sans-serif;
17
+ body, table tr td, .fixed {
18
+ /*font-family: 'Inconsolata', Verdana, sans-serif;*/
19
+ font-family: 'Verdana', Verdana, sans-serif;
19
20
  font-size: 1em;
20
21
  }
21
22
 
@@ -76,3 +77,9 @@ a.page.btn {
76
77
  .debug {
77
78
  border: 1px solid orange;
78
79
  }
80
+
81
+ .table-condensed tbody > tr > td {
82
+ padding: 3px 3px;
83
+ }
84
+
85
+
@@ -42,7 +42,7 @@
42
42
 
43
43
  - unless @queue.empty?
44
44
  %tbody.jobs
45
- = render :dashboard_table, {jobs: @queue.reverse}
45
+ = render :dashboard_table, {jobs: @queue}
46
46
 
47
47
  %thead
48
48
  %tr
@@ -51,4 +51,4 @@
51
51
 
52
52
  - unless jobs.empty?
53
53
  %tbody.jobs
54
- = render :dashboard_table, {jobs: jobs.reverse}
54
+ = render :dashboard_table, {jobs: jobs}
@@ -17,14 +17,18 @@ module RestFtpDaemon
17
17
  # Prepare status hash and vars
18
18
  @statuses = {}
19
19
  @workers = {}
20
+ @conchita = nil
20
21
  @mutex = Mutex.new
21
22
  @counter = 0
22
23
  @timeout = (Settings.transfer.timeout rescue nil) || DEFAULT_WORKER_TIMEOUT
23
24
 
24
25
  # Create worker threads
25
- info "WorkerPool initializing with [#{number_threads}] workers and [#{@timeout}]s timeout"
26
+ info "WorkerPool creating worker threads [#{number_threads}] timeout [#{@timeout}]s"
26
27
  create_worker_threads number_threads
27
28
 
29
+ # Create conchita thread
30
+ info "WorkerPool creating conchita thread"
31
+ create_conchita_thread
28
32
  end
29
33
 
30
34
  def worker_variables
@@ -44,6 +48,7 @@ module RestFtpDaemon
44
48
  private
45
49
 
46
50
  def create_worker_threads n
51
+ # FIXME counter instead of upto ?
47
52
  n.times do
48
53
  # Increment counter
49
54
  @mutex.synchronize do
@@ -77,6 +82,16 @@ module RestFtpDaemon
77
82
  end
78
83
  end
79
84
 
85
+ def create_conchita_thread
86
+ Thread.new do
87
+ begin
88
+ @conchita = Conchita.new
89
+ rescue Exception => e
90
+ info "CONCHITA EXCEPTION: #{e.inspect}"
91
+ end
92
+ end
93
+ end
94
+
80
95
  def work
81
96
  # Wait for a job to come into the queue
82
97
  worker_status :waiting
@@ -20,7 +20,8 @@ defaults: &defaults
20
20
  # license: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
21
21
 
22
22
  conchita:
23
- timer: 10
23
+ timer: 60
24
+ # garbage_collector: true
24
25
  # clean_failed: 3600
25
26
  # clean_finished: 3600
26
27
  # clean_queued: 86400
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-ftp-daemon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.213.0
4
+ version: 0.214.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno MEDICI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-30 00:00:00.000000000 Z
11
+ date: 2015-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -231,6 +231,7 @@ files:
231
231
  - lib/rest-ftp-daemon/api/root.rb
232
232
  - lib/rest-ftp-daemon/api/routes.rb
233
233
  - lib/rest-ftp-daemon/api/status.rb
234
+ - lib/rest-ftp-daemon/conchita.rb
234
235
  - lib/rest-ftp-daemon/constants.rb
235
236
  - lib/rest-ftp-daemon/exceptions.rb
236
237
  - lib/rest-ftp-daemon/helpers.rb