Documentation
¶
Overview ¶
Package types provides core QoS types that can be imported without cycles.
The DataExtractor interface defines how endpoint quality data is extracted from responses. This enables both hardcoded extractors (EVM, Cosmos, Solana) and future dynamic/generic extractors (YAML-configured rules).
This package is separate from qos to avoid import cycles with gateway.
Package types provides the NoOpDataExtractor for passthrough services.
NoOpDataExtractor is used for services that don't need response parsing. All extraction methods return zero values or indicate "not available". This is the default fallback for unknown services.
Package types provides the ExtractorRegistry for mapping service IDs to DataExtractors.
The registry enables service-agnostic request processing on the hot path, with service-specific parsing deferred to async workers.
Usage ¶
registry := types.NewExtractorRegistry()
registry.Register("eth", evm.NewEVMDataExtractor())
registry.Register("osmosis", cosmos.NewCosmosDataExtractor())
registry.Register("text-to-text", types.NewNoOpDataExtractor()) // passthrough
// In async worker:
extractor := registry.Get(serviceID)
data := types.NewExtractedData(endpoint, statusCode, response, latency)
data.ExtractAll(extractor)
Index ¶
- Variables
- type DataExtractor
- type ExtractedData
- type ExtractionConfig
- type ExtractorRegistry
- func (r *ExtractorRegistry) Count() int
- func (r *ExtractorRegistry) Get(serviceID protocol.ServiceID) DataExtractor
- func (r *ExtractorRegistry) Has(serviceID protocol.ServiceID) bool
- func (r *ExtractorRegistry) List() []protocol.ServiceID
- func (r *ExtractorRegistry) Register(serviceID protocol.ServiceID, extractor DataExtractor)
- func (r *ExtractorRegistry) RegisterMultiple(extractors map[protocol.ServiceID]DataExtractor)
- func (r *ExtractorRegistry) SetFallback(extractor DataExtractor)
- type NoOpDataExtractor
- func (e *NoOpDataExtractor) ExtractBlockHeight(_ []byte) (int64, error)
- func (e *NoOpDataExtractor) ExtractChainID(_ []byte) (string, error)
- func (e *NoOpDataExtractor) IsArchival(_ []byte) (bool, error)
- func (e *NoOpDataExtractor) IsSyncing(_ []byte) (bool, error)
- func (e *NoOpDataExtractor) IsValidResponse(response []byte) (bool, error)
Constants ¶
This section is empty.
Variables ¶
var ErrNoOpExtractor = errors.New("noop extractor: extraction not supported for this service")
ErrNoOpExtractor is returned when extraction is not supported.
Functions ¶
This section is empty.
Types ¶
type DataExtractor ¶
type DataExtractor interface {
// ExtractBlockHeight extracts the latest block height from a response.
// This is used to determine sync status - endpoints behind in block height
// are potentially stale or syncing.
//
// Returns:
// - Block height as int64
// - Error if extraction fails or response doesn't contain block height
ExtractBlockHeight(response []byte) (int64, error)
// ExtractChainID extracts the chain identifier from a response.
// This is used to validate endpoints are on the correct chain.
//
// Returns:
// - Chain ID as string (hex for EVM, chain-name for Cosmos)
// - Error if extraction fails or response doesn't contain chain ID
ExtractChainID(response []byte) (string, error)
// IsSyncing determines if the endpoint is currently syncing.
// Syncing endpoints may return stale data and should be deprioritized.
//
// Returns:
// - true if endpoint is syncing
// - false if endpoint is synced
// - Error if sync status cannot be determined
IsSyncing(response []byte) (bool, error)
// IsArchival determines if the endpoint supports archival queries.
// Archival endpoints can serve historical data queries.
//
// Parameters:
// - response: Response from an archival-specific query (e.g., eth_getBalance at historical block)
//
// Returns:
// - true if endpoint is archival (query succeeded)
// - false if endpoint is not archival (query failed)
// - Error if archival status cannot be determined
IsArchival(response []byte) (bool, error)
// IsValidResponse checks if the response is valid for the protocol.
// This performs basic validation without extracting specific data.
//
// Returns:
// - true if response is valid (correct format, no errors)
// - false if response is invalid (malformed, contains error)
// - Error if validation fails unexpectedly
IsValidResponse(response []byte) (bool, error)
}
DataExtractor defines how endpoint quality data is extracted from responses. All QoS services (EVM, Cosmos, Solana, generic) implement this interface.
This interface enables:
- Hardcoded extractors: Know exactly how to parse their protocol's responses
- Dynamic extractors: Use configurable rules for unknown protocols
type ExtractedData ¶
type ExtractedData struct {
// BlockHeight is the latest block number (0 if not extracted).
BlockHeight int64
// ChainID is the chain identifier (empty if not extracted).
ChainID string
// IsSyncing indicates if the endpoint is syncing.
IsSyncing bool
// IsArchival indicates if the endpoint supports archival queries.
IsArchival bool
// IsValidResponse indicates if the response was valid.
IsValidResponse bool
// ResponseTime is how long the request took.
ResponseTime time.Duration
// EndpointAddr identifies the endpoint that responded.
EndpointAddr protocol.EndpointAddr
// HTTPStatusCode is the HTTP status code from the response.
HTTPStatusCode int
// RawResponse is the original response bytes (for re-parsing if needed).
RawResponse []byte
// ExtractionErrors holds any errors that occurred during extraction.
// Map from field name (e.g., "block_height") to error message.
ExtractionErrors map[string]string
}
ExtractedData holds all data extracted from a response. This is the result of running all extractors on a response.
func NewExtractedData ¶
func NewExtractedData(endpointAddr protocol.EndpointAddr, statusCode int, response []byte, latency time.Duration) *ExtractedData
NewExtractedData creates a new ExtractedData with defaults.
func (*ExtractedData) ExtractAll ¶
func (ed *ExtractedData) ExtractAll(extractor DataExtractor)
ExtractAll runs all extractors and populates the ExtractedData. Errors are captured in ExtractionErrors rather than returned directly, allowing partial extraction even when some fields fail.
func (*ExtractedData) ExtractWithConfig ¶
func (ed *ExtractedData) ExtractWithConfig(extractor DataExtractor, config ExtractionConfig)
ExtractWithConfig runs extractions based on the provided config.
func (*ExtractedData) HasErrors ¶
func (ed *ExtractedData) HasErrors() bool
HasErrors returns true if any extraction errors occurred.
type ExtractionConfig ¶
type ExtractionConfig struct {
// ExtractBlockHeight enables block height extraction.
ExtractBlockHeight bool
// ExtractChainID enables chain ID extraction.
ExtractChainID bool
// CheckSyncStatus enables sync status checking.
CheckSyncStatus bool
// CheckArchival enables archival status checking.
CheckArchival bool
// ValidateResponse enables response validation.
ValidateResponse bool
}
ExtractionConfig configures which extractions to run. Used to skip extractions that aren't relevant for a given check.
func DefaultExtractionConfig ¶
func DefaultExtractionConfig() ExtractionConfig
DefaultExtractionConfig returns a config with all extractions enabled.
type ExtractorRegistry ¶
type ExtractorRegistry struct {
// contains filtered or unexported fields
}
ExtractorRegistry maps service IDs to their DataExtractor implementations. This enables the hot path to be completely service-agnostic, with service-specific parsing deferred to async workers.
Thread-safe for concurrent reads/writes.
func NewExtractorRegistry ¶
func NewExtractorRegistry() *ExtractorRegistry
NewExtractorRegistry creates a new registry with a NoOp fallback.
func (*ExtractorRegistry) Count ¶
func (r *ExtractorRegistry) Count() int
Count returns the number of registered extractors.
func (*ExtractorRegistry) Get ¶
func (r *ExtractorRegistry) Get(serviceID protocol.ServiceID) DataExtractor
Get returns the DataExtractor for a service ID. Returns the fallback (NoOp) extractor if the service is not registered.
func (*ExtractorRegistry) Has ¶
func (r *ExtractorRegistry) Has(serviceID protocol.ServiceID) bool
Has returns true if a service ID has a registered extractor.
func (*ExtractorRegistry) List ¶
func (r *ExtractorRegistry) List() []protocol.ServiceID
List returns all registered service IDs.
func (*ExtractorRegistry) Register ¶
func (r *ExtractorRegistry) Register(serviceID protocol.ServiceID, extractor DataExtractor)
Register adds a DataExtractor for a service ID. Overwrites any existing extractor for the same service.
func (*ExtractorRegistry) RegisterMultiple ¶
func (r *ExtractorRegistry) RegisterMultiple(extractors map[protocol.ServiceID]DataExtractor)
RegisterMultiple adds multiple DataExtractors at once. Useful for bulk registration during initialization.
func (*ExtractorRegistry) SetFallback ¶
func (r *ExtractorRegistry) SetFallback(extractor DataExtractor)
SetFallback sets the fallback extractor for unknown services. By default, this is a NoOpDataExtractor.
type NoOpDataExtractor ¶
type NoOpDataExtractor struct{}
NoOpDataExtractor is a passthrough extractor that doesn't parse responses. Used for:
- Services explicitly configured as "passthrough"
- Unknown services (fallback)
- Services where response parsing isn't needed or possible
func NewNoOpDataExtractor ¶
func NewNoOpDataExtractor() *NoOpDataExtractor
NewNoOpDataExtractor creates a new NoOp data extractor.
func (*NoOpDataExtractor) ExtractBlockHeight ¶
func (e *NoOpDataExtractor) ExtractBlockHeight(_ []byte) (int64, error)
ExtractBlockHeight returns an error indicating extraction is not supported.
func (*NoOpDataExtractor) ExtractChainID ¶
func (e *NoOpDataExtractor) ExtractChainID(_ []byte) (string, error)
ExtractChainID returns an error indicating extraction is not supported.
func (*NoOpDataExtractor) IsArchival ¶
func (e *NoOpDataExtractor) IsArchival(_ []byte) (bool, error)
IsArchival returns an error indicating extraction is not supported.
func (*NoOpDataExtractor) IsSyncing ¶
func (e *NoOpDataExtractor) IsSyncing(_ []byte) (bool, error)
IsSyncing returns an error indicating extraction is not supported.
func (*NoOpDataExtractor) IsValidResponse ¶
func (e *NoOpDataExtractor) IsValidResponse(response []byte) (bool, error)
IsValidResponse returns true for any non-empty response. This is the only method that provides a meaningful result for NoOp. A response is considered "valid" if it has content.