ubgo is in early alpha: libraries and APIs may still change.

Skip to content
ubgo Alpha

cache-memcached

Memcached backend for cache, covering the parts of the interface Memcached supports.

go get github.com/ubgo/cache-memcached
Language
Go
Go version
1.24
Core deps
2 direct
Latest tag
v0.1.0
License
Apache-2.0
Go modules
1

Highlights from the README

  • Interop, not greenfield. If you already run Memcached, this lets that fleet back any code written against cache.Cache without standing up Redis or Postgres.
  • Honest about limits. TTL introspection, prefix delete, and key iteration are impossible over the Memcached protocol. This adapter returns an explicit cache.ErrUnsupported (or an iterator whose first Next() is false with Err() == ErrUnsupported) instead of faking them or silently returning empty.
  • Correct counter semantics. Memcached counters are unsigned and decrement floors at 0; this adapter implements the missing-key initialisation dance atomically so Incr/Decr behave per the contract (missing key = 0) within Memcached’s rules.
  • Server-free tests. A complete in-process fake exercises every supported op; MEMCACHED_ADDR enables optional real-server checks.

Code from the README

package main

import (
	"context"
	"errors"
	"log"
	"time"

	"github.com/bradfitz/gomemcache/memcache"
	"github.com/ubgo/cache"
	memcachedcache "github.com/ubgo/cache-memcached"
)

func main() {
	mc := memcache.New("localhost:11211")
	c := memcachedcache.New(mc)
	defer c.Close()

	ctx := context.Background()
	_ = c.Set(ctx, "k", []byte("v"), time.Minute)

	b, err := c.Get(ctx, "k")
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("%s", b)

	// Unsupported ops are explicit, never silent:
	if _, err := c.TTL(ctx, "k"); errors.Is(err, cache.ErrUnsupported) {
		log.Println("Memcached cannot report remaining TTL")
	}
}

From the cache-memcached README.

At a glance (from the README)

cache.Cache opMemcached mappingStatus
Get / GetMulti / Hasgetworks
Set / SetMultisetworks
SetNXadd (ErrNotStored ⇒ key exists ⇒ false)works
Expire / Touchtouchworks
Incr / Decrincr / decr + missing-key add initworks (Decr floors at 0)
Deldelete (miss tolerated)works
Flushflush_allworks
Ping / Closeversion / local flagworks
TTL(key)— no command existsErrUnsupported
DeleteByPrefix— no server-side scanErrUnsupported
Iterate— no key enumerationErrUnsupported (iterator: Next()=false, Err()=ErrUnsupported)