riak-ruby-ledger 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmFiZWE5ODMwODQwODRiYzI3YjBjM2Y5ZDAwMmM0NzI4Y2ZhZDZlNA==
4
+ NTJhNWMzN2E2NTNiYTQ2MzAzMDM5ODI2NDUwYTZlMjNjZDc1NjE3ZA==
5
5
  data.tar.gz: !binary |-
6
- ZDNhNDI3MzA5NWZjY2U3NGRhYjAxNGMzYzVhOTEwMGUzZTZjYTA5OQ==
6
+ NTE5YjllZjJlMWJjMGM4NmZkNzRmNjNjNzEyNmJiY2EyNzg4YjU2OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjI5MzU1MzVhYzZhZDY4Y2UwMzJiNGJkMDc3YjdjY2JmNmU5MTM4MzM4ZjQ3
10
- OTRjYjI5Mzg5NTI4ZGIxY2M5MjUwNmY3YWVlZmRhNDI2OWViZmIzZWZhYjQw
11
- ODE1NTFhYWQyM2YwZDU0OGVhYzQyYjUxMTgxZjRiMTcwZmNmNGE=
9
+ MDc5YTA3MGE5MDBhZTc1YTc5Yzc0Y2FjNzQ5YjhmYjgwN2IyZGI0ZGNhYjI0
10
+ YzI3ZjhhYzZkMTIyOGE4YjU5N2NiNGQ1Njc0YzVhZjI4NzA3ZDI2ZmJiZjA2
11
+ YTIzNTE4MWQ5YzlkYmMwZjhiZjBmNzcyZjRjZDVjZTk1Zjk5NzA=
12
12
  data.tar.gz: !binary |-
