Ver código fonte

Add Ping method. (#91)

* Add Ping method.
Andrei Avram 6 anos atrás
pai
commit
a41fca850d
2 arquivos alterados com 34 adições e 0 exclusões
  1. 31 0
      memcache/memcache.go
  2. 3 0
      memcache/memcache_test.go

+ 31 - 0
memcache/memcache.go

@@ -112,6 +112,7 @@ var (
 	resultTouched   = []byte("TOUCHED\r\n")
 
 	resultClientErrorPrefix = []byte("CLIENT_ERROR ")
+	versionPrefix           = []byte("VERSION")
 )
 
 // New returns a memcache client using the provided server(s)
@@ -398,6 +399,30 @@ func (c *Client) flushAllFromAddr(addr net.Addr) error {
 	})
 }
 
+// ping sends the version command to the given addr
+func (c *Client) ping(addr net.Addr) error {
+	return c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
+		if _, err := fmt.Fprintf(rw, "version\r\n"); err != nil {
+			return err
+		}
+		if err := rw.Flush(); err != nil {
+			return err
+		}
+		line, err := rw.ReadSlice('\n')
+		if err != nil {
+			return err
+		}
+
+		switch {
+		case bytes.HasPrefix(line, versionPrefix):
+			break
+		default:
+			return fmt.Errorf("memcache: unexpected response line from ping: %q", string(line))
+		}
+		return nil
+	})
+}
+
 func (c *Client) touchFromAddr(addr net.Addr, keys []string, expiration int32) error {
 	return c.withAddrRw(addr, func(rw *bufio.ReadWriter) error {
 		for _, key := range keys {
@@ -644,6 +669,12 @@ func (c *Client) DeleteAll() error {
 	})
 }
 
+// Ping checks all instances if they are alive. Returns error if any
+// of them is down.
+func (c *Client) Ping() error {
+	return c.selector.Each(c.ping)
+}
+
 // Increment atomically increments key by delta. The return value is
 // the new value after being incremented or an error. If the value
 // didn't exist in memcached the error is ErrCacheMiss. The value in

+ 3 - 0
memcache/memcache_test.go

@@ -209,6 +209,9 @@ func testWithClient(t *testing.T, c *Client) {
 		t.Errorf("post-DeleteAll want ErrCacheMiss, got %v", err)
 	}
 
+	// Test Ping
+	err = c.Ping()
+	checkErr(err, "error ping: %s", err)
 }
 
 func testTouchWithClient(t *testing.T, c *Client) {