alloc8 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in alloc8.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,18 @@
1
+ Simple distributed resource allocation using Redis.
2
+
3
+ <pre>
4
+ require 'alloc8'
5
+
6
+ HOST = "my-redis"
7
+ PORT = 6379 # default Redis port
8
+
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
15
+ Alloc8::Tor.with_resource("worker", HOST, PORT) do |worker|
16
+ # something
17
+ end
18
+ </pre>
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ task :default => :spec
data/alloc8.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "alloc8/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "alloc8"
7
+ s.version = Alloc8::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Ariel Salomon"]
10
+ s.email = ["ariel@oscillatory.org"]
11
+ s.homepage = ""
12
+ s.summary = %q{Simple distributed resource allocator based on Redis}
13
+ s.description = %q{Simple distributed resource allocation using Redis.
14
+ Alloc8::Tor.with_resource do ...}
15
+
16
+ s.rubyforge_project = "alloc8"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_runtime_dependency "redis", "~> 2.2.0"
24
+ s.add_development_dependency "rspec", "~> 2.0"
25
+ end
data/lib/alloc8.rb ADDED
@@ -0,0 +1,52 @@
1
+ require 'redis'
2
+
3
+ module Alloc8
4
+ class Tor
5
+ # initialize connection to a redis
6
+ def initialize(host, port, db=nil)
7
+ @redis = Redis.new(:host => host, :port => port)
8
+ @redis.select(db) if db
9
+ end
10
+
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
15
+ end
16
+ end
17
+
18
+ # delete a resource
19
+ def purge(resource_class)
20
+ nkeys = @redis.del "resource:#{resource_class}:avail", "resource:#{resource_class}"
21
+ nkeys == 2 # true if purged all
22
+ end
23
+
24
+ # 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
29
+ end
30
+ end
31
+
32
+ # acquire next available resource
33
+ def acquire(resource_class, timeout = 0)
34
+ key, res = @redis.brpop "resource:#{resource_class}:avail", timeout
35
+ res
36
+ end
37
+
38
+ # 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
42
+ end
43
+
44
+ # 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)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module Alloc8
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,69 @@
1
+ require 'alloc8'
2
+
3
+ describe Alloc8 do
4
+ KIND = "ResourceClass"
5
+ HOST = "localhost"
6
+ PORT = 6379 # default redis port
7
+
8
+ before {
9
+ @allocator = Alloc8::Tor.new(HOST, PORT)
10
+ @allocator.purge(KIND)
11
+ }
12
+
13
+ context "having no resources" do
14
+ it "can create a resource" do
15
+ @allocator.create(KIND, "a").should == 1
16
+ end
17
+ end
18
+
19
+ context "having a single resource" do
20
+ before { @allocator.create KIND, "a" }
21
+
22
+ it "can't allocate it again" do
23
+ @allocator.create(KIND, "a").should == nil
24
+ end
25
+
26
+ it "can allocate other resources" do
27
+ @allocator.create(KIND, "b").should == 2
28
+ @allocator.create(KIND, "c").should == 3
29
+ end
30
+
31
+ it "can purge resource class" do
32
+ @allocator.purge(KIND).should == true
33
+ end
34
+
35
+ it "can acquire and return a resource" do
36
+ @allocator.acquire(KIND).should == "a"
37
+ @allocator.return(KIND, "a").should == 1
38
+ end
39
+
40
+ it "can acquire with a block" do
41
+ Alloc8::Tor.with_resource(KIND, HOST, PORT) do |res|
42
+ res.should == "a"
43
+ end
44
+ end
45
+
46
+ it "can't acquire a second resource" do
47
+ @allocator.acquire(KIND)
48
+ @allocator.acquire(KIND, 1).should == nil # with 1s timeout
49
+ end
50
+ end
51
+
52
+ context "having multiple resources" do
53
+ before { ["a", "b", "c"].each {|r| @allocator.create KIND, r} }
54
+
55
+ it "can purge resource class" do
56
+ @allocator.purge(KIND).should == true
57
+ end
58
+
59
+ it "can acquire and return multiple resources" do
60
+ @allocator.acquire(KIND).should == "a"
61
+ @allocator.acquire(KIND).should == "b"
62
+ @allocator.acquire(KIND).should == "c"
63
+ @allocator.return(KIND, "c").should == 1
64
+ @allocator.return(KIND, "b").should == 2
65
+ @allocator.return(KIND, "a").should == 3
66
+ end
67
+ end
68
+
69
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alloc8
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ariel Salomon
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-20 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: redis
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 2
32
+ - 2
33
+ - 0
34
+ version: 2.2.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 2
48
+ - 0
49
+ version: "2.0"
50
+ type: :development
51
+ version_requirements: *id002
52
+ description: |-
53
+ Simple distributed resource allocation using Redis.
54
+ Alloc8::Tor.with_resource do ...
55
+ email:
56
+ - ariel@oscillatory.org
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files: []
62
+
63
+ files:
64
+ - .gitignore
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - alloc8.gemspec
69
+ - lib/alloc8.rb
70
+ - lib/alloc8/version.rb
71
+ - spec/alloc8_spec.rb
72
+ has_rdoc: true
73
+ homepage: ""
74
+ licenses: []
75
+
76
+ post_install_message:
77
+ rdoc_options: []
78
+
79
+ require_paths:
80
+ - lib
81
+ required_ruby_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 3
87
+ segments:
88
+ - 0
89
+ version: "0"
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ requirements: []
100
+
101
+ rubyforge_project: alloc8
102
+ rubygems_version: 1.5.3
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Simple distributed resource allocator based on Redis
106
+ test_files:
107
+ - spec/alloc8_spec.rb