Files
box-box/internal/api/client.go

85 lines
2.5 KiB
Go
Raw Normal View History

2026-03-03 00:20:09 -05:00
package api
import (
"net/http"
2026-03-27 19:27:38 -04:00
"sync/atomic"
2026-03-03 00:20:09 -05:00
"time"
)
type OpenF1Client struct {
url string
2026-03-27 00:30:53 -04:00
apiKey string
2026-03-03 00:20:09 -05:00
httpClient *http.Client
2026-03-27 00:30:53 -04:00
cache *Cache
2026-03-27 19:27:38 -04:00
// staleFlag is set to 1 atomically whenever a request falls back to stale
// cached data (e.g. because the API is locked during a live session).
// The UI reads this via LastResponseWasStale() to decide whether to show
// a disclaimer banner. The flag is sticky until ClearStaleFlag() is called.
staleFlag int32
2026-03-03 00:20:09 -05:00
}
func NewOpenF1Client(url string, timeout time.Duration) *OpenF1Client {
return &OpenF1Client{
url: url,
httpClient: &http.Client{Timeout: timeout},
2026-03-27 00:30:53 -04:00
cache: NewCache(),
}
}
// NewOpenF1ClientWithKey creates a client that authenticates with a Bearer token.
// This allows access during live sessions (paid tier).
func NewOpenF1ClientWithKey(url string, timeout time.Duration, apiKey string) *OpenF1Client {
return &OpenF1Client{
url: url,
apiKey: apiKey,
httpClient: &http.Client{Timeout: timeout},
cache: NewCache(),
2026-03-03 00:20:09 -05:00
}
}
2026-03-03 02:29:34 -05:00
2026-05-25 00:45:46 -04:00
// BaseURL returns the configured OpenF1 API root URL.
func (c *OpenF1Client) BaseURL() string {
return c.url
}
2026-03-27 19:27:38 -04:00
// Cache returns the underlying Cache so callers can access track outline
// storage and other persistent data directly.
func (c *OpenF1Client) Cache() *Cache {
return c.cache
}
// LastResponseWasStale reports whether the most recent API request (or any
// request since the last ClearStaleFlag call) fell back to expired cached
// data because the API was unavailable. The UI uses this to show a
// disclaimer banner informing the user that data may be stale.
func (c *OpenF1Client) LastResponseWasStale() bool {
return atomic.LoadInt32(&c.staleFlag) == 1
}
// ClearStaleFlag resets the stale indicator. Call this when navigating away
// from a tab or after the disclaimer has been acknowledged.
func (c *OpenF1Client) ClearStaleFlag() {
atomic.StoreInt32(&c.staleFlag, 0)
}
// setStale marks the client as having served stale data.
func (c *OpenF1Client) setStale() {
atomic.StoreInt32(&c.staleFlag, 1)
}
2026-03-03 02:29:34 -05:00
// CacheStats returns the cache hit/miss statistics.
func (c *OpenF1Client) CacheStats() CacheStats {
return c.cache.Stats()
}
// CacheSize returns the number of cached entries and total size in bytes.
func (c *OpenF1Client) CacheSize() (int, int64) {
return c.cache.Size()
}
2026-03-27 00:30:53 -04:00
// Close releases resources held by the client (closes the cache database).
func (c *OpenF1Client) Close() error {
return c.cache.Close()
}