Giter VIP home page Giter VIP logo

gomemcache's Introduction

About

This is a memcache client library for the Go programming language (http://golang.org/).

Example

Install with:

$ go get github.com/bradfitz/gomemcache/memcache

Then use it like:

import (
    "github.com/bradfitz/gomemcache/memcache"
)

func main() {
     mc := memcache.New("10.0.0.1:11211", "10.0.0.2:11211", "10.0.0.3:11212")
     mc.Set(&memcache.Item{Key: "foo", Value: []byte("my value")})

     it, err := mc.Get("foo")
     ...
}

Full docs, see:

See https://pkg.go.dev/github.com/bradfitz/gomemcache/memcache

Or run:

$ godoc github.com/bradfitz/gomemcache/memcache

gomemcache's People

Contributors

andreiavrammsd avatar arodland avatar bradfitz avatar bronze1man avatar craigmj avatar d2fn avatar eclipseo avatar fira42073 avatar garyburd avatar gpaul avatar jeddenlea avatar jgrahamc avatar kennygrant avatar mar4uk avatar mingrammer avatar mostynb avatar nickdavies avatar qoelet avatar rhencke avatar robfig avatar sshaplygin avatar urandom2 avatar vanstinator avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gomemcache's Issues

Add health check support

At the moment when creating a memcached client using client := memcache.New(address)

New function does not return any error or something, which it should when doing ss.SetServers(server...). Provide an extra function which returns stats or does a ping pong of sorts which checks is server is up and running

MaxConns parameter?

Hiya,

I'm using this library for an application that absolutely pounds a memcached server. Something on the order of 8k queries per second is on my dev branch. However, because memcached is limited by default to 1024 simultaneous connections, I keep overrunning that limit.

Would it be worthwhile to add a MaxConns parameter to the Client object? I'm already working on it on my own fork, but if you'd like, when I finish it, I'm happy to PR it back in.

Alternatively, I could also stop trying to kill my memcached server, or maybe not run 8k queries per second. Eh, this is more fun though.

Thanks!

Edit: My changes are done, come take a look: https://github.com/demilletech/gomemcache

how to set timeout

hi, I read code and find Timeout val int client struct , But I don't know how to set the Timeout .

ConnectTimeoutError should satisfy net.Error

I’m not quite sure why it was done this way, but gomemcache creates a ConnectTimeoutError instead of the standard i/o timeout or net.OpError.

This, in turn, does not have the Timeout() and Temporary() methods to satisfy the net.Error interface, obfuscating the error handling for clients.

In our library, we ended up recreating a net.OpError: Shopify/goose#35

Could you clarify why it was done way?

I would suggest getting rid of ConnectTimeoutError and instead wrapping the poll.TimeoutError in a net.OpError to satisfy the interface and retain proper messaging.

Compilation error on go get

After I run,

$ go get github.com/bradfitz/gomemcache/memcache

My shell outputs:

github.com/bradfitz/gomemcache/memcache

src/github.com/bradfitz/gomemcache/memcache/selector.go:92: undefined: sync.Pool

Is there something I am doing wrong or is the code broken?

I am attempting to install this on Linux Ubuntu 14.04 with Go 1.2.1 installed.

ConnectEx

dial tcp 127.0.0.1:11211: ConnectEx tcp: Only one usage of each socket address (protocol/network address/port) is normally permitted.

package throws panic if one of the servers is not available during Set

2019/07/02 13:46:46 [Recovery] 2019/07/02 - 13:46:46 panic recovered:
runtime error: invalid memory address or nil pointer dereference
/usr/local/Cellar/go/1.12.6/libexec/src/runtime/panic.go:82 (0x1042540)
	panicmem: panic(memoryError)
/usr/local/Cellar/go/1.12.6/libexec/src/runtime/signal_unix.go:390 (0x104236f)
	sigpanic: panicmem()
/Users/user/go/src/git/user/app/vendor/git/plateng/memcached-pkg-golang/memcached.go:57 (0x15c2e9e)
	(*Client).Get: return string(retValue.Value)
/Users/user/go/src/git/user/app/main.go:32 (0x15c3a6d)
	main.func1: fmt.Println(cache.Memcached.Get("key1"))
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/context.go:124 (0x14dabc9)
	(*Context).Next: c.handlers[c.index](c)
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/recovery.go:83 (0x14ede99)
	RecoveryWithWriter.func1: c.Next()
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/context.go:124 (0x14dabc9)
	(*Context).Next: c.handlers[c.index](c)
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/logger.go:240 (0x14ecf40)
	LoggerWithConfig.func1: c.Next()
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/context.go:124 (0x14dabc9)
	(*Context).Next: c.handlers[c.index](c)
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/gin.go:425 (0x14e44b7)
	serveError: c.Next()
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/gin.go:418 (0x14e41d8)
	(*Engine).handleHTTPRequest: serveError(c, http.StatusNotFound, default404Body)
/Users/user/go/src/git/user/app/vendor/github.com/gin-gonic/gin/gin.go:351 (0x14e3c13)
	(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
/usr/local/Cellar/go/1.12.6/libexec/src/net/http/server.go:2774 (0x12c59d7)
	serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
/usr/local/Cellar/go/1.12.6/libexec/src/net/http/server.go:1878 (0x12c15c0)
	(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
/usr/local/Cellar/go/1.12.6/libexec/src/runtime/asm_amd64.s:1337 (0x1059d20)
	goexit: BYTE	$0x90	// NOP

GetMulti giving i/o timeout

Hi ,

Just wanted to know is there any constraint on using getMulti because it gived i/o timeout if the key array is large, i.e 15K.

Let me know if there is any threshold on max number of keys that could be passed.

Better distribution in PickServer?

Hi, is there any particular reason to use CRC32 instead of a better distribution algorithm?

Even MD5 or SHA1 would distribute better amongst servers, not to mention ketama based algorithms (which I don´t know if there is any proper golang implementation)

no Go source files error. Perhaps repo is not properly tagged ?

This is the error I get when goinstalling on freebsd 9.0 RELEASE, amd64 , latest go weekly (i just pulled)

gopath/src/github.com/bradfitz/gomemcache: no Go source files

Note that other pkgs built fine (mgo, go-gb, bson, etc)

Thanks.

Let me know if you need more details.

Consistent Hashing?

Hi @bradfitz ,
Does this client supports consistent hashing since its return CacheMiss and CacheHit randomly. I am using it in Memcached cluster in Kubernetes with 5 pods.

Regards
Abhishek

support SetMulti method

I want SetMulti method like GetMulti.
Memcached doesn't have such method, but it can be implemented, and will be faster if using "noreply" flag. just like other language's clients.
Is there any plan to implement it?

Expiration not set?

I can't seem to get the Expiration property to be set:

package main

import (
    "github.com/bradfitz/gomemcache/memcache" // "io/ioutil"
    "log"
    "time"
)

func main() {
    mc := memcache.New("memcache_server_1:11211")
    mc.Timeout = time.Second * 5 // Increase the client's timeout to 5 seconds
    mc.Set(&memcache.Item{Key: "foo", Value: []byte("my value"), Expiration: int32(604800)})

    it, err := mc.Get("foo")

    log.Print(it.Key)
    log.Print(string(it.Value))
    log.Print(it.Expiration)
    log.Print(err)
}

outputs:

go run mc.go
2016/10/13 08:50:48 foo
2016/10/13 08:50:48 my value
2016/10/13 08:50:48 0
2016/10/13 08:50:48 <nil>

Where I feel it should output 604800 instead of 0.

Can you help?


go version go1.7.1 darwin/amd64
memcached:1.4.24

Re-resolve server names on connection failure

Currently the server names are only resolved once, to optimize performance. However, this doesn't support dynamic environments well in which the name should be re-resolved.

I think that I can work around this by wrapping the library calls, and creating a new connection upon error (or maybe creating something which detects name resolution changes), but this doesn't seem ideal.

I considered periodically running SetServers, but I believe the ServerList isn't public in the client.

Questions about MaxIdleConns

On the begining I set MaxIdleConns to 1 then did pressure test,I got "read: connection reset by peer" or "broken pipe" or "connect: can't assign requested address" panic

then I notice that MaxIdleConns with commend "Consider your expected traffic rates and latency carefully. This should be set to a number higher than your peak parallel requests."

so I set MaxIdleConns to 100+ and the light pressure test is ok
I check the tcp connect with memcached server , exactly 100 ESTABLISHED connect
but when pressure test over , the connects doesn't decrease

On my understanding, MaxIdleConns means to avoid low connect duration cost, make some basic connects to server the normal request. on busy time, it should increase the connect as much as the peak parallel requests, on idle time, it decrease to the MaxIdleConns setting number. It base on my experience on go-sql-driver/mysql and go-redis/redis, but when i turn MaxIdleConns lower than my parallel-pressture, it is show the panic above

Is my wrong understanding? is it exists a cycle timer to recycle the idle persistent connect? or some other recycle mechanism?

Support get-and-touch commands

gat and gats were added to the ASCII protocol in memcached 1.5.3 (2017-11-04). They work like get / gets and have the same response format, but have a new first argument that is an expiration time in the same format as touch.

I can implement this, the approach I would take would be:

  1. Add a param and a conditional in getFromAddr so that it supports either gets or gats using the same code path.
  2. Refactor most of GetMulti into a private method, so that the public method that's left is similarly as thin as Get or Set.
  3. Add an expiration param to the new private getMulti as well.
  4. Add GetAndTouch(key string, seconds int32) and GetAndTouchMulti(keys []string, seconds int32).

If that sounds alright, then I'll go ahead, but I figured I would check in on approach first.

How to use Increment/Decrement

Hi, can you give me a demo about how to use Increment/Decrement. Because I don't find how to set the decimal number in gomemcache.

thanks

Closing client's connection

There isn't any Close() function provided for closing a connection from client side. Probably there is a way to close the connection by manipulating the freeconn attribute of the client instance, but I am not sure if this is a safe solution. Can anyone provide a safe solution for closing a connection from client side?

Does it support kestrel?

I use gomemcache to connect to kestrel like this
mc := memcache.New("***.com:21122")
it, err := mc.Get("kestrel_queue_name")

But err returned like this
memcache: unexpected line in get response: "ERROR\r\n"

Why doesn't function New(server ...string) return err?

// New returns a memcache client using the provided server(s)
// with equal weight. If a server is listed multiple times,
// it gets a proportional amount of weight.
func New(server ...string) *Client {
	ss := new(ServerList)
	ss.SetServers(server...)
	return NewFromSelector(ss)
}

"getsockopt: connection timed out" error under high concurrence

I rewrite my project from python tornado to go(use iris framwork),the basic function tested ok. when I test under high concurrence.the app always stops a while and then comes out the errors that set object to memcache connect timeout and the memcache process was still running . I doute that the client is closed immediately when the server reached the max
client access so that the follow client to connect happens the error.

encounter fault, "Get failed memcache: unexpected line in get response: "ERROR\r\n""

memcached version: 1.5.1
code:
// Set
foo := &memcache.Item{Key: "home", Value: []byte("fooval")}
err := mc.Add(foo) // work 0k here
if err != nil {
fmt.Println("Set failed once", err.Error())
}
err = mc.Add(foo) // work 0k here
if err != nil {
fmt.Println("Set failed secondly", err.Error())
}

// Get
it, err := mc.Get("home")
if err != nil {
fmt.Println("Get failed", err.Error()) // failed here
} else {
if string(it.Key) == "foo" {
fmt.Println("Add value is ", string(it.Value))
} else {
fmt.Println("Get failed")
}
}

Client function to check if server is available

I'd like to print a warning when no mc servers are available. In theory I could do something like insert or get a dummy key, and check if there's an error, and check if that error is a ConnectTimeoutError, but a client method encapsulating this would be nice.

Similar to #68

Timeouts when calling Set() in concurrent goroutines

I'm pretty new to Go and very new to Memcached, which is probably a bad combination for using gomemcache, but I couldn't find any info regarding my problem in the docs.

I start Memcached with Docker like this: docker run -it --rm -p 11211:11211 memcached

Then I run this code:

package main

import (
	"fmt"
	"strconv"
	"sync"

	"github.com/bradfitz/gomemcache/memcache"
)

func main() {
	mc := memcache.New("localhost:11211")

	// This one works
	mySet(mc, -1)
	// See:
	myGet(mc, -1)

	goroutineCount := 100
	waitGroup := sync.WaitGroup{}
	waitGroup.Add(goroutineCount)

	for i := 0; i < goroutineCount; i++ {
		go func(i int) {
			// These lead to errors
			mySet(mc, i)
			//waitGroup.Done()
		}(i)
	}
	waitGroup.Wait()
}

func mySet(mc *memcache.Client, i int) {
	item := memcache.Item{
		Key:   strconv.Itoa(i),
		Value: []byte("foo"),
	}
	err := mc.Set(&item)
	if err != nil {
		fmt.Println(err)
	}
}

func myGet(mc *memcache.Client, i int) {
	item, err := mc.Get(strconv.Itoa(i))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("value: " + string(item.Value))
}

waitGroup.Done() is commented out because that leads to more output (?). It's just for reproducing the behavior, so it doesn't matter that the program doesn't finish this way.

This is what I get:

value: foo
read tcp 127.0.0.1:39385->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39379->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39387->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39382->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39389->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39391->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39401->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39394->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39396->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39390->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39409->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39412->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39410->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39413->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39406->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39405->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39415->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39418->127.0.0.1:11211: i/o timeout
read tcp 127.0.0.1:39416->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39414->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39417->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39425->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39421->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39443->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39419->127.0.0.1:11211: i/o timeout
memcache: connect timeout to 127.0.0.1:11211
read tcp 127.0.0.1:39422->127.0.0.1:11211: i/o timeout

So the first Set() and Get() call work, which indicate that I properly created the client and that the server is running fine. But as soon as the calls take place concurrently in multiple goroutines, I get errors.

The server is still working fine. When I restart the program, the first Set() and Get() still work.

add a License

What is the license of this project? Could you please add it?

Connection timeout issues with memcached on AWS

Main Problem

My main issue is that I'm able to run a local instance of memcached on my machine and have it connect, write some key/value pairs, and read them back. However, when I try to pivot to doing the exact same process over a public facing AWS ubuntu instance with memcached installed and running, I get an almost immediate connection timeout error.

Theories?

I'm really not sure what the issue could be, I've been sure to check all AWS related network setting including VPCs, security groups, open ports, etc. I'm able to SSH into the machine and verify memcached is running but my connection still fails and I don't see a whole lot of logging information to go by.

I've provided my short code snippet below:

package main

import (
	"fmt"
	"math/rand"
	"strings"
	"time"

	"github.com/bradfitz/gomemcache/memcache"
)

func main() {

	const (
		// DefaultTimeout is the default socket read/write timeout.
		DefaultTimeout = 10000 * time.Millisecond

		// DefaultMaxIdleConns is the default maximum number of idle connections
		// kept for any single address.
		DefaultMaxIdleConns = 2
	)

	// fmt.Println(status)
	start := time.Now()

	// Connect to our memcache instance
	mc := memcache.New("172.31.33.237:11211")
	//mc := memcache.New("127.0.0.1:11211")
	mc.FlushAll()
	mc.Timeout = time.Second * 5 // Increase the client's timeout to 5 seconds

	//this will hold our keys so we can retrieve them later
	var keys []string

	// Setting multiple values
	for i := 0; i < 1; i++ {
		fmt.Println("formatting key")
		key := fmt.Sprintf("%s%d", "key", i)
		fmt.Println("generating value")
		value := strings.Repeat("#", rand.Intn(5+1))
		fmt.Println("pairing")
		mc.Set(&memcache.Item{Key: key, Value: []byte(value)})
		fmt.Println("adding to key list")
		keys = append(keys, key)
	}

	// Get multiple values
	fmt.Println("Getting errs")
	it, err := mc.GetMulti(keys)

	// // print errors if any
	// fmt.Println("Trying to print errs")
	// if err != nil {
	//     fmt.Println(err)
	//     return
	// }

	fmt.Println(err)

	// It's important to note here that `range` iterates in a *random* order
	for k, v := range it {
		fmt.Println("reading...")
		fmt.Printf("## %s => %s\n", k, v.Value)
	}
	elapsed := time.Since(start)
	fmt.Println("Total execution time: ", elapsed)

}

I've been fighting with this for a few days. I'm really hoping I can get some feedback on what could be causing this issue or how I can go about debugging it further.

Add health check support

At the moment when creating a memcached client using client := memcache.New(address)

New function does not return any error or something, which it should when doing ss.SetServers(server...). Provide an extra function which returns stats or does a ping pong of sorts which checks is server is up and running

Context Support?

Was wondering if there was any desire to support context.Context?

I'm working on adding tracing support to some commonly used libraries and Context support is usually a pre-requisite. I thought of a couple ways:

  1. The appengine API has:

    func Add(c context.Context, item *Item) error
    func AddMulti(c context.Context, item []*Item) error
    func CompareAndSwap(c context.Context, item *Item) error
    ...

    So maybe there could be a new type of Client with these method signatures instead of the current ones? Something like NewContextualClient(server ... string) *ContextualClient?

  2. The github.com/go-redis/redis library has:

    func (c *Client) WithContext(ctx context.Context) *Client

    So you could chain calls like: client.WithContext(ctx).Add(item)

I briefly looked into the second option and I think it could work, but there are a few places where it's not super-clean in order to preserve the existing API (the field names on the Client should probably be in some sort of Pool, and keeping zero-value-struct support is tricky)

If context.Context isn't a great fit for this library, it's probably not essential for tracing because memcache is a terminal span in a trace anyway. I could add the WithContext method to my wrapper and any deadline on the context would just be ignored.

Cant use for NDB Memcached API due to not allowing tab in key

Using NDB API with tables with a compound key need to allow a tab (or \t) in key
Also need to be able to specify memcached prefix as I cant find a way to specify this
e.g. for python
if messageok:
try:
mckey = "mkt:{0}\t{1}".format(data['payload']['marketId'],data['payload']['eventId'])
mcval = "{0}\t{1}\t{2}\t{3}\t{4}\t{5}".format(data['payload']['name'],data['payload']['displayed'],data['payload']['suspended'],data['msgId'],(int(data['timestamp'])/1000),time.time())
if mc.set(mckey.encode(), mcval.encode()):

Unable to connect to remote memcached server

I am facing connect timeout error when trying to connect to my remote memcached instance but there seems to be no issue while connecting to a local instance. I'm not sure what exactly is happening but I am using the exact code as in the Readme.

whitespace key is not allowed when reading an existing key from memcached

is there a reason why legalKey function returns False if the binary key has whitespace character ?

having a key with whitespace is not an issue when using `python-binary-memcached in spite of https://github.com/memcached/memcached/blob/95e6469bd2ceef92bcaaf140e2724fc73d556185/doc/protocol.txt#L49.

for instance I am able to set and retrieve a binary key ((' \u039b\ufffd\ufffd#\ufffdm')) or (' ��#�m') from python but unable to read this key using gomemcache due to this check :

if key[i] <= ' ' || key[i] == 0x7f {

python code:

from bmemcached import Client
client.set(' \u039b\ufffd\ufffd#\ufffdm', "sample value")
print(client.get(' \u039b\ufffd\ufffd#\ufffdm'))

Go

mc.Get(" \u039b\ufffd\ufffd#\ufffdm")

Reference error on doing a 'go get'

I just did a get fro this lib go get github.com/bradfitz/gomemcache/memcache
But im getting reference error ,, can you help me with this.
Please check this the screencast attached below.

screen shot 2017-04-24 at 12 12 33 pm

Get sends gets to server and there's no Gets

When I call mc.Get("foo"), I mean get foo command, in fact the command sent to server is gets foo like this
image

I mean some servers partially implemented memcache protocol, eg, a message queue service only implemented get and set command, and when gets is called the server would take it as an illegal command.

I would assume that this guy was in the same situation with me #110.

The reason why I make the PR #111 is that I think mc.Get should send get foo instead of gets foo and If one need CAS feature he should call mc.Gets explicitlly.

Anyway thanks for your great work.

ASCII Support

Hello,

Does this library support ASCII protocol ?

Add SASL and binary protocol support

I'm using gomemcache with Memcachier and having issues. Memcachier requires authentication, which as far as I understand, means that I also have to use the memcache binary protocol. Any help?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.