Skip to content

Commit

Permalink
Adds measurer middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
ksysoev committed May 25, 2024
1 parent 7ee0241 commit 9328735
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
26 changes: 26 additions & 0 deletions middleware/request/measure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package request

import (
"time"

"github.com/ksysoev/wasabi"
"github.com/ksysoev/wasabi/dispatch"
)

// NewMeasurer returns a middleware function that measures the duration of each request and saves the metric using the provided `saveMetric` function.
// The `saveMetric` function takes three parameters: the request, the error (if any), and the duration of the request.
// The middleware function wraps the provided `next` request handler and measures the duration of the request by calculating the time elapsed between the start and end of the request.
// After the request is handled, the metric is saved using the `saveMetric` function.
// The middleware function returns the wrapped request handler.
func NewMeasurer(saveMetric func(req wasabi.Request, err error, duration time.Duration)) func(next wasabi.RequestHandler) wasabi.RequestHandler {
return func(next wasabi.RequestHandler) wasabi.RequestHandler {
return dispatch.RequestHandlerFunc(func(conn wasabi.Connection, req wasabi.Request) error {
start := time.Now()
err := next.Handle(conn, req)
duration := time.Since(start)

saveMetric(req, err, duration)
return err
})
}
}
57 changes: 57 additions & 0 deletions middleware/request/measure_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package request

import (
"testing"
"time"

"github.com/ksysoev/wasabi"
"github.com/ksysoev/wasabi/dispatch"
"github.com/ksysoev/wasabi/mocks"
)

func TestNewMeasurer(t *testing.T) {
// Define a mock saveMetric function
var savedMetric wasabi.Request
var savedError error
var savedDuration time.Duration
saveMetric := func(req wasabi.Request, err error, duration time.Duration) {
savedMetric = req
savedError = err
savedDuration = duration
}

// Define a mock request handler
mockHandler := dispatch.RequestHandlerFunc(func(conn wasabi.Connection, req wasabi.Request) error {
// Simulate some processing time
time.Sleep(100 * time.Microsecond)
return nil
})

// Create the measurer middleware
measurer := NewMeasurer(saveMetric)

// Create a mock connection and request
mockConn := mocks.NewMockConnection(t)
mockReq := mocks.NewMockRequest(t)

// Call the measurer middleware with the mock handler
err := measurer(mockHandler).Handle(mockConn, mockReq)

// Check if the metric was saved correctly
if savedMetric != mockReq {
t.Errorf("Expected saved metric to be %v, but got %v", mockReq, savedMetric)
}

if savedError != nil {
t.Errorf("Expected saved error to be nil, but got %v", savedError)
}

if savedDuration < 100*time.Microsecond {
t.Errorf("Expected saved duration to be greater than 100ms, but got %v", savedDuration)
}

// Check if the error is propagated correctly
if err != nil {
t.Errorf("Expected error to be nil, but got %v", err)
}
}

0 comments on commit 9328735

Please sign in to comment.