Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions internal/cache/rpc_cache.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package cache

import (
"context"
"encoding/json"
"fmt"
"log"
"reflect"
"time"

"github.com/go-redis/cache/v9"
Expand Down Expand Up @@ -77,3 +80,57 @@

return result, cached, nil
}

func (c *RPCCache) HandleRequestParallel(
chainName string,
ttl time.Duration,
reqBody jsonrpc.SingleRequestBody,
originFunc func() (*jsonrpc.SingleResponseBody, error),
) (json.RawMessage, bool, error) {
var (
cached = true
result json.RawMessage
)

ctx := context.Background()

key := c.CreateRequestKey(chainName, reqBody)
err := c.Get(ctx, key, &result) // Attempt to fetch from cache
if err == nil {

Check failure on line 99 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

only one cuddle assignment allowed before if statement (wsl)
return result, cached, nil // Return if cache hit
}

// Cache miss, proceed with the request to origin
cached = false
respBody, err := originFunc()
if err != nil {

Check failure on line 106 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

only one cuddle assignment allowed before if statement (wsl)
return nil, cached, err
}

result = respBody.Result

// Perform cache set asynchronously
go func() {
existingResult := json.RawMessage{}
if err := c.Get(ctx, key, &existingResult); err == nil {

Check failure on line 115 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

shadow: declaration of "err" shadows declaration at line 98 (govet)
if !jsonEqual(existingResult, result) {
log.Printf("Cache inconsistency detected for key %s", key)
}
return // Do not overwrite existing key

Check failure on line 119 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

return statements should not be cuddled if block has more than two lines (wsl)
}
err = c.Set(&cache.Item{Key: c.CreateRequestKey(chainName, reqBody), Value: &result, TTL: ttl})

Check failure on line 121 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

assignments should only be cuddled with other assignments (wsl)
if err != nil {

Check failure on line 122 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

only one cuddle assignment allowed before if statement (wsl)
log.Println("error setting cache", err)
}
}()

return result, cached, nil
}

// jsonEqual checks if two JSON values are equal
func jsonEqual(a, b json.RawMessage) bool {
var j1, j2 interface{}
_ = json.Unmarshal(a, &j1)
_ = json.Unmarshal(b, &j2)
return reflect.DeepEqual(j1, j2)

Check failure on line 135 in internal/cache/rpc_cache.go

View workflow job for this annotation

GitHub Actions / Code linting with golangci-lint

return statements should not be cuddled if block has more than two lines (wsl)
}
2 changes: 1 addition & 1 deletion internal/route/request_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func (r *RequestExecutor) retrieveOrCacheRequest(httpReq *http.Request, requestB
return singleRespBody, nil
}

val, cached, err := r.cache.HandleRequest(r.chainName, r.cacheConfig.TTL, requestBody, originFunc)
val, cached, err := r.cache.HandleRequestParallel(r.chainName, r.cacheConfig.TTL, requestBody, originFunc)

if err != nil {
switch err := err.(type) {
Expand Down
Loading