/godis.go

http://github.com/simonz05/exp-godis · Go · 114 lines · 86 code · 25 blank · 3 comment · 18 complexity · f72aca28af6f4494d39955de7e5e1162 MD5 · raw file

  1. // package godis implements a db client for Redis.
  2. package godis
  3. import (
  4. "bytes"
  5. "strings"
  6. )
  7. type Client struct {
  8. Addr string
  9. Proto string
  10. pool *connPool
  11. }
  12. func NewClient(addr string) *Client {
  13. if addr == "" {
  14. addr = "tcp:127.0.0.1:6379"
  15. }
  16. na := strings.SplitN(addr, ":", 2)
  17. return &Client{Addr: na[1], Proto: na[0], pool: newConnPool()}
  18. }
  19. func (c *Client) Call(args ...interface{}) (*Reply, error) {
  20. conn, err := c.Connect()
  21. defer c.Push(conn)
  22. if err != nil {
  23. return nil, err
  24. }
  25. conn.Write(args...)
  26. if err != nil {
  27. return nil, err
  28. }
  29. return conn.Read()
  30. }
  31. // pop a connection from pool
  32. func (c *Client) Connect() (conn Connection, err error) {
  33. conn = c.pool.pop()
  34. if conn == nil {
  35. conn, err = NewConn(c.Addr, c.Proto)
  36. if err != nil {
  37. return nil, err
  38. }
  39. }
  40. return conn, nil
  41. }
  42. // return connection to pool
  43. func (c *Client) Push(conn Connection) {
  44. c.pool.push(conn)
  45. }
  46. func (c *Client) AsyncClient() *AsyncClient {
  47. return &AsyncClient{c, bytes.NewBuffer(make([]byte, 0, 1024*16)), nil, 0}
  48. }
  49. type AsyncClient struct {
  50. *Client
  51. buf *bytes.Buffer
  52. conn Connection
  53. queued int
  54. }
  55. func NewAsyncClient(addr string) *AsyncClient {
  56. return &AsyncClient{
  57. NewClient(addr),
  58. bytes.NewBuffer(make([]byte, 0, 1024*16)),
  59. nil,
  60. 0,
  61. }
  62. }
  63. func (ac *AsyncClient) Call(args ...interface{}) (err error) {
  64. _, err = ac.buf.Write(format(args...))
  65. ac.queued++
  66. return err
  67. }
  68. func (ac *AsyncClient) Poll() (*Reply, error) {
  69. if ac.conn == nil {
  70. conn, e := NewConn(ac.Addr, ac.Proto)
  71. if e != nil {
  72. return nil, e
  73. }
  74. ac.conn = conn
  75. }
  76. if ac.buf.Len() > 0 {
  77. _, err := ac.buf.WriteTo(ac.conn.Sock())
  78. if err != nil {
  79. return nil, err
  80. }
  81. }
  82. reply, e := ac.conn.Read()
  83. ac.queued--
  84. return reply, e
  85. }
  86. func (ac *AsyncClient) Close() {
  87. ac.conn.Close()
  88. ac.conn = nil
  89. }