github.com/turingchain2020/turingchain@v1.1.21/common/db/go_ssdb_util.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package db 6 7 import ( 8 "bytes" 9 "fmt" 10 "net" 11 "strconv" 12 "sync" 13 "time" 14 15 "github.com/turingchain2020/turingchain/types" 16 ) 17 18 //const 19 const ( 20 ENDN = '\n' 21 ENDR = '\r' 22 23 OK = "ok" 24 NotFound = "not_found" 25 26 ReadTimeOut = 3 27 WriteTimeOut = 3 28 29 ReadBufSize = 8 * 1024 30 31 IteratorPageSize = 10240 32 33 PooledSize = 3 34 ) 35 36 //SDBClient ... 37 type SDBClient struct { 38 sock *net.TCPConn 39 timeZero time.Time 40 mu sync.Mutex 41 } 42 43 //SDBPool SDB池 44 type SDBPool struct { 45 clients []*SDBClient 46 round *RoundInt 47 } 48 49 //RoundInt ... 50 type RoundInt struct { 51 round int 52 index int 53 } 54 55 func (val *RoundInt) incr() int { 56 val.index++ 57 if val.index < val.round { 58 return val.index 59 } 60 val.index = 0 61 return val.index 62 } 63 64 func (pool *SDBPool) get() *SDBClient { 65 return pool.clients[pool.round.incr()] 66 } 67 func (pool *SDBPool) close() { 68 for _, v := range pool.clients { 69 err := v.Close() 70 dlog.Error("ssdb close ", "error", err) 71 } 72 } 73 74 //NewSDBPool new 75 func NewSDBPool(nodes []*SsdbNode) (pool *SDBPool, err error) { 76 dbpool := &SDBPool{} 77 for i := 0; i < PooledSize; i++ { 78 for _, v := range nodes { 79 db, err := Connect(v.ip, v.port) 80 if err != nil { 81 dlog.Error("connect to ssdb error!", "ssdb", v) 82 return dbpool, types.ErrDataBaseDamage 83 } 84 dbpool.clients = append(dbpool.clients, db) 85 } 86 } 87 dbpool.round = &RoundInt{round: PooledSize * len(nodes)} 88 return dbpool, nil 89 } 90 91 //Connect 连接 92 func Connect(ip string, port int) (*SDBClient, error) { 93 addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port)) 94 if err != nil { 95 return nil, err 96 } 97 sock, err := net.DialTCP("tcp", nil, addr) 98 if err != nil { 99 return nil, err 100 } 101 102 var c SDBClient 103 c.sock = sock 104 c.timeZero = time.Time{} 105 106 return &c, nil 107 } 108 109 //Get 获取指定 key 的值内容 110 // key 键值 111 // 返回 一个 Value,可以方便的向其它类型转换 112 // 返回 一个可能的错误,操作成功返回 nil 113 func (c *SDBClient) Get(key string) (*Value, error) { 114 resp, err := c.Do("get", key) 115 if err != nil { 116 return nil, newErrorf(err, "Get %s error", key) 117 } 118 119 if len(resp) == 0 { 120 return nil, newError("ssdb response error") 121 } 122 123 if len(resp) == 2 && resp[0] == OK { 124 return toValue(resp[1]), nil 125 } 126 127 return nil, makeError(resp, key) 128 } 129 130 //Set 设置指定 key 的值内容 131 // key 键值 132 // val 存贮的 value 值,val只支持基本的类型,如果要支持复杂的类型,需要开启连接池的 Encoding 选项 133 // ttl 可选,设置的过期时间,单位为秒 134 // 返回 err,可能的错误,操作成功返回 nil 135 func (c *SDBClient) Set(key string, val []byte) (err error) { 136 var resp []string 137 resp, err = c.Do("set", key, val) 138 if err != nil { 139 return newErrorf(err, "Set %s error", key) 140 } 141 if len(resp) > 0 && resp[0] == OK { 142 return nil 143 } 144 return makeError(resp, key) 145 } 146 147 //Del 删除指定 key 148 // key 要删除的 key 149 // 返回 err,执行的错误,操作成功返回 nil 150 func (c *SDBClient) Del(key string) error { 151 resp, err := c.Do("del", key) 152 if err != nil { 153 return newErrorf(err, "Del %s error", key) 154 } 155 156 //response looks like s: [ok 1] 157 if len(resp) > 0 && resp[0] == OK { 158 return nil 159 } 160 return makeError(resp, key) 161 } 162 163 //MultiSet 批量设置一批 key-value. 164 // 包含 key-value 的字典 165 // 返回 err,可能的错误,操作成功返回 nil 166 func (c *SDBClient) MultiSet(kvs map[string][]byte) (err error) { 167 168 args := []interface{}{"multi_set"} 169 170 for k, v := range kvs { 171 args = append(args, k) 172 args = append(args, v) 173 } 174 resp, err := c.Do(args...) 175 176 if err != nil { 177 return newErrorf(err, "MultiSet %s error", kvs) 178 } 179 180 if len(resp) > 0 && resp[0] == OK { 181 return nil 182 } 183 return makeError(resp, kvs) 184 } 185 186 //MultiDel 批量删除一批 key 和其对应的值内容. 187 // key,要删除的 key,可以为多个 188 // 返回 err,可能的错误,操作成功返回 nil 189 func (c *SDBClient) MultiDel(key ...string) (err error) { 190 if len(key) == 0 { 191 return nil 192 } 193 args := []interface{}{"multi_del"} 194 for _, v := range key { 195 args = append(args, v) 196 } 197 resp, err := c.Do(args...) 198 if err != nil { 199 return newErrorf(err, "MultiDel %s error", key) 200 } 201 202 if len(resp) > 0 && resp[0] == OK { 203 return nil 204 } 205 return makeError(resp, key) 206 } 207 208 //MultiGet 批量删除一批 key 和其对应的值内容. 209 // key,要删除的 key,可以为多个 210 // 返回 err,可能的错误,操作成功返回 nil 211 func (c *SDBClient) MultiGet(key ...string) (vals []*Value, err error) { 212 if len(key) == 0 { 213 return nil, nil 214 } 215 data := []interface{}{"multi_get"} 216 for _, k := range key { 217 data = append(data, k) 218 } 219 resp, err := c.Do(data...) 220 221 if err != nil { 222 return nil, newErrorf(err, "MultiGet %s error", key) 223 } 224 225 size := len(resp) 226 if size > 0 && resp[0] == OK { 227 for i := 1; i < size && i+1 < size; i += 2 { 228 vals = append(vals, toValue(resp[i+1])) 229 } 230 return vals, nil 231 } 232 return nil, makeError(resp, key) 233 } 234 235 //Keys 列出处于区间 (key_start, key_end] 的 key 列表.("", ""] 表示整个区间. 236 // keyStart int 返回的起始 key(不包含), 空字符串表示 -inf. 237 // keyEnd int 返回的结束 key(包含), 空字符串表示 +inf. 238 // limit int 最多返回这么多个元素. 239 // 返回 返回包含 key 的数组. 240 // 返回 err,可能的错误,操作成功返回 nil 241 func (c *SDBClient) Keys(keyStart, keyEnd string, limit int64) ([]string, error) { 242 243 resp, err := c.Do("keys", keyStart, keyEnd, limit) 244 245 if err != nil { 246 return nil, newErrorf(err, "Keys [%s,%s] %d error", keyStart, keyEnd, limit) 247 } 248 if len(resp) > 0 && resp[0] == OK { 249 return resp[1:], nil 250 } 251 return nil, makeError(resp, keyStart, keyEnd, limit) 252 } 253 254 //Rkeys 列出处于区间 (key_start, key_end] 的 key 列表.("", ""] 表示整个区间.反向选择 255 // keyStart int 返回的起始 key(不包含), 空字符串表示 -inf. 256 // keyEnd int 返回的结束 key(包含), 空字符串表示 +inf. 257 // limit int 最多返回这么多个元素. 258 // 返回 返回包含 key 的数组. 259 // 返回 err,可能的错误,操作成功返回 nil 260 func (c *SDBClient) Rkeys(keyStart, keyEnd string, limit int64) ([]string, error) { 261 262 resp, err := c.Do("rkeys", keyStart, keyEnd, limit) 263 264 if err != nil { 265 return nil, newErrorf(err, "Rkeys [%s,%s] %d error", keyStart, keyEnd, limit) 266 } 267 if len(resp) > 0 && resp[0] == OK { 268 return resp[1:], nil 269 } 270 return nil, makeError(resp, keyStart, keyEnd, limit) 271 } 272 273 //Do do 274 func (c *SDBClient) Do(args ...interface{}) ([]string, error) { 275 c.mu.Lock() 276 defer c.mu.Unlock() 277 //dlog.Warn("begin to send", "value", fmt.Sprintf("%v", args)) 278 err := c.send(args) 279 if err != nil { 280 //dlog.Error("send error", "value", fmt.Sprintf("%v", err)) 281 return nil, err 282 } 283 resp, err := c.recv() 284 //dlog.Warn("begin to return", "value", fmt.Sprintf("%v", resp)) 285 return resp, err 286 } 287 288 func (c *SDBClient) send(args []interface{}) error { 289 var packetBuf bytes.Buffer 290 var err error 291 for _, arg := range args { 292 switch arg := arg.(type) { 293 case string: 294 if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10)); err != nil { 295 return err 296 } 297 if err = packetBuf.WriteByte(ENDN); err != nil { 298 return err 299 } 300 if _, err = packetBuf.WriteString(arg); err != nil { 301 return err 302 } 303 case []string: 304 for _, a := range arg { 305 if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(a)), 10)); err != nil { 306 return err 307 } 308 if err = packetBuf.WriteByte(ENDN); err != nil { 309 return err 310 } 311 if _, err = packetBuf.WriteString(a); err != nil { 312 return err 313 } 314 if err = packetBuf.WriteByte(ENDN); err != nil { 315 return err 316 } 317 } 318 continue 319 case []byte: 320 if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10)); err != nil { 321 return err 322 } 323 if err = packetBuf.WriteByte(ENDN); err != nil { 324 return err 325 } 326 if _, err = packetBuf.Write(arg); err != nil { 327 return err 328 } 329 case int64: 330 bs := strconv.AppendInt(nil, arg, 10) 331 if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(bs)), 10)); err != nil { 332 return err 333 } 334 if err = packetBuf.WriteByte(ENDN); err != nil { 335 return err 336 } 337 if _, err = packetBuf.Write(bs); err != nil { 338 return err 339 } 340 case nil: 341 if err = packetBuf.WriteByte(0); err != nil { 342 return err 343 } 344 if err = packetBuf.WriteByte(ENDN); err != nil { 345 return err 346 } 347 if _, err = packetBuf.WriteString(""); err != nil { 348 return err 349 } 350 default: 351 return fmt.Errorf("bad arguments type") 352 } 353 if err = packetBuf.WriteByte(ENDN); err != nil { 354 return err 355 } 356 } 357 if err = packetBuf.WriteByte(ENDN); err != nil { 358 return err 359 } 360 if err = c.sock.SetWriteDeadline(time.Now().Add(time.Second * WriteTimeOut)); err != nil { 361 return err 362 } 363 for _, err = packetBuf.WriteTo(c.sock); packetBuf.Len() > 0; { 364 if err != nil { 365 packetBuf.Reset() 366 return newErrorf(err, "client socket write error") 367 } 368 } 369 //设置不超时 370 if err := c.sock.SetWriteDeadline(c.timeZero); err != nil { 371 return err 372 } 373 packetBuf.Reset() 374 return nil 375 } 376 func (c *SDBClient) recv() (resp []string, err error) { 377 packetBuf := []byte{} 378 //设置读取数据超时, 379 if err = c.sock.SetReadDeadline(time.Now().Add(time.Second * ReadTimeOut)); err != nil { 380 return nil, err 381 } 382 //数据包分解,发现长度,找到结尾,循环发现,发现空行,结束 383 readBuf := make([]byte, ReadBufSize) 384 for { 385 bufSize, err := c.sock.Read(readBuf) 386 if err != nil { 387 return nil, newErrorf(err, "client socket read error") 388 } 389 if bufSize < 1 { 390 continue 391 } 392 packetBuf = append(packetBuf, readBuf[:bufSize]...) 393 394 for { 395 rsp, n := c.parse(packetBuf) 396 if n == -1 { 397 break 398 } else if n == -2 { 399 return nil, newErrorf(err, "parse error") 400 } else { 401 resp = append(resp, rsp) 402 packetBuf = packetBuf[n+1:] 403 } 404 } 405 } 406 } 407 408 func (c *SDBClient) parse(buf []byte) (resp string, size int) { 409 n := bytes.IndexByte(buf, ENDN) 410 size = -1 411 if n != -1 { 412 if n == 0 || n == 1 && buf[0] == ENDR { //空行,说明一个数据包结束 413 size = -2 414 return 415 } 416 //数据包开始,包长度解析 417 blockSize := ToNum(buf[:n]) 418 bufSize := len(buf) 419 420 if n+blockSize < bufSize { 421 resp = string(buf[n+1 : blockSize+n+1]) 422 for i := blockSize + n + 1; i < bufSize; i++ { 423 if buf[i] == ENDN { 424 size = i 425 return 426 } 427 } 428 } 429 } 430 return 431 } 432 433 // Close The Client Connection 434 func (c *SDBClient) Close() error { 435 return c.sock.Close() 436 } 437 438 //生成通过的错误信息,已经确定是有错误 439 func makeError(resp []string, errKey ...interface{}) error { 440 if len(resp) < 1 { 441 return newError("ssdb response error") 442 } 443 //正常返回的不存在不报错,如果要捕捉这个问题请使用exists 444 if resp[0] == NotFound { 445 return ErrNotFoundInDb 446 } 447 if len(errKey) > 0 { 448 return newError("access ssdb error, code is %v, parameter is %v", resp, errKey) 449 } 450 return newError("access ssdb error, code is %v", resp) 451 452 } 453 454 //Value 扩展值,原始类型为 string 455 type Value struct { 456 val []byte 457 } 458 459 //返回 string 的值 460 func (v *Value) String() string { 461 return string(v.val) 462 } 463 464 //Bytes 返回 []byte 类型的值 465 func (v *Value) Bytes() []byte { 466 return v.val 467 } 468 469 func toValue(val interface{}) *Value { 470 if val == nil { 471 return nil 472 } 473 if v, ok := val.(string); ok { 474 return &Value{val: []byte(v)} 475 } else if v, ok := val.([]byte); ok { 476 return &Value{val: v} 477 } else { 478 dlog.Error("unsupported value type", "value", val) 479 return nil 480 } 481 } 482 483 var ( 484 byt = []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 485 maxByteSize byte = 57 486 minByteSize byte = 48 487 ) 488 489 //ToNum []byte -> int 490 func ToNum(bs []byte) int { 491 re := 0 492 for _, v := range bs { 493 if v > maxByteSize || v < minByteSize { 494 return re 495 } 496 re = re*10 + byt[v] 497 } 498 return re 499 } 500 501 var ( 502 //FormatString 格式化字符串 503 FormatString = "%v\nthe trace error is\n%s" 504 ) 505 506 //返回一个错误 507 func newError(format string, p ...interface{}) error { 508 return fmt.Errorf(format, p...) 509 } 510 511 //按格式返回一个错误 512 //同时携带原始的错误信息 513 func newErrorf(err error, format string, p ...interface{}) error { 514 return fmt.Errorf(FormatString, fmt.Sprintf(format, p...), err) 515 }