-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add custom middleware example with timing middleware
- Loading branch information
1 parent
6bf8d00
commit 2060721
Showing
2 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |