mediakit 0.0.2 → 0.0.3

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: 6bce22e6bb5655d6ef5522dfb86cd95660b56119
4
- data.tar.gz: 4ae5b7f5a0c1348aa22de26b0da11a80c47f0f05
3
+ metadata.gz: b89173bcea5b5f50317e32e2034f49d28826f241
4
+ data.tar.gz: df29a2019137bc3524e5936eb240edc8694b9910
5
5
  SHA512:
6
- metadata.gz: 67789568de47730bc876c7be8971d45bfa6e69179cb227abd4052a390e41aea7eb52939932b144a27bcc2752abe02c690361e88c8e8b9f5973ae3a2897d8ed54
7
- data.tar.gz: 8db964b6558ceec920bc45833bcb7e57cccc1a5f6891c69540c40b3934a35761feb7d02f440f0abb0bbfda304bf463c02de0b20b3d21cab73f8854032dc751ef
6
+ metadata.gz: 4277da4ec46a39da0570ad8d06380103890fa7e3fc80b11d2a257b514bf00fccc3c68a3feb7c6aaa48c7a543b266da2302e8ec2ab3340cac256a027d0062fa20
7
+ data.tar.gz: ca904cac4f9c3d92911db53dd344610bf06616b9c76ff982790230c24fde0e00c608cebe755406b50bdc97b9ca4a22ea14a0deffccf77c54be0474af44efa7cb
data/.travis.yml CHANGED
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
+ cache:
3
+ bundler: true
2
4
  rvm:
3
5
  - 2.2.0
4
6
  before_install:
5
- - gem update --system
6
- - gem update bundler
7
- - gem --version
7
+ - bundler --version
8
+ - gem --version
@@ -2,7 +2,7 @@ require 'shellwords'
2
2
  require 'open3'
3
3
  require 'thread'
4
4
  require 'timeout'
5
-
5
+ require 'cool.io'
6
6
 
7
7
  module Mediakit
8
8
  module Utils
@@ -12,8 +12,9 @@ module Mediakit
12
12
  class TimeoutError < StandardError;
13
13
  end
14
14
 
15
- def initialize(timeout: nil)
15
+ def initialize(timeout: nil, nice: 0)
16
16
  @timeout = timeout
17
+ @nice = nice
17
18
  end
18
19
 
19
20
  # @overload run(command, *args)
@@ -26,37 +27,51 @@ module Mediakit
26
27
  # @return err [String] stderr of command
27
28
  # @return exit_status [Boolean] is succeeded
28
29
  def run(bin, *args)
29
- command = self.class.command(bin, *args)
30
-
31
- pid, out, err, exit_status = nil
30
+ command = build_command(bin, *args)
31
+ pid, exit_status = nil
32
32
  out_reader, err_reader = nil
33
- watch = TimeoutWatch.new(@timeout)
33
+ loop = Coolio::Loop.new
34
34
  begin
35
35
  stdin, stdout, stderr, wait_thr = Open3.popen3(command)
36
36
  stdin.close
37
37
  pid = wait_thr.pid
38
- watch.start(Thread.current)
39
- out_reader = IOReader.new(stdout) { |chunk| watch.update }
40
- err_reader = IOReader.new(stderr) { |chunk| watch.update }
41
-
38
+ timer = TimeoutTimer.new(@timeout, Thread.current)
39
+ timer.attach(loop)
40
+ out_watcher = IOWatcher.new(stdout) { timer.update }
41
+ out_watcher.attach(loop)
42
+ err_watcher = IOWatcher.new(stderr) { timer.update }
43
+ err_watcher.attach(loop)
44
+ loop_thread = Thread.new do
45
+ loop.run
46
+ end
42
47
  wait_thr.join
43
48
  exit_status = (wait_thr.value.exitstatus == 0)
44
49
  rescue Errno::ENOENT => e
45
50
  raise(CommandNotFoundError, "Can't find command - #{command}, #{e.meessage}")
46
51
  rescue Timeout::Error => error
47
- Process.kill('SIGKILL', pid)
52
+ safe_kill_process(pid)
48
53
  raise(error)
49
54
  ensure
50
- out_reader.finish
51
- err_reader.finish
52
- watch.finish
55
+ out_watcher.close if out_watcher
56
+ err_watcher.close if err_watcher
57
+ timer.detach if timer
58
+ loop_thread.join
53
59
  end
54
60
 
55
- [out_reader.data, err_reader.data, exit_status]
61
+ [out_watcher.data, err_watcher.data, exit_status]
56
62
  end
57
63
 
