tair 0.1.0.pre

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