Skip to content

Commit

Permalink
chore: add custom middleware example with timing middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
pgautier404 committed Aug 13, 2024
1 parent 6bf8d00 commit 2060721
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 0 deletions.
108 changes: 108 additions & 0 deletions examples/middleware-example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package main

import (
"context"
"fmt"
"log"
"sync"
"time"

"github.com/momentohq/client-sdk-go/auth"
"github.com/momentohq/client-sdk-go/config"
"github.com/momentohq/client-sdk-go/config/logger/momento_default_logger"
"github.com/momentohq/client-sdk-go/config/middleware"
"github.com/momentohq/client-sdk-go/momento"
"github.com/momentohq/client-sdk-go/responses"

"github.com/google/uuid"
)

const (
cacheName = "my-test-cache"
itemDefaultTTLSeconds = 60
)

func doWork(ctx context.Context, client momento.CacheClient, index int) {
// Sets key with default TTL and gets value with that key
key := uuid.NewString()
value := fmt.Sprintf("%d", index)
log.Printf("#%d setting key: %s, value: %s\n", index, key, value)
_, err := client.Set(ctx, &momento.SetRequest{
CacheName: cacheName,
Key: momento.String(key),
Value: momento.String(value),
})
if err != nil {
panic(err)
}

log.Printf("Getting key: %s\n", key)
resp, err := client.Get(ctx, &momento.GetRequest{
CacheName: cacheName,
Key: momento.String(key),
})
if err != nil {
panic(err)
}

switch r := resp.(type) {
case *responses.GetHit:
log.Printf("Lookup resulted in cache HIT. value=%s\n", r.ValueString())
case *responses.GetMiss:
log.Printf("Look up did not find a value key=%s", key)
}
}

func main() {
ctx := context.Background()
var credentialProvider, err = auth.NewEnvMomentoTokenProvider("MOMENTO_API_KEY")
if err != nil {
panic(err)
}

loggerFactory := momento_default_logger.NewDefaultMomentoLoggerFactory(momento_default_logger.INFO)
myConfig := config.LaptopLatest().WithMiddleware(
[]middleware.Middleware{
NewTimingMiddleware(loggerFactory.GetLogger("timing-middleware")),
},
)

// Initializes Momento
client, err := momento.NewCacheClientWithEagerConnectTimeout(
myConfig,
credentialProvider,
itemDefaultTTLSeconds*time.Second,
30*time.Second,
)
if err != nil {
panic(err)
}

// Create Cache
_, err = client.CreateCache(ctx, &momento.CreateCacheRequest{
CacheName: cacheName,
})
if err != nil {
panic(err)
}

var wg sync.WaitGroup

for i := 0; i < 100; i++ {
wg.Add(1)
// avoid reuse of the same i value in each closure
i := i
go func() {
defer wg.Done()
doWork(ctx, client, i)
}()
}

wg.Wait()

// Permanently delete the cache
if _, err = client.DeleteCache(ctx, &momento.DeleteCacheRequest{CacheName: cacheName}); err != nil {
panic(err)
}
log.Printf("Cache named %s is deleted\n", cacheName)
}
60 changes: 60 additions & 0 deletions examples/middleware-example/timing_middleware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"context"
"fmt"
"strconv"
"strings"
"time"

"github.com/loov/hrtime"
"github.com/momentohq/client-sdk-go/config/logger"
)

type timingMiddleware struct {
Log logger.MomentoLogger
timerChan chan string
}

func timer(timerChan chan string, log logger.MomentoLogger) {
startTimes := make(map[uint64]int64)
for {
select {
case timingMsg := <-timerChan:
res := strings.Split(timingMsg, ":")
operation := res[0]
requestId, _ := strconv.ParseUint(res[1], 10, 64)
timePoint, _ := strconv.ParseInt(res[2], 10, 64)
if operation == "start" {
startTimes[requestId] = timePoint
continue
}
// we got an "end" message
elapsed := timePoint - startTimes[requestId]
log.Info(
fmt.Sprintf(
"Request %d took %dms", requestId, time.Duration(elapsed).Milliseconds(),
),
)
}
}
}

func (mw *timingMiddleware) OnRequest(requestId uint64, theRequest interface{}, metadata context.Context) {
mw.timerChan <- fmt.Sprintf("start:%d:%d", requestId, hrtime.Now())
}

func (mw *timingMiddleware) OnResponse(requestId uint64, theResponse map[string]string) {
mw.timerChan <- fmt.Sprintf("end:%d:%d", requestId, hrtime.Now())
}

func NewTimingMiddleware(log logger.MomentoLogger) *timingMiddleware {
mw := &timingMiddleware{
Log: log,
timerChan: make(chan string),
}
go func() {
timer(mw.timerChan, mw.Log)
}()
return mw
}

0 comments on commit 2060721

Please sign in to comment.