tair 0.1.0.pre

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.
@@ -0,0 +1,12 @@
1
+ require 'tair/operation/incr'
2
+
3
+ module Tair
4
+ module Operation
5
+
6
+ def count(key)
7
+ incr(key, 0, op: :count)
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'tair/operation/incr'
2
+
3
+ module Tair
4
+ module Operation
5
+
6
+ def decr(key, step=1)
7
+ incr(key, -step, op: :decr)
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,49 @@
1
+ require 'tair/operation/get'
2
+
3
+ module Tair
4
+ module Operation
5
+
6
+ #TODO: support batch delete
7
+ #FIXME: 某些集群上存在删除失败的bug,需要找时间看一下
8
+ def delete(key)
9
+ raise InvalidKeyType unless valid_key?(key)
10
+ req = DelRequest.new(key)
11
+ operate(:delete, req, key: key) do |res|
12
+ DelResponse.new(res).success?
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+
19
+ class DelRequest < GetRequest
20
+ PACKET_CODE = 3
21
+ end
22
+
23
+
24
+ class DelResponse < Response
25
+
26
+ def success?
27
+ decode
28
+ @success
29
+ end
30
+
31
+
32
+ def decode
33
+ return if defined? @success
34
+ Body.read(@body).tap do |body|
35
+ @success = [0, NON_EXIST_ERR_CODE].include?(body.code)
36
+ end
37
+ end
38
+
39
+ NON_EXIST_ERR_CODE = -3998
40
+
41
+
42
+ class Body < BinData::Record
43
+ int32be :version
44
+ int32be :code
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,123 @@
1
+ require 'zlib'
2
+
3
+ module Tair
4
+ module Operation
5
+
6
+ def fetch_data_servers(group)
7
+ log_time "fetch_data_nodes" do
8
+ req = FetchDataServerRequest.new(group)
9
+ config_conn.operate(req) do |res|
10
+ # TODO: error processing
11
+ FetchDataServerResponse.new(res).decode
12
+ end
13
+ end
14
+ end
15
+
16
+ end
17
+
18
+
19
+ class FetchDataServerRequest < Request
20
+
21
+ PACKET_CODE = 1002
22
+
23
+ attr_accessor :group
24
+
25
+ def initialize(group)
26
+ @group = group
27
+ end
28
+
29
+ def body
30
+ Body.new(group: group)
31
+ end
32
+
33
+
34
+ class Body < BinData::Record
35
+ int32be :version, value: 0
36
+ int32be :name_len, value: lambda { group.length + 1 }
37
+ stringz :group
38
+ end
39
+
40
+ end
41
+
42
+
43
+ class FetchDataServerResponse < Response
44
+
45
+ def decode
46
+ Body.read(@body).tap do |body|
47
+ bucket = body[:bucket]
48
+ nodes = DataServersInfo.read(Zlib.inflate(body[:ds_data])).nodes.map do |n|
49
+ [num_str_to_ip(n[:ip_num]), n[:port]].join(":".freeze).freeze
50
+ end
51
+
52
+ Cluster.new.tap do |cluster|
53
+ cluster.update nodes,
54
+ nodes_per_bucket: body[:bucket],
55
+ copying_buckets_count: body[:copy]
56
+
57
+ return cluster
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ UNPACK_METHOD = 'C*'.freeze
64
+ IP_SPLITTER = '.'.freeze
65
+
66
+ def num_str_to_ip(str)
67
+ str.unpack(UNPACK_METHOD).join(IP_SPLITTER).freeze
68
+ end
69
+
70
+
71
+ class CString < BinData::Record
72
+ int32be :len
73
+ stringz :s_value, read_length: lambda { len }
74
+ end
75
+
76
+
77
+ class ConfigServer < BinData::Record
78
+ c_string :server_name
79
+ c_string :server_value
80
+ end
81
+
82
+
83
+ class DataServer < BinData::Record
84
+ int32be :port
85
+ uint8 :ip4
86
+ uint8 :ip3
87
+ uint8 :ip2
88
+ uint8 :ip1
89
+ end
90
+
91
+
92
+ class Body < BinData::Record
93
+ int32be :bucket
94
+ int32be :copy
95
+ int32be :version
96
+ int32be :config_count
97
+ array :config_servers, type: :config_server, initial_length: lambda { config_count }
98
+
99
+ int32be :ds_data_len
100
+ string :ds_data, read_length: lambda { ds_data_len }
101
+
102
+ # 这里的数据现在不关心,所以暂时去掉
103
+ # TODO: 加上 down_servers 逻辑
104
+ #int32be :data_server_count
105
+ #array :data_servers, type: :data_server, initial_length: lambda { data_server_count }
106
+ end
107
+
108
+
109
+ # Yet another data server!
110
+ class YaDataServer < BinData::Record
111
+ string :ip_num, read_length: 4
112
+ int32le :port
113
+ end
114
+
115
+
116
+ class DataServersInfo < BinData::Record
117
+ array :nodes, type: :ya_data_server, read_until: :eof
118
+ end
119
+
120
+
121
+ end
122
+
123
+ end
@@ -0,0 +1,128 @@
1
+ require 'tair/key'
2
+
3
+ module Tair
4
+ module Operation
5
+
6
+ include ::Tair::Key
7
+
8
+ # TODO: support batch get
9
+ def get(key)
10
+ raise InvalidKeyType unless valid_key?(key)
11
+ req = GetRequest.new(key)
12
+ operate(:get, req, key: key) do |res|
13
+ GetResponse.new(res).value
14
+ end
15
+ end
16
+
17
+ alias_method :[], :get
18
+
19
+ end
20
+
21
+
22
+ class GetRequest < Request
23
+
24
+ PACKET_CODE = 2
25
+
26
+ def initialize(key)
27
+ @key = key
28
+ end
29
+
30
+
31
+ def body
32
+ Body.new.tap do |body|
33
+ body.namespace = namespace || 0
34
+ body.key = @key
35
+ end
36
+ end
37
+
38
+
39
+ class Body < BinData::Record
40
+ int8 :start_flag, value: 0
41
+ int16be :namespace
42
+ int32be :key_count, value: 1
43
+ array :meta_flag, type: :uint8, initial_length: 7
44
+ array :default_data, type: :uint8, initial_length: 29
45
+ tair_object :key_obj
46
+
47
+ def key
48
+ key_obj.value
49
+ end
50
+
51
+ def key=(k)
52
+ key_obj.value = k
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+
59
+ class GetResponse < Response
60
+
61
+ def value
62
+ decode
63
+ @value
64
+ end
65
+
66
+
67
+ def success?
68
+ decode
69
+ @success
70
+ end
71
+
72
+
73
+ def decode
74
+ return if defined? @value
75
+
76
+ body = Body.read(@body)
77
+ if @success = body.success?
78
+ @value = body.succ_data.data.value
79
+ else
80
+ # TODO: save failure reason
81
+ @value = nil
82
+ end
83
+ end
84
+
85
+
86
+ class SuccessData < BinData::Record
87
+ int8 :merged
88
+ int32be :area
89
+ int16be :server_flag
90
+ int16be :magic
91
+ int16be :checksum
92
+ int16be :key_size
93
+ int16be :meta_version
94
+ int32be :pad_size
95
+ int32be :value_size
96
+ int8 :flag
97
+ int32be :cdate
98
+ int32be :mdate
99
+ int32be :edate
100
+
101
+ int32be :data_size #?
102
+ string :encoded_key, read_length: lambda{ data_size & 0x3FFFFF }
103
+ key_meta
104
+
105
+ tair_object :data
106
+ end
107
+
108
+
109
+ class FailureData < BinData::Record
110
+ end
111
+
112
+
113
+ class Body < BinData::Record
114
+ int32be :version
115
+ uint32be :code
116
+ int32be :ret_count
117
+
118
+ success_data :succ_data, onlyif: :success?
119
+
120
+ def success?
121
+ code == 0
122
+ end
123
+ end
124
+
125
+
126
+ end
127
+
128
+ end
@@ -0,0 +1,76 @@
1
+ require 'tair/operation/get'
2
+
3
+ module Tair
4
+ module Operation
5
+
6
+ def incr(key, step=1, op: :incr)
7
+ valid_key?(key) or fail InvalidKeyType.new(key)
8
+ valid_count_step?(step) or fail InvalidCountStep.new(step)
9
+
10
+ req = IncrRequest.new(key, step)
11
+ operate(op, req, key: key) do |res|
12
+ IncrResponse.new(res).count
13
+ end
14
+ end
15
+
16
+
17
+ def valid_count_step?(step)
18
+ Fixnum === step
19
+ end
20
+
21
+ alias_method :increase, :incr
22
+ alias_method :inc, :incr
23
+
24
+ end
25
+
26
+
27
+
28
+ class IncrRequest < Request
29
+
30
+ PACKET_CODE = 11
31
+
32
+ def initialize(key, step = 1)
33
+ @key, @step = key, step
34
+ end
35
+
36
+ def body
37
+ Body.new.tap do |body|
38
+ body.step = @step
39
+ body.key_obj = Tair::TairObject.from(@key)
40
+ body.namespace = namespace
41
+ end
42
+ end
43
+
44
+ class Body < BinData::Record
45
+ int8
46
+ int16be :namespace
47
+ int32be :step
48
+ # 如果不存在时的初始化值,默认为0
49
+ int32be :init_value
50
+ int32be :expired_at
51
+
52
+ key_meta
53
+ tair_object :key_obj
54
+ end
55
+
56
+ end
57
+
58
+
59
+ class IncrResponse < Response
60
+
61
+ def count
62
+ @count ||= decode.current_count.value
63
+ end
64
+
65
+ def decode
66
+ Body.read(body)
67
+ end
68
+
69
+ class Body < BinData::Record
70
+ int32be :version
71
+ int32be :current_count
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,168 @@
1
+ module Tair
2
+ module Operation
3
+
4
+ include ::Tair::Key
5
+ include ::Tair::Log
6
+
7
+ def put(key, value)
8
+ raise InvalidKeyType unless valid_key?(key)
9
+
10
+ if value.nil?
11
+ return delete(key)
12
+ end
13
+
14
+ req = PutRequest.new({key => value})
15
+
16
+ operate(:put, req, key: key) do |res|
17
+ PutResponse.new(res).success?
18
+ end
19
+ end
20
+
21
+ alias_method :set, :put
22
+ alias_method :[]=, :put
23
+
24
+ end
25
+
26
+
27
+ class PutRequest < Request
28
+
29
+ PACKET_CODE = 1
30
+
31
+ def initialize(kv)
32
+ @key, @value = *(kv.to_a.flatten)
33
+ end
34
+
35
+
36
+ def body
37
+ Body.new.tap do |body|
38
+ body.key = @key
39
+ body.value = @value
40
+ body.namespace = namespace || 0
41
+ end
42
+ end
43
+
44
+ TAIR_TYPE_STRING = 2
45
+
46
+ class Body < BinData::Record
47
+ int8 :start_flag, value: 0
48
+ int16be :namespace
49
+ int16be :data_version
50
+ int32be :expiring_at
51
+ key_meta
52
+ tair_object :key_obj
53
+
54
+ key_meta
55
+ tair_object :value_obj
56
+
57
+
58
+ def key
59
+ key_obj.value
60
+ end
61
+
62
+ def key=(v)
63
+ key_obj.value = v
64
+ end
65
+
66
+ def value
67
+ value_obj.value
68
+ end
69
+
70
+ def value=(v)
71
+ value_obj.value = v
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+
79
+ class PutResponse < Response
80
+
81
+ def success?
82
+ return true
83
+
84
+ decode
85
+ @value
86
+ end
87
+
88
+
89
+ def decode
90
+ body = Body.read(@body)
91
+ if body.success?
92
+ data = body.succ_data
93
+ type, raw = data.value_type >> 1, data.raw_value
94
+ @value = case type
95
+ when TAIR_TYPE_INT then BinData::Double.read(raw).to_i
96
+ when TAIR_TYPE_STRING then raw.to_s
97
+ end
98
+ else
99
+ nil
100
+ end
101
+ end
102
+
103
+
104
+ # tair serialize type
105
+ TAIR_TYPE_INT = 1
106
+ TAIR_TYPE_STRING = 2
107
+ TAIR_TYPE_BOOL = 3
108
+ TAIR_TYPE_LONG = 4
109
+ TAIR_TYPE_DATE = 5
110
+ TAIR_TYPE_BYTE = 6
111
+ TAIR_TYPE_FLOAT = 7
112
+ TAIR_TYPE_DOUBLE = 8
113
+ TAIR_TYPE_BYTEARRAY = 9
114
+ TAIR_TYPE_SERIALIZE = 10
115
+ TAIR_TYPE_INCDATA = 11
116
+ TAIR_TYPE_MIXEDKEY = 12
117
+
118
+
119
+ class SuccessData < BinData::Record
120
+ int8 :merged
121
+ int32be :area
122
+ int16be :server_flag
123
+ int16be :magic
124
+ int16be :checksum
125
+ int16be :key_size
126
+ int16be :meta_version
127
+ int32be :pad_size
128
+ int32be :value_size
129
+ int8 :flag
130
+ int32be :cdate
131
+ int32be :mdate
132
+ int32be :edate
133
+
134
+ int32be :data_size #?
135
+ string :encoded_key, read_length: lambda{ data_size & 0x3FFFFF }
136
+ array :key_meta, type: :int8, initial_length: 36
137
+ int32be :value_len
138
+ int16be :value_type
139
+ string :raw_value, read_length: lambda { value_len - 2 }
140
+ end
141
+
142
+
143
+ class FailureData < BinData::Record
144
+ end
145
+
146
+
147
+ class Body < BinData::Record
148
+ int32be :version
149
+ uint32be :code
150
+ int32be :ret_count
151
+
152
+ success_data :succ_data, onlyif: :success?
153
+ failure_data :fail_data, onlyif: :failed?
154
+
155
+ def success?
156
+ ret_count > 0
157
+ end
158
+
159
+ def failed?
160
+ !success?
161
+ end
162
+
163
+ end
164
+
165
+
166
+ end
167
+
168
+ end