Member-only story
‘How to build pluggable libraries in Go’
4 min readOct 23, 2024
What is go buildmode=plugin?
Because we want to implement a pluggable library called cache Cache, Therefore, we need to implement this interface. We can implement this interface anywhere, even in a separate repository. In this example, I created two implementations: one using memory caching and the other using Redis, both in separate repositories.
In-Memory Cache Plugin
package mainimport (
"context"
"log/slog"
"sync"
"time" "github.com/josestg/yt-go-plugin/cache"
)// Value represents a cache entry.
type Value struct {
Data string
ExpAt time.Time
}// Memcache is a simple in-memory cache.
type Memcache struct {
mu sync.RWMutex
log *slog.Logger
store map[string]Value
}// Factory is the symbol the plugin loader will try to load. It must implement the cache.Factory signature.
var Factory cache.Factory = New// New creates a new Memcache instance.
func New(log *slog.Logger) (cache.Cache, error) {
log.Info("[plugin/memcache] loaded")
c := &Memcache{
mu: sync.RWMutex{},
log: log,
store: make(map[string]Value),
}
return c, nil
}func (m *Memcache) Set(ctx context.Context, key, val string, exp time.Duration) error {
m.log.InfoContext(ctx, "[plugin/memcache] set", "key", key, "val", val, "exp", exp)
m.mu.Lock()
m.log.DebugContext(ctx, "[plugin/memcache] lock acquired")
defer func() {
m.mu.Unlock()
m.log.DebugContext(ctx, "[plugin/memcache] lock released")
}() m.store[key] = Value{
Data: val,
ExpAt: time.Now().Add(exp),
} return nil
}func (m…