synapsecns/sanguine

View on GitHub
services/rfq/relayer/inventory/inflight.go

Summary

Maintainability
A
0 mins
Test Coverage
package inventory

import (
    "context"
    "fmt"
    "github.com/synapsecns/sanguine/services/rfq/relayer/reldb"
    "sync"
    "time"
)

// inFlightManager stores in-flight quotes and allows retrieval via the db.
// it is thread-safe.
type inFlightManager struct {
    ttl   time.Duration
    db    reldb.Service
    mux   sync.RWMutex
    entry *inFlightQuoteCacheEntry
}

// inFlightQuoteCacheEntry represents an entry in the in-flight quote cache.
type inFlightQuoteCacheEntry struct {
    createdAt time.Time
    quotes    []reldb.QuoteRequest
}

// QuoterOption defines a type for functional options.
type QuoterOption func(*inFlightManager)

// WithTTL sets the TTL for the inFlightManager.
func WithTTL(ttl time.Duration) QuoterOption {
    return func(q *inFlightManager) {
        q.ttl = ttl
    }
}

const defaultTTL = 2 * time.Second

// newInflightManager creates a new inFlightManager with the given options.
func newInflightManager(db reldb.Service, options ...QuoterOption) *inFlightManager {
    // Default TTL to 250ms
    quoter := &inFlightManager{
        ttl: defaultTTL,
        db:  db,
    }

    // Apply options
    for _, opt := range options {
        opt(quoter)
    }

    return quoter
}

func (q *inFlightManager) GetInFlightQuotes(ctx context.Context, skipCache bool) (quotes []reldb.QuoteRequest, err error) {
    if skipCache || q.shouldRefresh() {
        inFlightQuotes, err := q.db.GetQuoteResultsByStatus(ctx, reldb.CommittedPending, reldb.CommittedConfirmed, reldb.RelayStarted)
        if err != nil {
            return nil, fmt.Errorf("could not get in flight quotes: %w", err)
        }
        q.mux.Lock()
        defer q.mux.Unlock()
        q.entry = &inFlightQuoteCacheEntry{
            createdAt: time.Now(),
            quotes:    inFlightQuotes,
        }

        return inFlightQuotes, nil
    }

    q.mux.RLock()
    defer q.mux.RUnlock()

    return q.entry.quotes, nil
}

func (q *inFlightManager) shouldRefresh() bool {
    q.mux.RLock()
    defer q.mux.RUnlock()

    return q.entry == nil || time.Since(q.entry.createdAt) > q.ttl
}