alloc8 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,18 +1,46 @@
1
1
  Simple distributed resource allocation using Redis.
2
2
 
3
+ To use resources:
3
4
  <pre>
5
+ require 'rubygems'
4
6
  require 'alloc8'
5
7
 
6
8
  HOST = "my-redis"
7
9
  PORT = 6379 # default Redis port
8
10
 
9
- # to create resources
10
- @allocator = Alloc8::Tor.new(HOST, PORT)
11
- @allocator.create("worker", "worker1.my.org")
12
- @allocator.create("worker", "worker2.my.org")
13
-
14
- # to use them
11
+ puts "acquiring worker"
15
12
  Alloc8::Tor.with_resource("worker", HOST, PORT) do |worker|
13
+ puts "about to do something with #{worker}"
16
14
  # something
17
15
  end
18
- </pre>
16
+ </pre>
17
+
18
+ Command-line tool to set up resources:
19
+ <pre>
20
+ $ alloc8
21
+ Tasks:
22
+ alloc8 create CLASS RESOURCE # Create a resource of a specific class
23
+ alloc8 help [TASK] # Describe available tasks or one specific task
24
+ alloc8 list CLASS [-A] # List all instances (or just available) of a resource class
25
+ alloc8 purge CLASS # Delete all resources from a class
26
+ alloc8 reset CLASS # Release acquired resources for a class
27
+
28
+ Options:
29
+ -p, [--port=N] # Redis store port
30
+ # Default: 6379
31
+ [--db=N] # Redis store database number
32
+ -h, [--host=HOST] # Redis store hostname
33
+ # Default: localhost
34
+
35
+ $ export ALLOC8_HOST="my-redis"
36
+ $ alloc8 list worker
37
+ List entries for worker:
38
+ $ alloc8 create worker worker1.my.org
39
+ Added worker1.my.org to worker.
40
+ $ alloc8 create worker worker2.my.org
41
+ Added worker2.my.org to worker.
42
+ $ alloc8 list worker
43
+ List entries for worker:
44
+ worker1.my.org
45
+ worker2.my.org
46
+ </pre>
data/alloc8.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
 
23
- s.add_runtime_dependency "redis", "~> 2.2.0"
23
+ s.add_runtime_dependency "redis", ">= 2.0"
24
+ s.add_runtime_dependency "thor"
24
25
  s.add_development_dependency "rspec", "~> 2.0"
25
26
  end
data/bin/alloc8 ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'thor'
4
+ require 'alloc8'
5
+
6
+ class Alloc8Cmd < Thor
7
+
8
+ class_option :host, :aliases => "-h", :type => :string, :default => (ENV["ALLOC8_HOST"] || "localhost"),
9
+ :desc => "Redis store hostname"
10
+ class_option :port, :aliases => "-p", :type => :numeric, :default => 6379, :desc => "Redis store port"
11
+ class_option :db, :type => :numeric, :desc => "Redis store database number"
12
+
13
+ desc "list CLASS [-A]", "List all instances (or just available) of a resource class"
14
+ method_option :available, :aliases => "-A", :type => :boolean, :desc => "List only the available (non-acquired) instances"
15
+ def list(klass)
16
+ allocator = Alloc8::Tor.new options[:host], options[:port], options[:db]
17
+ verb = options[:available] ? :available : :list
18
+ puts "#{verb.to_s.capitalize} entries for #{klass}:"
19
+ allocator.send(verb, klass).each do |res|
20
+ puts " #{res}"
21
+ end
22
+ end
23
+
24
+ desc "create CLASS RESOURCE", "Create a resource of a specific class"
25
+ def create(klass, resource)
26
+ allocator = Alloc8::Tor.new options[:host], options[:port], options[:db]
27
+ allocator.create(klass, resource)
28
+ puts "Added #{resource} to #{klass}."
29
+ end
30
+
31
+ desc "purge CLASS", "Delete all resources from a class"
32
+ def purge(klass)
33
+ allocator = Alloc8::Tor.new options[:host], options[:port], options[:db]
34
+ allocator.purge(klass)
35
+ puts "Purged all entries for #{klass}."
36
+ end
37
+
38
+ desc "reset CLASS", "Release acquired resources for a class"
39
+ def reset(klass)
40
+ allocator = Alloc8::Tor.new options[:host], options[:port], options[:db]
41
+ allocator.reset(klass)
42
+ puts "Reset all acquired entries for #{klass}."
43
+ end
44
+ end
45
+
46
+ Alloc8Cmd.start
data/lib/alloc8.rb CHANGED
@@ -2,51 +2,72 @@ require 'redis'
2
2
 
3
3
  module Alloc8
4
4
  class Tor
5
- # initialize connection to a redis
5
+ # initialize connection to redis
6
6
  def initialize(host, port, db=nil)
7
7
  @redis = Redis.new(:host => host, :port => port)
8
8
  @redis.select(db) if db
9
9
  end
10
10
 
11
11
  # create a resource in a class
12
- def create(resource_class, resource)
13
- if @redis.sadd("resource:#{resource_class}", resource.to_s)
14
- @redis.lpush "resource:#{resource_class}:avail", resource.to_s
12
+ def create(klass, resource)
13
+ if @redis.sadd(key(klass), resource.to_s)
14
+ @redis.lpush key(klass, :avail), resource.to_s
15
15
  end
16
16
  end
17
17
 
18
- # delete a resource
19
- def purge(resource_class)
20
- nkeys = @redis.del "resource:#{resource_class}:avail", "resource:#{resource_class}"
18
+ # list all resources in class
19
+ def list(klass)
20
+ @redis.smembers(key(klass))
21
+ end
22
+
23
+ # delete a resource class
24
+ def purge(klass)
25
+ nkeys = @redis.del key(klass, :avail), key(klass)
21
26
  nkeys == 2 # true if purged all
22
27
  end
23
28
 
24
29
  # reset available items in resource class
25
- def reset(resource_class)
26
- @redis.del "resource:#{resource_class}:avail"
27
- @redis.smembers("resource:#{resource_class}").each do |resource|
28
- @redis.lpush "resource:#{resource_class}:avail", resource.to_s
30
+ def reset(klass)
31
+ akey = key(klass, :avail)
32
+ @redis.del akey
33
+ @redis.smembers(key(klass)).each do |resource|
34
+ @redis.lpush akey, resource.to_s
29
35
  end
30
36
  end
31
37
 
38
+ # list all available items in resource class
39
+ def available(klass)
40
+ akey = key(klass, :avail)
41
+ avail = []
42
+ @redis.llen(akey).times do |i|
43
+ avail << @redis.lindex(akey, i)
44
+ end
45
+ avail
46
+ end
47
+
32
48
  # acquire next available resource
33
- def acquire(resource_class, timeout = 0)
34
- key, res = @redis.brpop "resource:#{resource_class}:avail", timeout
49
+ def acquire(klass, timeout = 0)
50
+ akey, res = @redis.brpop key(klass, :avail), timeout
35
51
  res
36
52
  end
37
53
 
38
54
  # return resource
39
- def return(resource_class, resource)
40
- raise Exception if !@redis.sismember "resource:#{resource_class}", resource.to_s
41
- @redis.lpush "resource:#{resource_class}:avail", resource.to_s
55
+ def return(klass, resource)
56
+ raise Exception.new("Invalid resource #{resource} for class #{klass}") if !@redis.sismember key(klass), resource.to_s
57
+ @redis.lpush key(klass, :avail), resource.to_s
42
58
  end
43
59
 
44
60
  # block to allocate a resource
45
- def self.with_resource(resource_class, host, port, db=nil)
46
- a = Alloc8::Tor.new host, port, db
47
- res = a.acquire(resource_class)
48
- yield res
49
- a.return(resource_class, res)
61
+ def self.with_resource(klass, host, port, db=nil)
62
+ a = Alloc8::Tor.new host, port, db
63
+ res = a.acquire(klass)
64
+ yield res
65
+ a.return(klass, res)
66
+ end
67
+
68
+ private
69
+ def key(klass, suffix = nil)
70
+ "resource:#{klass}" << (suffix ? suffix.to_s : "")
50
71
  end
51
72
  end
52
73
  end
@@ -1,3 +1,3 @@
1
1
  module Alloc8
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/spec/alloc8_spec.rb CHANGED
@@ -19,6 +19,11 @@ describe Alloc8 do
19
19
  context "having a single resource" do
20
20
  before { @allocator.create KIND, "a" }
21
21
 
22
+ it "can return a list of resources, available resources" do
23
+ @allocator.list(KIND).should eq(["a"])
24
+ @allocator.available(KIND).should eq(["a"])
25
+ end
26
+
22
27
  it "can't allocate it again" do
23
28
  @allocator.create(KIND, "a").should == nil
24
29
  end
@@ -30,11 +35,21 @@ describe Alloc8 do
30
35
 
31
36
  it "can purge resource class" do
32
37
  @allocator.purge(KIND).should == true
38
+ @allocator.list(KIND).should eq([])
39
+ @allocator.available(KIND).should eq([])
33
40
  end
34
41
 
35
42
  it "can acquire and return a resource" do
36
43
  @allocator.acquire(KIND).should == "a"
44
+ @allocator.available(KIND).should eq([])
45
+
37
46
  @allocator.return(KIND, "a").should == 1
47
+ @allocator.list(KIND).should eq(["a"])
48
+ @allocator.available(KIND).should eq(["a"])
49
+ end
50
+
51
+ it "can't return an invalid resource" do
52
+ lambda { @allocator.return(KIND, "foo") }.should raise_error
38
53
  end
39
54
 
40
55
  it "can acquire with a block" do
@@ -52,6 +67,13 @@ describe Alloc8 do
52
67
  context "having multiple resources" do
53
68
  before { ["a", "b", "c"].each {|r| @allocator.create KIND, r} }
54
69
 
70
+ it "can return a list of resources, available resources" do
71
+ @allocator.list(KIND).should include("a", "b", "c")
72
+ @allocator.list(KIND).should have(3).items
73
+ @allocator.available(KIND).should include("a", "b", "c")
74
+ @allocator.available(KIND).should have(3).items
75
+ end
76
+
55
77
  it "can purge resource class" do
56
78
  @allocator.purge(KIND).should == true
57
79
  end
@@ -66,4 +88,4 @@ describe Alloc8 do
66
88
  end
67
89
  end
68
90
 
69
- end
91
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alloc8
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ariel Salomon
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-20 00:00:00 -07:00
18
+ date: 2011-05-22 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -24,20 +24,33 @@ dependencies:
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
- hash: 7
29
+ hash: 3
30
30
  segments:
31
31
  - 2
32
- - 2
33
32
  - 0
34
- version: 2.2.0
33
+ version: "2.0"
35
34
  type: :runtime
36
35
  version_requirements: *id001
37
36
  - !ruby/object:Gem::Dependency
38
- name: rspec
37
+ name: thor
39
38
  prerelease: false
40
39
  requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ version: "0"
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rspec
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
41
54
  none: false
42
55
  requirements:
43
56
  - - ~>
@@ -48,14 +61,14 @@ dependencies:
48
61
  - 0
49
62
  version: "2.0"
50
63
  type: :development
51
- version_requirements: *id002
64
+ version_requirements: *id003
52
65
  description: |-
53
66
  Simple distributed resource allocation using Redis.
54
67
  Alloc8::Tor.with_resource do ...
55
68
  email:
56
69
  - ariel@oscillatory.org
57
- executables: []
58
-
70
+ executables:
71
+ - alloc8
59
72
  extensions: []
60
73
 
61
74
  extra_rdoc_files: []
@@ -66,6 +79,7 @@ files:
66
79
  - README.md
67
80
  - Rakefile
68
81
  - alloc8.gemspec
82
+ - bin/alloc8
69
83
  - lib/alloc8.rb
70
84
  - lib/alloc8/version.rb
71
85
  - spec/alloc8_spec.rb