rest-ftp-daemon 0.213.0 → 0.214.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
  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