scalaroid 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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