scalaroid 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: caabb3032c072a916a68ac2ce0eea04add8c8dac
4
- data.tar.gz: 6101f0516c5ab1b843ea839fcc81a2d2e19c29da
3
+ metadata.gz: ebb984a4a84bf062f362565b3dcb99024d272133
4
+ data.tar.gz: 8bf7ab7c403ac124cea9b35734849fa56d3f4abe
5
5
  SHA512:
6
- metadata.gz: df3b5753c4c179ae421d8d280e186881df86d21efb8cfb626c011572f225c6bda9d540bc7ef20d4d711a351b6e7ebe6bb3a621267834d151117ee23528fbb4d3
7
- data.tar.gz: 2c08973fdff5d72b8acaabcfb57654b10dfc5ce3aeb3bb2c74a9675b5a2ba0c0e54888ceb4565ed0bffce5e0c035206bcfcf01fb28d4c5f6aa15ec0a471a6227
6
+ metadata.gz: ef3074ccc62dce91e386cbd276ee5d209527f66e6d510bae3dc788f566a4db992d3c98522857d328011af2abd48468b121022ad1b3a0e442578ca1801ef9084d
7
+ data.tar.gz: 8925be104f80a04795d88dbc5f1c4239a558286d9db4d81b3fb2ad2fcfd6f9e25c49917681ba48c085fd2d64ea90a00d2612d0ae5fa8b836557a3597dbe2a896
@@ -0,0 +1,13 @@
1
+ module Scalaroid
2
+ # Stores the result of a delete operation.
3
+ class DeleteResult
4
+ attr_reader :ok
5
+ attr_reader :locks_set
6
+ attr_reader :undefined
7
+ def initialize(ok, locks_set, undefined)
8
+ @ok = ok
9
+ @locks_set = locks_set
10
+ @undefined = undefined
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,96 @@
1
+ module Scalaroid
2
+ # Request list for use with Transaction.req_list()
3
+ class JSONReqList
4
+ # Create a new object using a JSON connection.
5
+ def initialize(other = nil)
6
+ @requests = []
7
+ @is_commit = false
8
+ if not other == nil
9
+ concat(other)
10
+ end
11
+ end
12
+
13
+ # Adds a read operation to the request list.
14
+ def add_read(key)
15
+ if (@is_commit)
16
+ raise RuntimeError.new('No further request supported after a commit!')
17
+ end
18
+ @requests << {'read' => key}
19
+ self
20
+ end
21
+
22
+ # Adds a write operation to the request list.
23
+ def add_write(key, value, binary = false)
24
+ if (@is_commit)
25
+ raise RuntimeError.new('No further request supported after a commit!')
26
+ end
27
+ @requests << {'write' => {key => JSONConnection.encode_value(value, binary)}}
28
+ self
29
+ end
30
+
31
+ # Adds a add_del_on_list operation to the request list.
32
+ def add_add_del_on_list(key, to_add, to_remove)
33
+ if (@is_commit)
34
+ raise RuntimeError.new('No further request supported after a commit!')
35
+ end
36
+ @requests << {'add_del_on_list' => {'key' => key, 'add' => to_add, 'del'=> to_remove}}
37
+ self
38
+ end
39
+
40
+ # Adds a add_on_nr operation to the request list.
41
+ def add_add_on_nr(key, to_add)
42
+ if (@is_commit)
43
+ raise RuntimeError.new('No further request supported after a commit!')
44
+ end
45
+ @requests << {'add_on_nr' => {key => to_add}}
46
+ self
47
+ end
48
+
49
+ # Adds a test_and_set operation to the request list.
50
+ def add_test_and_set(key, old_value, new_value)
51
+ if (@is_commit)
52
+ raise RuntimeError.new('No further request supported after a commit!')
53
+ end
54
+ @requests << {'test_and_set' => {'key' => key,
55
+ 'old' => JSONConnection.encode_value(old_value, false),
56
+ 'new' => JSONConnection.encode_value(new_value, false)}}
57
+ self
58
+ end
59
+
60
+ # Adds a commit operation to the request list.
61
+ def add_commit
62
+ if (@is_commit)
63
+ raise RuntimeError.new('Only one commit per request list allowed!')
64
+ end
65
+ @requests << {'commit' => ''}
66
+ @is_commit = true
67
+ self
68
+ end
69
+
70
+ # Gets the collected requests.
71
+ def get_requests
72
+ @requests
73
+ end
74
+
75
+ # Returns whether the transactions contains a commit or not.
76
+ def is_commit()
77
+ @is_commit
78
+ end
79
+
80
+ # Checks whether the request list is empty.
81
+ def is_empty()
82
+ @requests.empty?
83
+ end
84
+
85
+ # Gets the number of requests in the list.
86
+ def size()
87
+ @requests.length
88
+ end
89
+
90
+ # Adds all requests of the other request list to the end of this list.
91
+ def concat(other)
92
+ @requests.concat(other.get_requests())
93
+ self
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,8 @@
1
+ module Scalaroid
2
+ # Request list for use with Transaction.req_list().
3
+ class JSONReqListTransaction < JSONReqList
4
+ def initialize(other = nil)
5
+ super(other)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ module Scalaroid
2
+ # Request list for use with TransactionSingleOp.req_list() which does not
3
+ # support commits.
4
+ class JSONReqListTransactionSingleOp < JSONReqList
5
+ def initialize(other = nil)
6
+ super(other)
7
+ end
8
+
9
+ # Adds a commit operation to the request list.
10
+ def add_commit()
11
+ raise RuntimeError.new('No commit allowed in TransactionSingleOp.req_list()!')
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,44 @@
1
+ module Scalaroid
2
+ # Publish and subscribe methods accessing Scalaris' pubsub system
3
+ class PubSub
4
+ # Create a new object using the given connection.
5
+ def initialize(conn = JSONConnection.new())
6
+ @conn = conn
7
+ end
8
+
9
+ # Publishes content under topic.
10
+ def publish(topic, content)
11
+ # note: do NOT encode the content, this is not decoded on the erlang side!
12
+ # (only strings are allowed anyway)
13
+ # content = @conn.class.encode_value(content)
14
+ result = @conn.call(:publish, [topic, content])
15
+ @conn.class.process_result_publish(result)
16
+ end
17
+
18
+ # Subscribes url for topic.
19
+ def subscribe(topic, url)
20
+ # note: do NOT encode the URL, this is not decoded on the erlang side!
21
+ # (only strings are allowed anyway)
22
+ # url = @conn.class.encode_value(url)
23
+ result = @conn.call(:subscribe, [topic, url])
24
+ @conn.class.process_result_subscribe(result)
25
+ end
26
+
27
+ # Unsubscribes url from topic.
28
+ def unsubscribe(topic, url)
29
+ # note: do NOT encode the URL, this is not decoded on the erlang side!
30
+ # (only strings are allowed anyway)
31
+ # url = @conn.class.encode_value(url)
32
+ result = @conn.call(:unsubscribe, [topic, url])
33
+ @conn.class.process_result_unsubscribe(result)
34
+ end
35
+
36
+ # Gets the list of all subscribers to topic.
37
+ def get_subscribers(topic)
38
+ result = @conn.call(:get_subscribers, [topic])
39
+ @conn.class.process_result_get_subscribers(result)
40
+ end
41
+
42
+ include InternalScalarisNopClose
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ module Scalaroid
2
+ # Non-transactional operations on the replicated DHT of Scalaris
3
+ class ReplicatedDHT
4
+ # Create a new object using the given connection.
5
+ def initialize(conn = JSONConnection.new())
6
+ @conn = conn
7
+ end
8
+
9
+ # Tries to delete the value at the given key.
10
+ #
11
+ # WARNING: This function can lead to inconsistent data (e.g. deleted items
12
+ # can re-appear). Also when re-creating an item the version before the
13
+ # delete can re-appear.
14
+ #
15
+ # returns the number of successfully deleted items
16
+ # use get_last_delete_result() to get more details
17
+ def delete(key, timeout = 2000)
18
+ result_raw = @conn.call(:delete, [key, timeout])
19
+ result = @conn.class.process_result_delete(result_raw)
20
+ @lastDeleteResult = result[:results]
21
+ if result[:success] == true
22
+ return result[:ok]
23
+ elsif result[:success] == :timeout
24
+ raise TimeoutError.new(result_raw)
25
+ else
26
+ raise UnknownError.new(result_raw)
27
+ end
28
+ end
29
+
30
+ # Returns the result of the last call to delete().
31
+ #
32
+ # NOTE: This function traverses the result list returned by Scalaris and
33
+ # therefore takes some time to process. It is advised to store the returned
34
+ # result object once generated.
35
+ def get_last_delete_result
36
+ @conn.class.create_delete_result(@lastDeleteResult)
37
+ end
38
+
39
+ include InternalScalarisNopClose
40
+ end
41
+ end
@@ -0,0 +1,153 @@
1
+ module Scalaroid
2
+ # Write or read operations on Scalaris inside a transaction.
3
+ class Transaction
4
+ # Create a new object using the given connection
5
+ def initialize(conn = JSONConnection.new())
6
+ @conn = conn
7
+ @tlog = nil
8
+ end
9
+
10
+ # Returns a new ReqList object allowing multiple parallel requests.
11
+ def new_req_list(other = nil)
12
+ @conn.class.new_req_list_t(other)
13
+ end
14
+
15
+ # Issues multiple parallel requests to Scalaris.
16
+ # Request lists can be created using new_req_list().
17
+ # The returned list has the following form:
18
+ # [{'status': 'ok'} or {'status': 'ok', 'value': xxx} or
19
+ # {'status': 'fail', 'reason': 'timeout' or 'abort' or 'not_found'}].
20
+ # The elements of this list can be processed with process_result_read(),
21
+ # process_result_write() and process_result_commit().
22
+ def req_list(reqlist)
23
+ if @tlog == nil
24
+ result = @conn.call(:req_list, [reqlist.get_requests()])
25
+ else
26
+ result = @conn.call(:req_list, [@tlog, reqlist.get_requests()])
27
+ end
28
+ result = @conn.class.process_result_req_list_t(result)
29
+ @tlog = result[:tlog]
30
+ result = result[:result]
31
+ if reqlist.is_commit()
32
+ _process_result_commit(result[-1])
33
+ # transaction was successful: reset transaction log
34
+ @tlog = nil
35
+ end
36
+ result
37
+ end
38
+
39
+ # Processes a result element from the list returned by req_list() which
40
+ # originated from a read operation.
41
+ # Returns the read value on success.
42
+ # Raises the appropriate exceptions if a failure occurred during the
43
+ # operation.
44
+ # Beware: lists of (small) integers may be (falsely) returned as a string -
45
+ # use str_to_list() to convert such strings.
46
+ def process_result_read(result)
47
+ @conn.class.process_result_read(result)
48
+ end
49
+
50
+ # Processes a result element from the list returned by req_list() which
51
+ # originated from a write operation.
52
+ # Raises the appropriate exceptions if a failure occurred during the
53
+ # operation.
54
+ def process_result_write(result)
55
+ @conn.class.process_result_write(result)
56
+ end
57
+
58
+ # Processes a result element from the list returned by req_list() which
59
+ # originated from a add_del_on_list operation.
60
+ # Raises the appropriate exceptions if a failure occurred during the
61
+ # operation.
62
+ def process_result_add_del_on_list(result)
63
+ @conn.class.process_result_add_del_on_list(result)
64
+ end
65
+
66
+ # Processes a result element from the list returned by req_list() which
67
+ # originated from a add_on_nr operation.
68
+ # Raises the appropriate exceptions if a failure occurred during the
69
+ # operation.
70
+ def process_result_add_on_nr(result)
71
+ @conn.class.process_result_add_on_nr(result)
72
+ end
73
+
74
+ # Processes a result element from the list returned by req_list() which
75
+ # originated from a test_and_set operation.
76
+ # Raises the appropriate exceptions if a failure occurred during the
77
+ # operation.
78
+ def process_result_test_and_set(result)
79
+ @conn.class.process_result_test_and_set(result)
80
+ end
81
+
82
+ # Processes a result element from the list returned by req_list() which
83
+ # originated from a commit operation.
84
+ # Raises the appropriate exceptions if a failure occurred during the
85
+ # operation.
86
+ def _process_result_commit(result)
87
+ @conn.class.process_result_commit(result)
88
+ end
89
+
90
+ private :_process_result_commit
91
+
92
+ # Issues a commit operation to Scalaris validating the previously
93
+ # created operations inside the transaction.
94
+ def commit
95
+ result = req_list(new_req_list().add_commit())[0]
96
+ _process_result_commit(result)
97
+ # reset tlog (minor optimization which is not done in req_list):
98
+ @tlog = nil
99
+ end
100
+
101
+ # Aborts all previously created operations inside the transaction.
102
+ def abort
103
+ @tlog = nil
104
+ end
105
+
106
+ # Issues a read operation to Scalaris, adds it to the current
107
+ # transaction and returns the result.
108
+ # Beware: lists of (small) integers may be (falsely) returned as a string -
109
+ # use str_to_list() to convert such strings.
110
+ def read(key)
111
+ result = req_list(new_req_list().add_read(key))[0]
112
+ return process_result_read(result)
113
+ end
114
+
115
+ # Issues a write operation to Scalaris and adds it to the current
116
+ # transaction.
117
+ def write(key, value, binary = false)
118
+ result = req_list(new_req_list().add_write(key, value, binary))[0]
119
+ _process_result_commit(result)
120
+ end
121
+
122
+ # Issues a add_del_on_list operation to scalaris and adds it to the
123
+ # current transaction.
124
+ # Changes the list stored at the given key, i.e. first adds all items in
125
+ # to_add then removes all items in to_remove.
126
+ # Both, to_add and to_remove, must be lists.
127
+ # Assumes en empty list if no value exists at key.
128
+ def add_del_on_list(key, to_add, to_remove)
129
+ result = req_list(new_req_list().add_add_del_on_list(key, to_add, to_remove))[0]
130
+ process_result_add_del_on_list(result)
131
+ end
132
+
133
+ # Issues a add_on_nr operation to scalaris and adds it to the
134
+ # current transaction.
135
+ # Changes the number stored at the given key, i.e. adds some value.
136
+ # Assumes 0 if no value exists at key.
137
+ def add_on_nr(key, to_add)
138
+ result = req_list(new_req_list().add_add_on_nr(key, to_add))[0]
139
+ process_result_add_on_nr(result)
140
+ end
141
+
142
+ # Issues a test_and_set operation to scalaris and adds it to the
143
+ # current transaction.
144
+ # Atomic test and set, i.e. if the old value at key is old_value, then
145
+ # write new_value.
146
+ def test_and_set(key, old_value, new_value)
147
+ result = req_list(new_req_list().add_test_and_set(key, old_value, new_value))[0]
148
+ process_result_test_and_set(result)
149
+ end
150
+
151
+ include InternalScalarisNopClose
152
+ end
153
+ end
@@ -0,0 +1,130 @@
1
+ module Scalaroid
2
+ # Single write or read operations on Scalaris.
3
+ class TransactionSingleOp
4
+ # Create a new object using the given connection
5
+ def initialize(conn = JSONConnection.new())
6
+ @conn = conn
7
+ end
8
+
9
+ # Returns a new ReqList object allowing multiple parallel requests.
10
+ def new_req_list(other = nil)
11
+ @conn.class.new_req_list_t(other)
12
+ end
13
+
14
+ # Issues multiple parallel requests to scalaris; each will be committed.
15
+ # NOTE: The execution order of multiple requests on the same key is
16
+ # undefined!
17
+ # Request lists can be created using new_req_list().
18
+ # The returned list has the following form:
19
+ # [{'status': 'ok'} or {'status': 'ok', 'value': xxx} or
20
+ # {'status': 'fail', 'reason': 'timeout' or 'abort' or 'not_found'}].
21
+ # Elements of this list can be processed with process_result_read() and
22
+ # process_result_write().
23
+ def req_list(reqlist)
24
+ result = @conn.call(:req_list_commit_each, [reqlist.get_requests()])
25
+ @conn.class.process_result_req_list_tso(result)
26
+ end
27
+
28
+ # Processes a result element from the list returned by req_list() which
29
+ # originated from a read operation.
30
+ # Returns the read value on success.
31
+ # Raises the appropriate exceptions if a failure occurred during the
32
+ # operation.
33
+ # Beware: lists of (small) integers may be (falsely) returned as a string -
34
+ # use str_to_list() to convert such strings.
35
+ def process_result_read(result)
36
+ @conn.class.process_result_read(result)
37
+ end
38
+
39
+ # Processes a result element from the list returned by req_list() which
40
+ # originated from a write operation.
41
+ # Raises the appropriate exceptions if a failure occurred during the
42
+ # operation.
43
+ def process_result_write(result)
44
+ # note: we need to process a commit result as the write has been committed
45
+ @conn.class.check_fail_abort(result)
46
+ @conn.class.process_result_commit(result)
47
+ end
48
+
49
+ # Processes a result element from the list returned by req_list() which
50
+ # originated from a add_del_on_list operation.
51
+ # Raises the appropriate exceptions if a failure occurred during the
52
+ # operation.
53
+ def process_result_add_del_on_list(result)
54
+ @conn.class.check_fail_abort(result)
55
+ @conn.class.process_result_add_del_on_list(result)
56
+ end
57
+
58
+ # Processes a result element from the list returned by req_list() which
59
+ # originated from a add_on_nr operation.
60
+ # Raises the appropriate exceptions if a failure occurred during the
61
+ # operation.
62
+ def process_result_add_on_nr(result)
63
+ @conn.class.check_fail_abort(result)
64
+ @conn.class.process_result_add_on_nr(result)
65
+ end
66
+
67
+ # Processes a result element from the list returned by req_list() which
68
+ # originated from a test_and_set operation.
69
+ # Raises the appropriate exceptions if a failure occurred during the
70
+ # operation.
71
+ def process_result_test_and_set(result)
72
+ @conn.class.check_fail_abort(result)
73
+ @conn.class.process_result_test_and_set(result)
74
+ end
75
+
76
+ # Read the value at key.
77
+ # Beware: lists of (small) integers may be (falsely) returned as a string -
78
+ # use str_to_list() to convert such strings.
79
+ def read(key)
80
+ result = @conn.call(:read, [key])
81
+ @conn.class.process_result_read(result)
82
+ end
83
+
84
+ # Write the value to key.
85
+ def write(key, value, binary = false)
86
+ value = @conn.class.encode_value(value, binary)
87
+ result = @conn.call(:write, [key, value])
88
+ @conn.class.check_fail_abort(result)
89
+ @conn.class.process_result_commit(result)
90
+ end
91
+
92
+ # Changes the list stored at the given key, i.e. first adds all items in
93
+ # to_add then removes all items in to_remove.
94
+ # Both, to_add and to_remove, must be lists.
95
+ # Assumes en empty list if no value exists at key.
96
+ def add_del_on_list(key, to_add, to_remove)
97
+ result = @conn.call(:add_del_on_list, [key, to_add, to_remove])
98
+ @conn.class.check_fail_abort(result)
99
+ @conn.class.process_result_add_del_on_list(result)
100
+ end
101
+
102
+ # Changes the number stored at the given key, i.e. adds some value.
103
+ # Assumes 0 if no value exists at key.
104
+ def add_on_nr(key, to_add)
105
+ result = @conn.call(:add_on_nr, [key, to_add])
106
+ @conn.class.check_fail_abort(result)
107
+ @conn.class.process_result_add_on_nr(result)
108
+ end
109
+
110
+ # Atomic test and set, i.e. if the old value at key is old_value, then
111
+ # write new_value.
112
+ def test_and_set(key, old_value, new_value)
113
+ result = @conn.call(:test_and_set, [key, old_value, new_value])
114
+ @conn.class.check_fail_abort(result)
115
+ @conn.class.process_result_test_and_set(result)
116
+ end
117
+
118
+ # Atomic test and set, i.e. if the old value at key is oldvalue, then
119
+ # write newvalue.
120
+ def test_and_set(key, oldvalue, newvalue)
121
+ oldvalue = @conn.class.encode_value(oldvalue)
122
+ newvalue = @conn.class.encode_value(newvalue)
123
+ result = @conn.call(:test_and_set, [key, oldvalue, newvalue])
124
+ @conn.class.check_fail_abort(result)
125
+ @conn.class.process_result_test_and_set(result)
126
+ end
127
+
128
+ include InternalScalarisNopClose
129
+ end
130
+ end
@@ -1,3 +1,3 @@
1
1
  module Scalaroid
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/scalaroid.gemspec CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "scalaroid"
9
- s.version = "0.0.1"
9
+ s.version = "0.0.2"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
@@ -26,7 +26,15 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "bin/scalaroid",
28
28
  "lib/scalaroid.rb",
