dynosaur 0.1.0 → 0.2.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/README.md +7 -0
- data/Rakefile +0 -19
- data/lib/dynosaur/process/heroku/finder.rb +34 -0
- data/lib/dynosaur/process/heroku.rb +3 -5
- data/lib/dynosaur/process/local/finder.rb +23 -0
- data/lib/dynosaur/process/local.rb +2 -3
- data/lib/dynosaur/process.rb +8 -11
- data/lib/dynosaur/utils/os.rb +24 -0
- data/lib/dynosaur/utils/rake_command.rb +45 -0
- data/lib/dynosaur/version.rb +1 -1
- data/lib/dynosaur.rb +7 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1448d342f89404da10452e0e95176627f5c7ed56
|
4
|
+
data.tar.gz: ffe0d95b07ad64c410d89e4645289faa107c7cf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06a80b1d43a568785eee94acab44b02a260d4a61e83bd2502886ab2abd1dc0c2c9bf647b37b8a23ddec22a260455024a66ffd4192df89fdb7139af767387cfce
|
7
|
+
data.tar.gz: f0d630594d61500d65d7eafa207c33c36ac622d5af7f89fd63ebb0d7c6dda2649aa7ca20a1c65bcd198f92acf8bb4b4aaeaa2ad20bea3e9ff3593ffd0e18c030
|
data/README.md
CHANGED
@@ -35,6 +35,13 @@ local_process.start
|
|
35
35
|
# => 48345
|
36
36
|
```
|
37
37
|
|
38
|
+
You can also check to see if a similar rake task is already running before starting
|
39
|
+
the task (e.g. if you want at most one instance of that task running concurrently)
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
dyno = Dynosaur::Process::Heroku.new(task: 'session:destroy', args: [2500])
|
43
|
+
dyno.start unless dyno.running?
|
44
|
+
```
|
38
45
|
|
39
46
|
## Development
|
40
47
|
|
data/Rakefile
CHANGED
@@ -5,22 +5,3 @@ require 'rspec/core/rake_task'
|
|
5
5
|
RSpec::Core::RakeTask.new(:spec)
|
6
6
|
|
7
7
|
task default: :spec
|
8
|
-
|
9
|
-
task :echo, [:arg1, :arg2] do |_task, args|
|
10
|
-
puts %Q(ARG1: "#{args[:arg1]}")
|
11
|
-
puts %Q(ARG2: "#{args[:arg2]}")
|
12
|
-
end
|
13
|
-
|
14
|
-
task :sleep, [:duration] do |_task, args|
|
15
|
-
File.open('/tmp/sleep', 'w') do |file|
|
16
|
-
file.puts "Sleeping"
|
17
|
-
args[:duration].to_i.times do
|
18
|
-
sleep(1)
|
19
|
-
file.print('.')
|
20
|
-
file.flush
|
21
|
-
end
|
22
|
-
file.print("\n")
|
23
|
-
file.puts "Awake"
|
24
|
-
file.flush
|
25
|
-
end
|
26
|
-
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Detects if a running dyno is currently executing the rake command
|
2
|
+
module Dynosaur
|
3
|
+
class Process
|
4
|
+
class Heroku
|
5
|
+
class Finder
|
6
|
+
def initialize(rake_command:, client: Client::HerokuClient.client)
|
7
|
+
@rake_command = rake_command
|
8
|
+
@client = client
|
9
|
+
end
|
10
|
+
|
11
|
+
def exists?
|
12
|
+
one_off_dynos.any? do |dyno|
|
13
|
+
Utils::RakeCommand.valid?(dyno.command) &&
|
14
|
+
Utils::RakeCommand.parse(dyno.command) == rake_command
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :rake_command, :client
|
21
|
+
|
22
|
+
# @return [Array] Object instances, which respond to #command, for all
|
23
|
+
# locally one off dynos
|
24
|
+
def one_off_dynos
|
25
|
+
app_name = Dynosaur::Client::HerokuClient.app_name
|
26
|
+
dynos = client.dyno.list(app_name).map do |response|
|
27
|
+
Struct.new(:type, :command).new(response['type'], response['command'])
|
28
|
+
end
|
29
|
+
dynos.select { |dyno| dyno.type == 'run' }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'dynosaur/client/heroku_client'
|
2
2
|
|
3
|
-
require_relative '../process'
|
4
|
-
|
5
3
|
# Start a detached rake task on a one-off dyno
|
6
4
|
module Dynosaur
|
7
5
|
class Process
|
@@ -23,10 +21,10 @@ module Dynosaur
|
|
23
21
|
|
24
22
|
def start
|
25
23
|
app_name = Dynosaur::Client::HerokuClient.app_name
|
26
|
-
|
27
|
-
create_opts = { command: rake_command, attach: false }
|
24
|
+
client = Dynosaur::Client::HerokuClient.client
|
25
|
+
create_opts = { command: rake_command.to_s, attach: false }
|
28
26
|
create_opts[:size] = size if size
|
29
|
-
response =
|
27
|
+
response = client.dyno.create(app_name, create_opts)
|
30
28
|
response['name']
|
31
29
|
end
|
32
30
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Detects if a running process is currently executing the rake command
|
2
|
+
module Dynosaur
|
3
|
+
class Process
|
4
|
+
class Local
|
5
|
+
class Finder
|
6
|
+
def initialize(rake_command:)
|
7
|
+
@rake_command = rake_command
|
8
|
+
end
|
9
|
+
|
10
|
+
def exists?
|
11
|
+
Utils::OS.structured_ps.any? do |process|
|
12
|
+
Utils::RakeCommand.valid?(process.command) &&
|
13
|
+
Utils::RakeCommand.parse(process.command) == rake_command
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :rake_command
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,10 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# Start the rake task in a local process
|
3
2
|
module Dynosaur
|
4
3
|
class Process
|
5
4
|
class Local < Process
|
6
5
|
def start
|
7
|
-
pid = ::Process.spawn(rake_command)
|
6
|
+
pid = ::Process.spawn(rake_command.to_s)
|
8
7
|
::Process.detach(pid)
|
9
8
|
pid
|
10
9
|
end
|
data/lib/dynosaur/process.rb
CHANGED
@@ -3,29 +3,26 @@ require 'shellwords'
|
|
3
3
|
module Dynosaur
|
4
4
|
class Process
|
5
5
|
def initialize(task:, args: [], opts: {})
|
6
|
-
@
|
7
|
-
@args = args
|
6
|
+
@rake_command = Utils::RakeCommand.new(task: task, args: args)
|
8
7
|
after_initialize(opts)
|
9
8
|
end
|
10
9
|
|
10
|
+
def running?
|
11
|
+
klass = self.class.const_get('Finder')
|
12
|
+
finder = klass.new(rake_command: rake_command)
|
13
|
+
finder.exists?
|
14
|
+
end
|
15
|
+
|
11
16
|
def start
|
12
17
|
fail NotImplementedError, 'This method must be implemented in a subclass'
|
13
18
|
end
|
14
19
|
|
15
20
|
private
|
16
21
|
|
17
|
-
attr_reader :
|
22
|
+
attr_reader :rake_command
|
18
23
|
|
19
24
|
def after_initialize(opts)
|
20
25
|
# Do nothing so subclasses don't have to override if they want a no-op
|
21
26
|
end
|
22
|
-
|
23
|
-
def rake_command
|
24
|
-
formatted_args = args.map do |arg|
|
25
|
-
arg.is_a?(String) ? arg.shellescape : arg
|
26
|
-
end.join(',')
|
27
|
-
task_with_args = args.empty? ? task : "#{task}[#{formatted_args}]"
|
28
|
-
"rake #{task_with_args} --trace"
|
29
|
-
end
|
30
27
|
end
|
31
28
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Utility methods for interacting with the underlying OS
|
2
|
+
module Dynosaur
|
3
|
+
module Utils
|
4
|
+
module OS
|
5
|
+
class << self
|
6
|
+
# @return [Array] Object instances, which respond to #command, for all
|
7
|
+
# locally running processes returned by the ps command
|
8
|
+
def structured_ps
|
9
|
+
ps_array = command_ps.split("\n").map(&:strip)
|
10
|
+
ps_array.shift # Remove the header row
|
11
|
+
ps_array.map do |command|
|
12
|
+
Struct.new(:command).new(command)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def command_ps
|
19
|
+
`ps -o command`
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Utility methods for generating and parsing rake command
|
2
|
+
module Dynosaur
|
3
|
+
module Utils
|
4
|
+
class RakeCommand
|
5
|
+
PARSE_REGEX = /\brake\s+([\w:]+)(\[.*\])?/
|
6
|
+
|
7
|
+
attr_reader :task, :args
|
8
|
+
|
9
|
+
# @param command [String] the command to test for validity
|
10
|
+
# @return [true|false] true iff the string is a valid rake command
|
11
|
+
def self.valid?(command)
|
12
|
+
!(command =~ PARSE_REGEX).nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param command [String] the command to parse
|
16
|
+
# @return [RakeCommand] an instance that represents the command being parsed
|
17
|
+
# @raise [ArgumentError] if the command is not a valid rake command
|
18
|
+
def self.parse(command)
|
19
|
+
match = command.match(PARSE_REGEX)
|
20
|
+
raise ArgumentError, %Q(Invalid rake command: "#{command}") unless match
|
21
|
+
task = match[1]
|
22
|
+
args = match[2] ? match[2].tr('[]', '').split(',') : []
|
23
|
+
new(task: task, args: args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(task:, args: [])
|
27
|
+
@task = task
|
28
|
+
@args = args
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] the full rake command, including arguments
|
32
|
+
def to_s
|
33
|
+
formatted_args = args.map do |arg|
|
34
|
+
arg.is_a?(String) ? arg.shellescape : arg
|
35
|
+
end.join(',')
|
36
|
+
task_with_args = args.empty? ? task : "#{task}[#{formatted_args}]"
|
37
|
+
"rake #{task_with_args} --trace"
|
38
|
+
end
|
39
|
+
|
40
|
+
def ==(other)
|
41
|
+
task == other.task && args.map(&:to_s) == other.args.map(&:to_s)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/dynosaur/version.rb
CHANGED
data/lib/dynosaur.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'dynosaur/version'
|
2
|
+
|
3
|
+
require 'dynosaur/process'
|
2
4
|
require 'dynosaur/process/heroku'
|
5
|
+
require 'dynosaur/process/heroku/finder'
|
3
6
|
require 'dynosaur/process/local'
|
7
|
+
require 'dynosaur/process/local/finder'
|
8
|
+
|
9
|
+
require 'dynosaur/utils/os'
|
10
|
+
require 'dynosaur/utils/rake_command'
|
4
11
|
|
5
12
|
# Spin up a rake task in a separate process
|
6
13
|
module Dynosaur
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynosaur
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Collier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: platform-api
|
@@ -117,7 +117,11 @@ files:
|
|
117
117
|
- lib/dynosaur/client/heroku_client.rb
|
118
118
|
- lib/dynosaur/process.rb
|
119
119
|
- lib/dynosaur/process/heroku.rb
|
120
|
+
- lib/dynosaur/process/heroku/finder.rb
|
120
121
|
- lib/dynosaur/process/local.rb
|
122
|
+
- lib/dynosaur/process/local/finder.rb
|
123
|
+
- lib/dynosaur/utils/os.rb
|
124
|
+
- lib/dynosaur/utils/rake_command.rb
|
121
125
|
- lib/dynosaur/version.rb
|
122
126
|
homepage:
|
123
127
|
licenses:
|