vidibus-recording 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +102 -0
- data/lib/generators/vidibus/recording_generator.rb +1 -1
- data/lib/generators/vidibus/templates/script +4 -2
- data/lib/vidibus/recording/backend/rtmpdump.rb +7 -4
- data/lib/vidibus/recording/capistrano/recipes.rb +1 -1
- data/lib/vidibus/recording/capistrano.rb +5 -5
- data/lib/vidibus/recording/daemon.rb +4 -4
- data/lib/vidibus/recording/mongoid.rb +15 -17
- data/lib/vidibus/recording/part.rb +4 -0
- data/lib/vidibus/recording/railtie.rb +9 -1
- data/lib/vidibus/recording/version.rb +1 -1
- data/lib/vidibus/recording/worker.rb +8 -9
- data/lib/vidibus/recording.rb +60 -1
- data/lib/vidibus-recording.rb +0 -14
- metadata +6 -8
- data/README.rdoc +0 -11
- data/lib/vidibus/recording/backend/railtie.rb +0 -1
- data/lib/vidibus/recording/monitoring_job.rb +0 -52
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Vidibus::Recording
|
2
|
+
|
3
|
+
Allows recording of RTMP video streams. Uses RTMPdump. Requires at least Ruby 1.9.
|
4
|
+
|
5
|
+
This gem is part of [Vidibus](http://vidibus.org), an open source toolset for building distributed (video) applications.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add `gem 'vidibus-recording'` to the Gemfile of your application. Then call `bundle install` on your console.
|
11
|
+
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
### Available methods
|
16
|
+
|
17
|
+
To control a recording, you may use these methods:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
recording.start # starts recording
|
21
|
+
recording.stop # stops recording
|
22
|
+
recording.resume # continues if recording has been started but is not running
|
23
|
+
recording.restart # erases recorded data and restarts recording
|
24
|
+
```
|
25
|
+
|
26
|
+
|
27
|
+
### Custom class names
|
28
|
+
|
29
|
+
This gem will set up a model `Recording` if Rails is around. If you want to use the recording logic inside of a custom model, you just have to include the module `Vidibus::Recording::Mongoid`:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
class MyCustomRecording
|
33
|
+
include Mongoid::Document
|
34
|
+
include Vidibus::Recording::Mongoid
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
### Monitoring
|
40
|
+
|
41
|
+
If the worker process does not receive data, it will halt the recording. To monitor and restart a recording perform `Vidibus::Recording.monitor`. Beware, this method is blocking, so better spawn the daemon.
|
42
|
+
|
43
|
+
|
44
|
+
#### Monitoring daemon
|
45
|
+
|
46
|
+
To run the monitor as daemon, this gem provides a shell script. Install it with
|
47
|
+
|
48
|
+
```
|
49
|
+
rails g vidibus:recording
|
50
|
+
```
|
51
|
+
|
52
|
+
The daemon requires that `gem 'daemons'` is installed. To spawn him, enter
|
53
|
+
|
54
|
+
```
|
55
|
+
script/recording start
|
56
|
+
```
|
57
|
+
|
58
|
+
#### Possible caveat
|
59
|
+
|
60
|
+
To monitor your custom recording classes, `Vidibus::Recording.monitor` requires that all classes that include `Vidibus::Recording::Mongoid` have been loaded.
|
61
|
+
|
62
|
+
Because Rails is autoloading almost everything in development, this requirement is not met without the help of a little hack: To trigger autoloading, the monitor collects all aforementioned class names from the `app` directory and constantizes them.
|
63
|
+
|
64
|
+
**So here's the caveat:** If you define custom recording models outside of the `app` directory, you'll have to let the listener know. An initializer is perfect for that:
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
# Collect all recording models in lib, too
|
68
|
+
Vidibus::Recording.autoload_paths << '/lib/**/*.rb'
|
69
|
+
```
|
70
|
+
|
71
|
+
|
72
|
+
## Deployment
|
73
|
+
|
74
|
+
A Capistrano configuration is included. Require it in your Capistrano `config.rb`.
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
require 'vidibus/recording/capistrano'
|
78
|
+
```
|
79
|
+
|
80
|
+
That will add a bunch of callback hooks.
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
after 'deploy:stop', 'vidibus:recording:stop'
|
84
|
+
after 'deploy:start', 'vidibus:recording:start'
|
85
|
+
after 'deploy:restart', 'vidibus:recording:restart'
|
86
|
+
```
|
87
|
+
|
88
|
+
If you need more control over the callbacks, you may load just the recipes without the hooks.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
require 'vidibus/recording/capistrano/recipes'
|
92
|
+
```
|
93
|
+
|
94
|
+
|
95
|
+
## Testing
|
96
|
+
|
97
|
+
To test this gem, call `bundle install` and `bundle exec rspec spec` on your console.
|
98
|
+
|
99
|
+
|
100
|
+
## Copyright
|
101
|
+
|
102
|
+
© 2011-2013 André Pankratz. See LICENSE for details.
|
@@ -1,6 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require File.expand_path('../../config/environment', __FILE__)
|
4
|
-
require 'vidibus/
|
4
|
+
require 'vidibus/recording/daemon'
|
5
5
|
|
6
|
-
Vidibus::
|
6
|
+
Vidibus::Recording.monitoring_interval = 1 # second
|
7
|
+
Vidibus::Recording.autoload_paths << Rails.root.join('app/**/*.rb')
|
8
|
+
Vidibus::Recording::Daemon.new(ARGV).daemonize
|
@@ -79,7 +79,7 @@ module Vidibus::Recording::Backend
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
-
#
|
82
|
+
# Detect error from stdout or stderr.
|
83
83
|
# Output delivered by rtmpdump looks like this:
|
84
84
|
#
|
85
85
|
# RTMPDump v2.4
|
@@ -88,9 +88,12 @@ module Vidibus::Recording::Backend
|
|
88
88
|
# ERROR: Problem accessing the DNS. (addr: whatever.domain)
|
89
89
|
#
|
90
90
|
def detect_error(string)
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
if error = string[/(?:ERROR\:\ (.+))/,1]
|
92
|
+
case error
|
93
|
+
when 'rtmp server sent error'
|
94
|
+
else
|
95
|
+
raise RuntimeError.new($1)
|
96
|
+
end
|
94
97
|
end
|
95
98
|
end
|
96
99
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'vidibus/recording/capistrano/recipes'
|
2
2
|
|
3
|
-
# Run Capistrano Recipes for
|
3
|
+
# Run Capistrano Recipes for monitoring recordings.
|
4
4
|
#
|
5
5
|
# Load this file from your Capistrano config.rb:
|
6
|
-
# require 'vidibus/
|
6
|
+
# require 'vidibus/recording/capistrano'
|
7
7
|
#
|
8
8
|
Capistrano::Configuration.instance.load do
|
9
|
-
after 'deploy:stop', 'vidibus:
|
10
|
-
after 'deploy:start', 'vidibus:
|
11
|
-
after 'deploy:restart', 'vidibus:
|
9
|
+
after 'deploy:stop', 'vidibus:recording:stop'
|
10
|
+
after 'deploy:start', 'vidibus:recording:start'
|
11
|
+
after 'deploy:restart', 'vidibus:recording:restart'
|
12
12
|
end
|
@@ -6,7 +6,7 @@ end
|
|
6
6
|
require 'optparse'
|
7
7
|
|
8
8
|
module Vidibus
|
9
|
-
module
|
9
|
+
module Recording
|
10
10
|
class Daemon
|
11
11
|
|
12
12
|
def initialize(args)
|
@@ -34,10 +34,10 @@ module Vidibus
|
|
34
34
|
def run
|
35
35
|
Dir.chdir(Rails.root)
|
36
36
|
log = File.join(Rails.root, 'log', 'recording.log')
|
37
|
-
Vidibus::
|
38
|
-
Vidibus::
|
37
|
+
Vidibus::Recording.logger = ActiveSupport::BufferedLogger.new(log)
|
38
|
+
Vidibus::Recording.monitor
|
39
39
|
rescue => e
|
40
|
-
Vidibus::
|
40
|
+
Vidibus::Recording.logger.fatal(e)
|
41
41
|
STDERR.puts(e.message)
|
42
42
|
exit 1
|
43
43
|
end
|
@@ -1,3 +1,8 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
require 'vidibus-uuid'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
require 'delayed_job_mongoid'
|
5
|
+
|
1
6
|
module Vidibus::Recording
|
2
7
|
module Mongoid
|
3
8
|
extend ActiveSupport::Concern
|
@@ -10,7 +15,6 @@ module Vidibus::Recording
|
|
10
15
|
|
11
16
|
field :name
|
12
17
|
field :stream
|
13
|
-
# field :live, :type => Boolean
|
14
18
|
field :pid, :type => Integer
|
15
19
|
field :info, :type => Hash
|
16
20
|
field :size, :type => Integer
|
@@ -20,13 +24,17 @@ module Vidibus::Recording
|
|
20
24
|
field :started_at, :type => DateTime
|
21
25
|
field :stopped_at, :type => DateTime
|
22
26
|
field :failed_at, :type => DateTime
|
27
|
+
field :active, :type => Boolean, :default => false
|
23
28
|
field :running, :type => Boolean, :default => false
|
24
|
-
|
29
|
+
|
30
|
+
index :active
|
25
31
|
|
26
32
|
validates :name, :presence => true
|
27
33
|
validates :stream, :format => {:with => /^rtmp.*?:\/\/.+$/}
|
28
34
|
|
29
35
|
before_destroy :cleanup
|
36
|
+
|
37
|
+
scope :active, where(active: true)
|
30
38
|
end
|
31
39
|
|
32
40
|
# Starts a recording worker now, unless it has been done already.
|
@@ -35,8 +43,8 @@ module Vidibus::Recording
|
|
35
43
|
return false if done? || started?
|
36
44
|
if time == :now
|
37
45
|
self.started_at = Time.now
|
46
|
+
self.active = true
|
38
47
|
start_worker
|
39
|
-
start_monitoring_job
|
40
48
|
save!
|
41
49
|
else
|
42
50
|
schedule(time)
|
@@ -48,8 +56,8 @@ module Vidibus::Recording
|
|
48
56
|
return false if running? || !started?
|
49
57
|
self.stopped_at = nil
|
50
58
|
self.failed_at = nil
|
59
|
+
self.active = true
|
51
60
|
start_worker
|
52
|
-
start_monitoring_job
|
53
61
|
save!
|
54
62
|
end
|
55
63
|
|
@@ -67,7 +75,7 @@ module Vidibus::Recording
|
|
67
75
|
self.pid = nil
|
68
76
|
self.stopped_at = Time.now
|
69
77
|
self.running = false
|
70
|
-
self.
|
78
|
+
self.active = false
|
71
79
|
postprocess
|
72
80
|
end
|
73
81
|
|
@@ -89,6 +97,7 @@ module Vidibus::Recording
|
|
89
97
|
self.error = msg
|
90
98
|
self.failed_at = Time.now
|
91
99
|
self.running = false
|
100
|
+
self.active = false
|
92
101
|
postprocess
|
93
102
|
end
|
94
103
|
|
@@ -104,8 +113,7 @@ module Vidibus::Recording
|
|
104
113
|
:info,
|
105
114
|
:error,
|
106
115
|
:size,
|
107
|
-
:duration
|
108
|
-
:monitoring_job_identifier
|
116
|
+
:duration
|
109
117
|
].map {|a| blank[a] = nil }
|
110
118
|
update_attributes!(blank)
|
111
119
|
destroy_all_parts
|
@@ -222,16 +230,6 @@ module Vidibus::Recording
|
|
222
230
|
self.pid = worker.pid
|
223
231
|
end
|
224
232
|
|
225
|
-
# Start a new monitoring job
|
226
|
-
def start_monitoring_job
|
227
|
-
self.monitoring_job_identifier = Vidibus::Uuid.generate
|
228
|
-
Vidibus::Recording::MonitoringJob.create({
|
229
|
-
:class_name => self.class.to_s,
|
230
|
-
:uuid => uuid,
|
231
|
-
:identifier => monitoring_job_identifier
|
232
|
-
})
|
233
|
-
end
|
234
|
-
|
235
233
|
def setup_next_part
|
236
234
|
number = nil
|
237
235
|
if current_part
|
@@ -1,11 +1,12 @@
|
|
1
|
+
require 'open3'
|
1
2
|
require 'timeout'
|
2
3
|
|
3
4
|
module Vidibus::Recording
|
4
5
|
class Worker
|
5
6
|
class ProcessError < StandardError; end
|
6
7
|
|
7
|
-
|
8
|
-
STOP_TIMEOUT =
|
8
|
+
START_TIMEOUT = 20
|
9
|
+
STOP_TIMEOUT = 2
|
9
10
|
|
10
11
|
attr_accessor :recording, :pid, :metadata
|
11
12
|
|
@@ -33,8 +34,7 @@ module Vidibus::Recording
|
|
33
34
|
Timeout::timeout(STOP_TIMEOUT) do
|
34
35
|
begin
|
35
36
|
log("Stopping process #{pid}...")
|
36
|
-
|
37
|
-
Process.kill('SIGQUIT', pid)
|
37
|
+
Process.kill('SIGTERM', pid)
|
38
38
|
Process.wait(pid)
|
39
39
|
log('STOPPED')
|
40
40
|
rescue Errno::ECHILD
|
@@ -73,8 +73,8 @@ module Vidibus::Recording
|
|
73
73
|
def record
|
74
74
|
cmd = recording.backend.command
|
75
75
|
log("START: #{recording.stream}", true)
|
76
|
+
timeout = Time.now + START_TIMEOUT
|
76
77
|
Open3::popen3(cmd) do |stdin, stdout, stderr|
|
77
|
-
maxloops = 10
|
78
78
|
loop do
|
79
79
|
begin
|
80
80
|
string = stdout.read_nonblock(1024).force_encoding('UTF-8')
|
@@ -90,12 +90,11 @@ module Vidibus::Recording
|
|
90
90
|
fail(e.message) && break
|
91
91
|
end
|
92
92
|
unless metadata
|
93
|
-
|
94
|
-
|
95
|
-
halt('No Metadata has been received so far.') && break
|
93
|
+
if Time.now > timeout
|
94
|
+
halt('No Metadata has been received so far, exiting.') && break
|
96
95
|
end
|
97
96
|
end
|
98
|
-
sleep
|
97
|
+
sleep(2)
|
99
98
|
end
|
100
99
|
end
|
101
100
|
end
|
data/lib/vidibus/recording.rb
CHANGED
@@ -1,6 +1,65 @@
|
|
1
1
|
require 'vidibus/recording/worker'
|
2
|
-
require 'vidibus/recording/monitoring_job'
|
3
2
|
require 'vidibus/recording/backend'
|
4
3
|
require 'vidibus/recording/helpers'
|
5
4
|
require 'vidibus/recording/part'
|
6
5
|
require 'vidibus/recording/mongoid'
|
6
|
+
require 'vidibus/recording/railtie' if defined?(Rails::Railtie)
|
7
|
+
|
8
|
+
module Vidibus
|
9
|
+
module Recording
|
10
|
+
extend self
|
11
|
+
|
12
|
+
class Error < StandardError; end
|
13
|
+
|
14
|
+
INTERVAL = 1
|
15
|
+
|
16
|
+
attr_accessor :logger, :autoload_paths, :classes, :monitoring_interval
|
17
|
+
@logger = Logger.new(STDOUT)
|
18
|
+
@autoload_paths = []
|
19
|
+
@classes = []
|
20
|
+
@monitoring_interval = 1
|
21
|
+
|
22
|
+
# Monitor all started recordings
|
23
|
+
def monitor
|
24
|
+
autoload
|
25
|
+
unless classes.any?
|
26
|
+
logger.error("[#{Time.now.utc}] - No recording classes given")
|
27
|
+
else
|
28
|
+
logger.info("[#{Time.now.utc}] - Watching recordings")
|
29
|
+
run
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Obtain all classes that include the Mongoid module
|
34
|
+
def autoload
|
35
|
+
return [] unless autoload_paths.any?
|
36
|
+
regexp = /class ([^<\n]+).+include Vidibus::Recording::Mongoid/m
|
37
|
+
names = Dir[*autoload_paths].map do |f|
|
38
|
+
File.read(f)[regexp, 1]
|
39
|
+
end.compact
|
40
|
+
self.classes = names.map { |k| k.constantize }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def run
|
46
|
+
loop do
|
47
|
+
classes.each do |klass|
|
48
|
+
klass.active.each do |recording|
|
49
|
+
begin
|
50
|
+
if recording.worker_running?
|
51
|
+
recording.track_progress
|
52
|
+
else
|
53
|
+
logger.info("[#{Time.now.utc}] - Resuming #{recording.class.name} #{recording.uuid}")
|
54
|
+
recording.resume
|
55
|
+
end
|
56
|
+
rescue => e
|
57
|
+
logger.error("[#{Time.now.utc}] - ERROR:\n#{e.inspect}\n---\n#{e.backtrace.join("\n")}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
sleep(monitoring_interval)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/vidibus-recording.rb
CHANGED
@@ -1,15 +1 @@
|
|
1
|
-
require 'open3'
|
2
|
-
require 'yaml'
|
3
|
-
require 'delayed_job_mongoid'
|
4
|
-
require 'active_support/core_ext'
|
5
|
-
require 'vidibus-uuid'
|
6
|
-
|
7
|
-
module Vidibus
|
8
|
-
module Recording
|
9
|
-
if defined?(Rails)
|
10
|
-
class Engine < ::Rails::Engine; end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
1
|
require 'vidibus/recording'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vidibus-recording
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-01 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: '2'
|
37
|
+
version: '2.5'
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: '2'
|
45
|
+
version: '2.5'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: delayed_job_mongoid
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -179,7 +179,6 @@ extra_rdoc_files: []
|
|
179
179
|
files:
|
180
180
|
- lib/generators/vidibus/recording_generator.rb
|
181
181
|
- lib/generators/vidibus/templates/script
|
182
|
-
- lib/vidibus/recording/backend/railtie.rb
|
183
182
|
- lib/vidibus/recording/backend/rtmpdump.rb
|
184
183
|
- lib/vidibus/recording/backend.rb
|
185
184
|
- lib/vidibus/recording/capistrano/recipes.rb
|
@@ -187,7 +186,6 @@ files:
|
|
187
186
|
- lib/vidibus/recording/daemon.rb
|
188
187
|
- lib/vidibus/recording/helpers.rb
|
189
188
|
- lib/vidibus/recording/mongoid.rb
|
190
|
-
- lib/vidibus/recording/monitoring_job.rb
|
191
189
|
- lib/vidibus/recording/part.rb
|
192
190
|
- lib/vidibus/recording/railtie.rb
|
193
191
|
- lib/vidibus/recording/version.rb
|
@@ -196,7 +194,7 @@ files:
|
|
196
194
|
- lib/vidibus-recording.rb
|
197
195
|
- app/models/recording.rb
|
198
196
|
- LICENSE
|
199
|
-
- README.
|
197
|
+
- README.md
|
200
198
|
- Rakefile
|
201
199
|
homepage: https://github.com/vidibus/vidibus-recording
|
202
200
|
licenses: []
|
@@ -212,7 +210,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
212
210
|
version: '0'
|
213
211
|
segments:
|
214
212
|
- 0
|
215
|
-
hash:
|
213
|
+
hash: 507116490268825761
|
216
214
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
215
|
none: false
|
218
216
|
requirements:
|
data/README.rdoc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
railtie.rb
|
@@ -1,52 +0,0 @@
|
|
1
|
-
module Vidibus::Recording
|
2
|
-
class MonitoringJob
|
3
|
-
INTERVAL = 10.seconds
|
4
|
-
|
5
|
-
def initialize(args)
|
6
|
-
unless @uuid = args[:uuid]
|
7
|
-
raise(ArgumentError, 'No recording UUID given')
|
8
|
-
end
|
9
|
-
unless @class_name = args[:class_name]
|
10
|
-
raise(ArgumentError, 'Must provide class name of recording')
|
11
|
-
end
|
12
|
-
unless @identifier = args[:identifier]
|
13
|
-
raise(ArgumentError, 'Must provide identifier of monitoring job')
|
14
|
-
end
|
15
|
-
ensure_recording
|
16
|
-
end
|
17
|
-
|
18
|
-
def perform
|
19
|
-
r = recording.reload
|
20
|
-
return unless r.monitoring_job_identifier == @identifier
|
21
|
-
if r.worker_running?
|
22
|
-
r.track_progress
|
23
|
-
run_again
|
24
|
-
elsif !r.stopped?
|
25
|
-
r.resume
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Returns job
|
30
|
-
def self.create(args)
|
31
|
-
job = new(args)
|
32
|
-
Delayed::Job.enqueue(job)
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def recording
|
38
|
-
@class_name.constantize.where(:uuid => @uuid).first
|
39
|
-
end
|
40
|
-
|
41
|
-
def ensure_recording
|
42
|
-
recording || raise(ArgumentError, 'No valid recording UUID given')
|
43
|
-
end
|
44
|
-
|
45
|
-
def run_again
|
46
|
-
obj = self.class.new({
|
47
|
-
:uuid => @uuid, :class_name => @class_name, :identifier => @identifier
|
48
|
-
})
|
49
|
-
Delayed::Job.enqueue(obj, 0, INTERVAL.from_now)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|