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 +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
|