29
+ "lib/scalaroid/delete_result.rb",
29
30
  "lib/scalaroid/json_connection.rb",
31
+ "lib/scalaroid/json_req_list.rb",
32
+ "lib/scalaroid/json_req_list_transaction.rb",
33
+ "lib/scalaroid/json_req_list_transaction_single_op.rb",
34
+ "lib/scalaroid/pub_sub.rb",
35
+ "lib/scalaroid/replicated_dht.rb",
36
+ "lib/scalaroid/transaction.rb",
37
+ "lib/scalaroid/transaction_single_op.rb",
30
38
  "lib/scalaroid/version.rb",
31
39
  "scalaroid.gemspec",
32
40
  "test/replicated_dht_test.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scalaroid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Teodor Pripoae
@@ -95,7 +95,15 @@ files:
95
95
  - Rakefile
96
96
  - bin/scalaroid
97
97
  - lib/scalaroid.rb
98
+ - lib/scalaroid/delete_result.rb
98
99
  - lib/scalaroid/json_connection.rb
100
+ - lib/scalaroid/json_req_list.rb
101
+ - lib/scalaroid/json_req_list_transaction.rb
102
+ - lib/scalaroid/json_req_list_transaction_single_op.rb
103
+ - lib/scalaroid/pub_sub.rb
104
+ - lib/scalaroid/replicated_dht.rb
105
+ - lib/scalaroid/transaction.rb
106
+ - lib/scalaroid/transaction_single_op.rb
99
107
  - lib/scalaroid/version.rb
100
108
  - scalaroid.gemspec
101
109
  - test/replicated_dht_test.rb