13
- ZjRmNjQ3NmJhNzlmNTBjMWNmMGM2ZWFhNWRhNjJiMGQxMzFhNmIzYzI1M2Fk
14
- MGM2YzU1YWEwNzRmYzYxYTVmMzdhYzc2NTFhNzdiMjZhNDNiYTliMjQwNjFj
15
- MThjZTAxMzc2MDFhMTk5ODdiZjM5NWY2ZDJiYzcyZjg4NDc1MTM=
13
+ ZTk4NWM5OWZjYWQ2YjI0NDJmMjA4ODcyZGQ1MjY1YzVjNzFhYjZkNzEwYjQy
14
+ OWY4OWRiZWZlNzk1ODkzNjNmNTVkMDFlZGViYjFiM2M4YjUzZTk0OTNkMmMw
15
+ NmU5NjhlYmUzNGM0MTIxZTg5N2NlMDI1YjJmOWIzYmIyOWVlYTA=
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Riak-Ruby-Ledger
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/riak-ruby-ledger.png)](http://badge.fury.io/rb/riak-ruby-ledger)
4
+
3
5
  An alternative to Riak Counters with idempotent writes within a client defined window.
4
6
 
5
7
  # Summary
@@ -116,6 +118,12 @@ Thread.current["name"] = "ACTOR1"
116
118
  # Create a Riak::Client instance
117
119
  client = Riak::Client.new pb_port: 8087
118
120
 
121
+ # Get the Riak::Bucket instance
122
+ bucket = client["ledgers"]
123
+
124
+ # Set allow_mult to true
125
+ bucket.allow_mult = true unless bucket.allow_mult
126
+
119
127
  # Default option values
120
128
  options = {
121
129
  :actor => Thread.current["name"], # Actor ID, one per thread or serialized writer
@@ -125,7 +133,7 @@ options = {
125
133
 
126
134
  # Create the ledger object
127
135
  # Riak::Bucket Key Hash
128
- ledger = Riak::Ledger.new(client["ledgers"], "player_1", options)
136
+ ledger = Riak::Ledger.new(bucket, "player_1", options)
129
137
  ```
130
138
 
131
139
  ### Credit and debit
@@ -5,24 +5,24 @@
5
5
  In version 0.0.4 of this gem, counter drift is still a possibility. Take the following scenario into consideration:
6
6
 
7
7
  1. Actor 1 and Actor 2 both are somehow trying to write the same transaction id, possibly because the process writing the transaction took too long, and your application erroneously had a policy of retrying the same transaction before the first actor finished.
8
- a. If the Actor 1 is successful in writing the transaction before Actor 2 begins, Actor 2 will see that the transaction id already exists, and will return successful before attempting to write.
9
- b. Similarly, if Actor 2 finishes before Actor 1 starts, Actor 1 would disregard the request and report success.
10
- c. If Actor 1 and Actor 2 simultaneously and successfully write the same transaction, a result of is two siblings.
8
+ 1. If the Actor 1 is successful in writing the transaction before Actor 2 begins, Actor 2 will see that the transaction id already exists, and will return successful before attempting to write.
9
+ 2. Similarly, if Actor 2 finishes before Actor 1 starts, Actor 1 would disregard the request and report success.
10
+ 3. If Actor 1 and Actor 2 simultaneously and successfully write the same transaction, a result of is two siblings.
11
11
  2. If 1a or 1b happen, there is no problem. If 1c occurs, the second line of defense happens during a merge (merges are triggered prior to every write, and after every read).
12
- a. If Actor 1 merges before Actor 2, Actor 1 will remove it's own duplicate transaction in favor of leaving Actor 2's version, knowing it cannot modify any other actors' data.
13
- b. Similarly, if Actor 2 merges before Actor 1, it will remove it's own duplicate transaction.
14
- c. If Actor 1 and Actor 2 merge simultaneously and successfully, they would both remove their own duplicate (from their point of view) version of the transaction, meaning it would be lost causing negative counter drift (on increments) and positive drift (on decrements)
12
+ 1. If Actor 1 merges before Actor 2, Actor 1 will remove it's own duplicate transaction in favor of leaving Actor 2's version, knowing it cannot modify any other actors' data.
13
+ 2. Similarly, if Actor 2 merges before Actor 1, it will remove it's own duplicate transaction.
14
+ 3. If Actor 1 and Actor 2 merge simultaneously and successfully, they would both remove their own duplicate (from their point of view) version of the transaction, meaning it would be lost causing negative counter drift (on increments) and positive drift (on decrements)
15
15
 
16
16
  This is an unlikely but possible scenario. Here are some ways to reduce or elimiate the possibility of 2c from happening:
17
17
 
18
18
  1. The precursor to the condition resulting from 2c can be avoided by serializing writes per transaction, like in the example of a game's application server knowing to only submit one unique transaction at a time. Submitting simultaneous transactions is ok, so long as the same transaction isn't active in more than one actor at the same time.
19
- a. This is possible using this gem, it's just a matter of implemeting some control over who can write a single unique at the same time.
19
+ 1. This is possible using this gem, it's just a matter of implemeting some control over who can write a single unique at the same time.
20
20
  2. Have a no duplicate delete policy, meaning that you could potentially have an infinitely growing list of duplicate transactions if your application causes this situation often.
21
- a. This is unimplemented in this gem as of now, but depending on the thoughts of others, I may add it as an optional policy.
21
+ 1. This is unimplemented in this gem as of now, but depending on the thoughts of others, I may add it as an optional policy.
22
22
  3. Attach a microsecond epoch to each transaction so that during merges the the duplicate transaction with the highest epoch always wins.
23
- a. This is unimplemented in this gem, and it would only lessen the statistical likelihood of 2c happening, it would still be possible. Because it only lowers the likelihood.
24
- 4. Do a string compare on the actor ids, whichever has the highest string compare value always keeps it's version of the duplicate transaction.
25
- a. This is now implemented in version 0.1.0, see below.
23
+ 1. This is unimplemented in this gem, and it would only lessen the statistical likelihood of 2c happening, it would still be possible. Because it only lowers the likelihood.
24
+ 4. Do a string compare on the actor ids, whichever has the highest string compare value always keeps it's version of the duplicate transaction. If one the lesser actor is stale and never merges, the actor that should keep the transaction will throw it away knowing that the stale actor will keep it.
25
+ 1. This is now implemented in version 0.0.5, see below.
26
26
 
27
27
  ##### Version 0.0.5 and Actor Naming [***Important***]
28
28
 
@@ -30,4 +30,8 @@ Solution 4 has been implemented to the potential counter drift caused by two sim
30
30
 
31
31
  As a result, keep in mind that when naming actors, they will be compared for ordering purposes
32
32
 
33
- Example: "ACTOR2" is greater than "ACTOR1", so ACTOR1 will always remove it's version of a duplicate transaction during a merge, and "ACTOR2" will never remove it's version. Avoid using actor ids that could potentially result in string equality.
33
+ Example: "ACTOR2" is greater than "ACTOR1", so ACTOR1 will always remove it's version of a duplicate transaction during a merge, and "ACTOR2" will never remove it's version unless it thinks actor 1 is stale. Avoid using actor ids that could potentially result in string equality.
34
+
35
+ ##### Version 0.0.5
36
+
37
+ Removed the automatic setting of allow_mult on the bucket in Riak::Ledger. Please remember to set allow_mult to true on your ledger bucket, notes in README.md
@@ -16,6 +16,8 @@ module Riak
16
16
  # :retry_count [Integer]: default 10
17
17
  # }
18
18
  def initialize(bucket, key, options={})
19
+ raise ArgumentError, 'Argument "bucket" must have "allow_mult" property set to true' unless bucket.allow_mult
20
+
19
21
  self.bucket = bucket
20
22
  self.key = key
21
23
  self.retry_count = options[:retry_count] || 10
@@ -24,10 +26,6 @@ module Riak
24
26
  self.counter_options[:actor] = options[:actor] || Thread.current["name"] || "ACTOR1"
25
27
  self.counter_options[:history_length] = options[:history_length] || 10
26
28
  self.counter = Riak::CRDT::TPNCounter.new(self.counter_options)
27
-
28
- unless bucket.allow_mult
29
- self.bucket.allow_mult = true
30
- end
31
29
  end
32
30
 
33
31
  # Find an existing Ledger object, merge and save it
@@ -1,5 +1,5 @@
1
1
  module Riak
2
2
  class Ledger
3
- VERSION = "0.0.5"
3
+ VERSION = "0.0.6"
4
4
  end
5
5
  end
@@ -9,6 +9,7 @@ describe Riak::Ledger do
9
9
  before do
10
10
  client = Riak::Client.new pb_port: 8087
11
11
  @bucket = client["ledger_test"]
12
+ @bucket.allow_mult = true
12
13
  @key = "player_1"
13
14
 
14
15
 
@@ -21,8 +22,17 @@ describe Riak::Ledger do
21
22
  @ledger2.delete()
22
23
  end
23
24
 
24
- it "have a valid starting state" do
25
+ it "must raise an error if mult is not allowed" do
26
+ @bucket.allow_mult = false
27
+
28
+ assert_raises ArgumentError do
29
+ Riak::Ledger.new(@bucket, @key, options1)
30
+ end
25
31
 
32
+ @bucket.allow_mult = true
33
+ end
34
+
35
+ it "have a valid starting state" do
26
36
  assert_equal({:type=>"TGCounter", :c=>{"ACTOR1"=>{"total"=>0, "txns"=>[]}}}, @ledger1.counter.p.to_hash)
27
37
  assert_equal({:type=>"TGCounter", :c=>{"ACTOR1"=>{"total"=>0, "txns"=>[]}}}, @ledger1.counter.n.to_hash)
28
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riak-ruby-ledger
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - drewkerrigan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-21 00:00:00.000000000 Z
11
+ date: 2013-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler