alloc8 0.0.1 → 0.0.2

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.
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