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 +4 -4
- data/Gemfile.lock +1 -1
- data/config.ru +3 -1
- data/lib/rest-ftp-daemon.rb +4 -0
- data/lib/rest-ftp-daemon/api/dashboard.rb +3 -3
- data/lib/rest-ftp-daemon/conchita.rb +65 -0
- data/lib/rest-ftp-daemon/constants.rb +5 -3
- data/lib/rest-ftp-daemon/job.rb +2 -1
- data/lib/rest-ftp-daemon/job_queue.rb +30 -73
- data/lib/rest-ftp-daemon/logger_pool.rb +8 -3
- data/lib/rest-ftp-daemon/static/css/main.css +9 -2
- data/lib/rest-ftp-daemon/views/dashboard_jobs.haml +2 -2
- data/lib/rest-ftp-daemon/worker_pool.rb +16 -1
- data/rest-ftp-daemon.yml.sample +2 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a453a7be5c87798246b4603a6787365b5829f58f
|
4
|
+
data.tar.gz: 3583043f7aa342bc2992fc5a8b0599a19acfe693
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94e64e9196678fa87b03d0ada12c1f7b4064e5c88d1996731b060a9703c901d858e2f0aab525f0b3ad5a12e15aad076e51d9b6e9fcd2292cad24788c78606368
|
7
|
+
data.tar.gz: 3933f23e1bbe6c039ef4f94c69e0bf682504514e8718a9df14d9c9c4f7466357dbf2a190170a8bc143975b5c1ff6543b52c15d4627f86f4afb360f11c87dd3ad
|
data/Gemfile.lock
CHANGED
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
|
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
|
data/lib/rest-ftp-daemon.rb
CHANGED
@@ -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
|
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
|
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.
|
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 =
|
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
|
-
:
|
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
|
data/lib/rest-ftp-daemon/job.rb
CHANGED
@@ -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
|
-
|
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
|
-
#
|
226
|
-
|
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
|
-
|
229
|
-
|
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
|
-
|
235
|
-
|
236
|
-
|
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
|
-
|
239
|
-
|
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
|
-
|
242
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
data/rest-ftp-daemon.yml.sample
CHANGED
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.
|
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-
|
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
|