58
- def self.command(bin, *args)
59
- escaped_args = escape(*args)
64
+ def build_command(bin, *args)
65
+ command = build_command_without_options(bin, *args)
66
+ unless @nice == 0
67
+ "nice -n #{@nice} sh -c \"#{command}\""
68
+ else
69
+ command
70
+ end
71
+ end
72
+
73
+ def build_command_without_options(bin, *args)
74
+ escaped_args = self.class.escape(*args)
60
75
  "#{bin} #{escaped_args}"
61
76
  end
62
77
 
@@ -77,69 +92,42 @@ module Mediakit
77
92
  splits.join(' ')
78
93
  end
79
94
 
80
- class IOReader
95
+ def safe_kill_process(pid)
96
+ Process.kill('SIGKILL', pid)
97
+ rescue Errno::ESRCH
98
+ warn 'already killedd'
99
+ end
100
+
101
+ class IOWatcher < Coolio::IO
81
102
  attr_reader(:data)
82
103
 
83
104
  def initialize(io, &block)
84
- raise(ArgumentError) unless block_given?
85
- @io = io
86
- @data = ''
87
105
  @block = block
88
- start
89
- end
90
-
91
- def finish
92
- @thread.join
93
- @thread.kill
106
+ @data = ''
107
+ super
94
108
  end
95
109
 
96
- private
97
- def start
98
- @thread = Thread.new { read }
99
- nil
100
- end
101
-
102
- def read
103
- return if @io.closed?
104
- begin
105
- while chunk = @io.gets
106
- @data << chunk
107
- @block.call(chunk) if @block
108
- end
109
- rescue IOError => e
110
- warn "[WARN] IOError #{e.message}"
111
- ensure
112
- @io.close unless @io.closed?
113
- end
110
+ def on_read(data)
111
+ @data << data
112
+ @block.call(self)
114
113
  end
115
114
  end
116
115
 
117
- # watch process progress by io.
118
- # when wait time exceed duration, then kill process.
119
- class TimeoutWatch
120
- attr_reader(:duration)
116
+ class TimeoutTimer < Coolio::TimerWatcher
117
+ DEFAULT_CHECK_INTERVAL = 0.1
121
118
 
122
- def initialize(duration)
123
- @duration = duration
119
+ def initialize(duration, current_thread)
120
+ @mutex = Mutex.new
121
+ @duration = duration
124
122
  @watched_at = Time.now
125
- @mutex = Mutex.new
126
- end
127
-
128
- def start(current_thread, &block)
129
123
  @current_thread = current_thread
130
- @watch_thread = Thread.new do
131
- loop do
132
- if timeout?
133
- @current_thread.raise(Timeout::Error, "wait timeout error with #{duration} sec.")
134
- end
135
- sleep(0.1)
136
- end
137
- end
138
- nil
124
+ super(DEFAULT_CHECK_INTERVAL, true)
139
125
  end
140
126
 
141
- def finish
142
- @watch_thread.kill
127
+ def on_timer
128
+ if timeout?
129
+ @current_thread.raise(Timeout::Error, "wait timeout error with #{@duration} sec.")
130
+ end
143
131
  end
144
132
 
145
133
  def update
@@ -151,7 +139,8 @@ module Mediakit
151
139
  private
152
140
 
153
141
  def timeout?
154
- (Time.now - @watched_at) > duration
142
+ # compare duration into first decimal place by integer
143
+ ((Time.now - @watched_at) * 10).floor >= (@duration * 10).floor
155
144
  end
156
145
  end
157
146
  end
@@ -1,3 +1,3 @@
1
1
  module Mediakit
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/mediakit.gemspec CHANGED
@@ -24,6 +24,7 @@ EOS
24
24
 
25
25
  spec.add_runtime_dependency "cocaine", "~> 0.5.7"
26
26
  spec.add_runtime_dependency "activesupport", "~> 4"
27
+ spec.add_runtime_dependency "cool.io", "~> 1.3"
27
28
  spec.add_development_dependency "rake", "~> 10.0"
28
29
  spec.add_development_dependency "pry", '~> 0.10'
29
30
  spec.add_development_dependency "ruby-debug-ide", "~> 0.4"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mediakit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ainame
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-05-12 00:00:00.000000000 Z
11
+ date: 2015-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cocaine
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cool.io
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -144,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
158
  version: '0'
145
159
  requirements: []
146
160
  rubyforge_project:
147
- rubygems_version: 2.4.6
161
+ rubygems_version: 2.4.5
148
162
  signing_key:
149
163
  specification_version: 4
150
164
  summary: mediakit is the libraries for ffmpeg and sox backed media manipulation something.