couchbase-id 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8c0049a7aa83f9c40a73745146062faec8f8802a
4
+ data.tar.gz: 91b16ae8153a4dde5b9538fd2ceef49836738343
5
+ SHA512:
6
+ metadata.gz: 595a593873c6104558ae8bc93e0df7b30d6da9c9cb5b140e6faf1f4c5221e79fe31f90363b2c333622c5fef1b869bfee380a48bdc8fe9605af490d07fd2e3a43
7
+ data.tar.gz: 3f15376892527018890300b436ba5dac626073d4300430e4cf34012b44c88a482bab33c24a4f441e8aec82b7dfb888aa9fb0cec4ee9cfbc733d1741a893839e0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 CoTag Media
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Couchbase ID Generator
2
+
3
+ Built to support efficient ID generation with XDCR capabilities
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'rspec/core/rake_task' # testing framework
3
+ require 'yard' # yard documentation
4
+
5
+
6
+
7
+ # By default we don't run network tests
8
+ task :default => :limited_spec
9
+ RSpec::Core::RakeTask.new(:limited_spec) do |t|
10
+ # Exclude network tests
11
+ # t.rspec_opts = "--tag ~network"
12
+ end
13
+ RSpec::Core::RakeTask.new(:spec)
14
+
15
+
16
+ desc "Run all tests"
17
+ task :test => [:spec]
18
+
19
+
20
+ YARD::Rake::YardocTask.new do |t|
21
+ t.files = ['lib/**/*.rb', '-', 'ext/README.md', 'README.md']
22
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path("../lib/couchbase-id/version", __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = "couchbase-id"
5
+ gem.version = CouchbaseId::VERSION
6
+ gem.license = 'MIT'
7
+ gem.authors = ["Stephen von Takach"]
8
+ gem.email = ["steve@cotag.me"]
9
+ gem.homepage = "https://github.com/cotag/couchbase-id"
10
+ gem.summary = "Couchbase ID generator with XDCR support"
11
+ gem.description = "Overwrites the existing couchbase-model id implementation"
12
+
13
+ gem.required_ruby_version = '>= 1.9.2'
14
+ gem.require_paths = ["lib"]
15
+
16
+ gem.add_runtime_dependency 'couchbase-model'
17
+ gem.add_runtime_dependency 'radix' # This converts numbers to the unicode representation
18
+
19
+ gem.add_development_dependency 'rspec', '>= 2.14'
20
+ gem.add_development_dependency 'rake', '>= 10.1'
21
+ gem.add_development_dependency 'yard'
22
+
23
+ gem.files = Dir["{lib}/**/*"] + %w(Rakefile couchbase-id.gemspec README.md LICENSE)
24
+ gem.test_files = Dir["spec/**/*"]
25
+ gem.extra_rdoc_files = ["README.md"]
26
+ end
@@ -0,0 +1,117 @@
1
+ #
2
+ # This disables the built in generator, faster then running validations twice
3
+ # Forces models to include an ID generator
4
+ #
5
+ module Couchbase
6
+ class Model
7
+ class UUID
8
+ def initialize(*args)
9
+
10
+ end
11
+
12
+ def next(*args)
13
+ nil
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ #
20
+ # This is our id generator, runs in the before save call back
21
+ #
22
+ module CouchbaseId
23
+
24
+ # NOTE:: incr, decr, append, prepend == atomic
25
+ module Generator
26
+
27
+
28
+ # Basic compression using UTF (more efficient for ID's stored as strings)
29
+ B65 = Radix::Base.new(Radix::BASE::B62 + ['-', '_', '~'])
30
+ B10 = Radix::Base.new(10)
31
+
32
+ # The cluster id this node belongs to (avoids XDCR clashes)
33
+ CLUSTER_ID ||= ENV['COUCHBASE_CLUSTER'] || 1 # Cluster ID number
34
+
35
+ # instance method
36
+ def generate_id
37
+ if self.id.nil?
38
+ name = "#{self.class.name.underscore.gsub!(/\/|_/, '-')}" # The included classes name
39
+
40
+ #
41
+ # Generate the id (incrementing values as required)
42
+ #
43
+ overflow = @@__overflow__ ||= self.class.bucket.get("#{name}:#{CLUSTER_ID}:overflow", :quiet => true) # Don't error if not there
44
+ count = self.class.bucket.incr("#{name}:#{CLUSTER_ID}:count", :create => true) # This models current id count
45
+ if count == 0 || overflow.nil?
46
+ overflow ||= 0
47
+ overflow += 1
48
+ # We shouldn't need to worry about concurrency here due to the size of count
49
+ # Would require ~18446744073709551615 concurrent writes
50
+ self.class.bucket.set("#{name}:#{CLUSTER_ID}:overflow", overflow)
51
+ @@__overflow__ = overflow
52
+ end
53
+
54
+ self.id = @@__class_id_generator__.call(name, overflow, count)
55
+
56
+
57
+ #
58
+ # So an existing id would only be present if:
59
+ # => something crashed before incrementing the overflow
60
+ # => this is another request was occurring before the overflow is incremented
61
+ #
62
+ # Basically only the overflow should be able to cause issues, we'll increment the count just to be sure
63
+ # One would hope this code only ever runs under high load during an overflow event
64
+ #
65
+ while self.class.bucket.get(self.id, :quiet => true).present?
66
+ # Set in-case we are here due to a crash (concurrency is not an issue)
67
+ # Note we are not incrementing the @__overflow__ variable
68
+ self.class.bucket.set("#{name}:#{CLUSTER_ID}:overflow", overflow + 1)
69
+ count = self.class.bucket.incr("#{name}:#{CLUSTER_ID}:count") # Increment just in case (attempt to avoid infinite loops)
70
+
71
+ # Reset the overflow
72
+ if @@__overflow__ == overflow
73
+ @@__overflow__ = nil
74
+ end
75
+
76
+ # Generate the new id
77
+ self.id = @@__class_id_generator__.call(name, overflow + 1, count)
78
+ end
79
+ end
80
+ end
81
+
82
+ module ClassMethods
83
+ def default_class_id_generator(name, overflow, count)
84
+ id = Radix.convert([overflow, CLUSTER_ID].join.to_i, B10, B65) + Radix.convert(count, B10, B65)
85
+ "#{name}-#{id}"
86
+ end
87
+
88
+ #
89
+ # Override the default hashing function
90
+ #
91
+ def set_class_id_generator(callback = nil, &block)
92
+ callback ||= block
93
+ @@__class_id_generator__ = callback
94
+ end
95
+ end
96
+
97
+ def self.included(base)
98
+ base.extend(ClassMethods)
99
+
100
+ base.class_eval do
101
+ #
102
+ # Configure class level variables
103
+ @@__overflow__ ||= nil
104
+ @@__class_id_generator__ ||= method(:default_class_id_generator)
105
+
106
+
107
+ #
108
+ # Best case we have 18446744073709551615 * 18446744073709551615 model entries for each database cluster
109
+ # and we can always change the cluster id if this limit is reached
110
+ #
111
+ define_model_callbacks :save, :create
112
+ before_save :generate_id
113
+ before_create :generate_id
114
+ end
115
+ end
116
+ end # END:: Generator
117
+ end
@@ -0,0 +1,3 @@
1
+ module CouchbaseId
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'radix'
2
+ require 'couchbase-model'
3
+ require 'couchbase-id/generator'
4
+
5
+
6
+ module CouchbaseId
7
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: couchbase-id
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen von Takach
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: couchbase-model
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: radix
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '2.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '2.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '10.1'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '10.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Overwrites the existing couchbase-model id implementation
84
+ email:
85
+ - steve@cotag.me
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files:
89
+ - README.md
90
+ files:
91
+ - lib/couchbase-id/generator.rb
92
+ - lib/couchbase-id/version.rb
93
+ - lib/couchbase-id.rb
94
+ - Rakefile
95
+ - couchbase-id.gemspec
96
+ - README.md
97
+ - LICENSE
98
+ homepage: https://github.com/cotag/couchbase-id
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 1.9.2
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.0.3
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Couchbase ID generator with XDCR support
122
+ test_files: []
123
+ has_rdoc: