rest-ftp-daemon 0.104.5 → 0.200
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +24 -22
- data/bin/rest-ftp-daemon +50 -43
- data/config.ru +1 -1
- data/lib/rest-ftp-daemon/api/dashboard.rb +1 -1
- data/lib/rest-ftp-daemon/api/root.rb +2 -2
- data/lib/rest-ftp-daemon/config.rb +11 -0
- data/lib/rest-ftp-daemon/constants.rb +26 -15
- data/lib/rest-ftp-daemon/exceptions.rb +1 -0
- data/lib/rest-ftp-daemon/helpers.rb +2 -1
- data/lib/rest-ftp-daemon/job.rb +194 -115
- data/lib/rest-ftp-daemon/job_queue.rb +9 -4
- data/lib/rest-ftp-daemon/logger.rb +21 -4
- data/lib/rest-ftp-daemon/logger_pool.rb +3 -1
- data/lib/rest-ftp-daemon/notification.rb +44 -19
- data/lib/rest-ftp-daemon/views/dashboard.haml +2 -3
- data/lib/rest-ftp-daemon/views/dashboard_headers.haml +1 -1
- data/lib/rest-ftp-daemon/views/dashboard_jobs.haml +13 -16
- data/lib/rest-ftp-daemon/worker_pool.rb +62 -30
- data/rest-ftp-daemon.gemspec +0 -1
- data/rest-ftp-daemon.yml.sample +3 -0
- metadata +2 -2
@@ -12,56 +12,81 @@ module RestFtpDaemon
|
|
12
12
|
|
13
13
|
def initialize url, params
|
14
14
|
# Generate a random key
|
15
|
-
@id = Helpers.identifier(
|
15
|
+
@id = Helpers.identifier(NOTIFY_IDENTIFIER_LEN)
|
16
16
|
|
17
17
|
# Logger
|
18
18
|
@logger = RestFtpDaemon::LoggerPool.instance.get :notify
|
19
19
|
|
20
20
|
# Check context
|
21
|
+
|
21
22
|
if url.nil?
|
22
|
-
info "skipping (missing url): #{params}"
|
23
|
+
info "skipping (missing url): #{params.inspect}"
|
23
24
|
return
|
24
|
-
|
25
|
-
|
25
|
+
|
26
|
+
elsif params[:event].nil?
|
27
|
+
info "skipping (missing event): #{params.inspect}"
|
26
28
|
return
|
29
|
+
|
27
30
|
else
|
28
|
-
#
|
29
|
-
info "
|
31
|
+
#info "created: OK"
|
32
|
+
# info "created: #{params.class}"
|
33
|
+
info "created #{params.inspect}"
|
34
|
+
|
30
35
|
end
|
31
36
|
|
32
37
|
# Params
|
33
38
|
body = {
|
34
39
|
id: params[:id].to_s,
|
35
|
-
signal: params[:
|
40
|
+
signal: "#{NOTIFY_PREFIX}.#{params[:event].to_s}",
|
36
41
|
error: params[:error],
|
37
|
-
host: Settings
|
42
|
+
host: Settings.host.to_s,
|
38
43
|
}
|
39
|
-
body[:status] = params[:status] if
|
44
|
+
body[:status] = params[:status] if params[:status].is_a? Enumerable
|
40
45
|
|
41
46
|
# Send message in a thread
|
42
47
|
Thread.new do |thread|
|
43
48
|
# Prepare query
|
44
49
|
uri = URI(url)
|
45
|
-
headers = {
|
46
|
-
|
50
|
+
headers = {
|
51
|
+
'Content-Type' => 'application/json',
|
52
|
+
'Accept' => 'application/json',
|
53
|
+
'User-Agent' => "#{APP_NAME} - #{APP_VER}"
|
54
|
+
}
|
55
|
+
data = body.to_json
|
56
|
+
info "sending #{data}"
|
57
|
+
|
58
|
+
# Prepare HTTP client
|
59
|
+
http = Net::HTTP.new uri.host, uri.port
|
60
|
+
# http.initialize_http_header({'User-Agent' => APP_NAME})
|
47
61
|
|
48
62
|
# Post notification
|
49
|
-
|
50
|
-
|
51
|
-
|
63
|
+
response = http.post uri.path, data, headers
|
64
|
+
|
65
|
+
# Handle server response / multi-lines
|
66
|
+
response_lines = response.body.lines
|
67
|
+
|
68
|
+
if response_lines.size > 1
|
69
|
+
human_size = Helpers.format_bytes(response.body.bytesize, "B")
|
70
|
+
#human_size = 0
|
71
|
+
info "received [#{response.code}] #{human_size} (#{response_lines.size} lines)", lines: response_lines
|
72
|
+
else
|
73
|
+
info "received [#{response.code}] #{response.body.strip}"
|
74
|
+
end
|
52
75
|
|
53
|
-
# info "notify reply: #{response.body.strip}"
|
54
|
-
info "reply: #{response.body.strip}"
|
55
76
|
end
|
56
77
|
|
57
78
|
end
|
58
79
|
|
59
80
|
protected
|
60
81
|
|
61
|
-
def info message,
|
82
|
+
def info message, context = {}
|
62
83
|
return if @logger.nil?
|
63
|
-
|
64
|
-
|
84
|
+
|
85
|
+
# Inject context
|
86
|
+
context[:id] = @id
|
87
|
+
context[:origin] = self.class
|
88
|
+
|
89
|
+
@logger.info_with_id message, context
|
65
90
|
end
|
66
91
|
|
67
92
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
%link{ href:"/css/bootstrap.css" , rel: "stylesheet"}
|
6
6
|
%link{ href:"/css/main.css" , rel: "stylesheet"}
|
7
7
|
%link{ href:"http://fonts.googleapis.com/css?family=Inconsolata:400,700" , rel: "stylesheet"}
|
8
|
-
%title="#{Settings
|
8
|
+
%title="#{Settings.host} [#{Settings.namespace}] #{APP_NAME}"
|
9
9
|
|
10
10
|
%body
|
11
11
|
|
@@ -49,10 +49,9 @@
|
|
49
49
|
%th target
|
50
50
|
%th date
|
51
51
|
%th status
|
52
|
-
%th progress
|
53
52
|
%th error
|
54
53
|
%th.text-right size
|
55
|
-
%th.text-right
|
54
|
+
%th.text-right bitrate
|
56
55
|
%th
|
57
56
|
|
58
57
|
- if @only.nil? && !@jobs_queued.empty?
|
@@ -3,18 +3,18 @@
|
|
3
3
|
- progress = job.get :progress
|
4
4
|
- source_count = job.get(:source_count) || 0
|
5
5
|
- source_processed = job.get(:source_processed) || 0
|
6
|
-
-
|
6
|
+
- source_current = job.get(:source_current)
|
7
7
|
- presented = present job, :with => RestFtpDaemon::API::Entities::JobPresenter, hide_params: true
|
8
8
|
- errmsg = job.get :error_message
|
9
9
|
- method = job.get(:target_method)
|
10
10
|
|
11
11
|
- if !job.error.nil?
|
12
12
|
- trclass = "danger"
|
13
|
-
- elsif job.status ==
|
13
|
+
- elsif job.status == JOB_STATUS_UPLOADING
|
14
14
|
- trclass = "info"
|
15
|
-
- elsif job.status ==
|
15
|
+
- elsif job.status == JOB_STATUS_FINISHED
|
16
16
|
- trclass = "success"
|
17
|
-
- elsif job.status ==
|
17
|
+
- elsif job.status == JOB_STATUS_QUEUED
|
18
18
|
- trclass = "active"
|
19
19
|
- else
|
20
20
|
- trclass = "warning"
|
@@ -41,29 +41,27 @@
|
|
41
41
|
%td
|
42
42
|
= job.status
|
43
43
|
|
44
|
-
-# if (source_count > 1) && (source_processed < source_count)
|
45
44
|
- if (source_processed < source_count)
|
46
|
-
|
45
|
+
= " (#{source_processed}/#{source_count})"
|
47
46
|
|
48
|
-
- unless
|
47
|
+
- unless progress.nil?
|
48
|
+
= "#{progress}%"
|
49
|
+
|
50
|
+
- if job.status != JOB_STATUS_FINISHED
|
49
51
|
%br
|
50
|
-
%b=
|
52
|
+
%b= source_current unless source_current.nil?
|
51
53
|
|
52
54
|
%td
|
53
|
-
-
|
55
|
+
- if !job.error && job.status != JOB_STATUS_FINISHED
|
56
|
+
-# unless progress.nil? ||
|
54
57
|
.progress
|
55
58
|
.progress-bar{style:"width: #{progress}%;"}
|
56
|
-
=
|
59
|
+
= "#{progress}%" unless progress.nil?
|
57
60
|
|
58
|
-
%td
|
59
|
-
- unless job.error || job.status == :finished
|
60
|
-
- unless progress.nil?
|
61
|
-
= "#{progress}%"
|
62
61
|
- else
|
63
62
|
.error{title: errmsg}
|
64
63
|
= Helpers.text_or_empty(job.error)
|
65
64
|
|
66
|
-
|
67
65
|
%td.nobr.text-right
|
68
66
|
= Helpers.format_bytes(size, "B")
|
69
67
|
|
@@ -76,5 +74,4 @@
|
|
76
74
|
.label.label-info.flag.worker-label= job.priority
|
77
75
|
|
78
76
|
- unless job.wid.nil?
|
79
|
-
%br
|
80
77
|
.label.label-warning.flag.worker-label= job.wid
|
@@ -1,3 +1,5 @@
|
|
1
|
+
|
2
|
+
|
1
3
|
module RestFtpDaemon
|
2
4
|
class WorkerPool
|
3
5
|
|
@@ -7,39 +9,57 @@ module RestFtpDaemon
|
|
7
9
|
# Logger
|
8
10
|
@logger = RestFtpDaemon::LoggerPool.instance.get :workers
|
9
11
|
|
12
|
+
|
10
13
|
# Check parameters
|
11
14
|
raise "A thread count of #{number_threads} is less than one" if number_threads < 1
|
12
15
|
|
13
|
-
# Prepare status hash
|
16
|
+
# Prepare status hash and vars
|
14
17
|
@statuses = {}
|
15
18
|
@workers = {}
|
19
|
+
@mutex = Mutex.new
|
20
|
+
@counter = 0
|
16
21
|
|
17
22
|
# Create worker threads
|
18
23
|
info "WorkerPool initializing with #{number_threads} workers"
|
19
|
-
|
20
|
-
|
24
|
+
create_worker_threads number_threads
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def worker_vars
|
29
|
+
vars = {}
|
30
|
+
|
31
|
+
@workers.each do |name, thread|
|
32
|
+
#currents[thread.id] = thread.current
|
33
|
+
vars[thread[:name]] = thread[:vars]
|
34
|
+
end
|
35
|
+
|
36
|
+
vars
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
21
40
|
|
22
|
-
|
41
|
+
def create_worker_threads n
|
42
|
+
n.times do
|
23
43
|
# Increment counter
|
24
44
|
@mutex.synchronize do
|
25
45
|
@counter +=1
|
26
46
|
end
|
27
|
-
name = "w#{@counter}"
|
28
47
|
|
29
|
-
|
48
|
+
# Create a dedicated thread for this worker
|
49
|
+
name = "w#{@counter}"
|
50
|
+
@workers[name] = create_worker_thread name
|
51
|
+
end
|
30
52
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
started_at: Time.now,
|
35
|
-
}
|
53
|
+
end
|
54
|
+
def create_worker_thread name
|
55
|
+
@workers[name] = Thread.new name do
|
36
56
|
|
37
|
-
|
38
|
-
|
39
|
-
|
57
|
+
# Set thread context
|
58
|
+
Thread.current[:name] = name
|
59
|
+
Thread.current[:vars] = { started_at: Time.now }
|
40
60
|
|
41
|
-
#
|
42
|
-
|
61
|
+
# Start working
|
62
|
+
work
|
43
63
|
end
|
44
64
|
|
45
65
|
end
|
@@ -70,12 +90,7 @@ module RestFtpDaemon
|
|
70
90
|
$queue.counter_inc :jobs_processed
|
71
91
|
|
72
92
|
rescue Exception => ex
|
73
|
-
|
74
|
-
info "UNHANDLED EXCEPTION: #{ex.message}"
|
75
|
-
ex.backtrace.each do |line|
|
76
|
-
info line, 1
|
77
|
-
end
|
78
|
-
sleep 1
|
93
|
+
handle_job_uncaught_exception job, ex
|
79
94
|
|
80
95
|
else
|
81
96
|
# Clean job status
|
@@ -87,25 +102,42 @@ module RestFtpDaemon
|
|
87
102
|
end
|
88
103
|
end
|
89
104
|
|
90
|
-
def
|
91
|
-
|
105
|
+
def handle_job_uncaught_exception job, ex
|
106
|
+
begin
|
107
|
+
# Log the exception
|
108
|
+
info "UNHDNALED EXCEPTION: job: #{ex.message}", lines: ex.backtrace
|
109
|
+
|
110
|
+
# Tell the worker has creashed
|
111
|
+
worker_status :crashed
|
112
|
+
|
113
|
+
# Flag the job as crashed
|
114
|
+
job.oops_after_crash ex
|
115
|
+
|
116
|
+
rescue Exception => ex
|
117
|
+
info "DOUBLE EXCEPTION: #{ex.message}", lines: ex.backtrace
|
92
118
|
|
93
|
-
@workers.each do |name, thread|
|
94
|
-
#currents[thread.id] = thread.current
|
95
|
-
vars[thread[:name]] = thread[:vars]
|
96
119
|
end
|
97
120
|
|
98
|
-
|
121
|
+
# Wait a bit
|
122
|
+
sleep 1
|
99
123
|
end
|
100
124
|
|
125
|
+
|
101
126
|
protected
|
102
127
|
|
103
128
|
def ping
|
104
129
|
end
|
105
130
|
|
106
|
-
def info message
|
131
|
+
def info message, context = {}
|
107
132
|
return if @logger.nil?
|
108
|
-
|
133
|
+
|
134
|
+
# Ensure context is a hash of options and inject context
|
135
|
+
context = {} unless context.is_a? Hash
|
136
|
+
context[:id] = Thread.current[:name]
|
137
|
+
context[:origin] = self.class
|
138
|
+
|
139
|
+
# Forward to logger
|
140
|
+
@logger.info_with_id message, context
|
109
141
|
end
|
110
142
|
|
111
143
|
def worker_status status, jobid = nil
|
data/rest-ftp-daemon.gemspec
CHANGED
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.200'
|
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-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|