Problem
PythLazerClient.create() blocks indefinitely when WebSocket endpoints are unreachable. The WebSocketPool.create() method contains this loop:
while(!pool.isAnyConnectionEstablished()) {
await new Promise((resolve) => setTimeout(resolve, 100));
}
This causes issues for fault-tolerant services (e.g., relayers) that need to:
- Handle Pyth Pro being temporarily unavailable
- Implement graceful degradation
- Avoid hanging promises that block service startup
Proposed Solution
Add optional AbortSignal and connectionTimeoutMs parameters to WebSocketPoolConfig:
export type WebSocketPoolConfig = {
// ... existing fields ...
/**
* AbortSignal to cancel connection establishment.
* If aborted before connection is established, create() will throw.
*/
signal?: AbortSignal;
/**
* Timeout in ms for initial connection establishment.
* If not connected within this time, create() will throw.
* @defaultValue Infinity (no timeout)
*/
connectionTimeoutMs?: number;
};
Implementation
In WebSocketPool.create():
static async create(config: WebSocketPoolConfig, token: string, logger?: Logger): Promise<WebSocketPool> {
// ... existing setup code ...
const startTime = Date.now();
const timeoutMs = config.connectionTimeoutMs ?? Infinity;
while(!pool.isAnyConnectionEstablished()) {
// Check abort signal
if (config.signal?.aborted) {
pool.shutdown();
throw new DOMException('Connection aborted', 'AbortError');
}
// Check timeout
if (Date.now() - startTime > timeoutMs) {
pool.shutdown();
throw new Error(`Connection timeout: failed to establish connection within ${timeoutMs}ms`);
}
await new Promise((resolve) => setTimeout(resolve, 100));
}
// ... rest of method ...
}
Usage Examples
With AbortSignal
const controller = new AbortController();
// Abort after 5 seconds
setTimeout(() => controller.abort(), 5000);
try {
const client = await PythLazerClient.create({
token: process.env.ACCESS_TOKEN!,
webSocketPoolConfig: {
urls: [...],
signal: controller.signal
}
});
} catch (err) {
if (err.name === 'AbortError') {
console.log('Connection was aborted');
// Handle gracefully - e.g., continue without real-time prices
}
}
With timeout (simpler API)
try {
const client = await PythLazerClient.create({
token: process.env.ACCESS_TOKEN!,
webSocketPoolConfig: {
urls: [...],
connectionTimeoutMs: 5000
}
});
} catch (err) {
console.log('Connection timed out, falling back to REST API');
}
Current workaround
// Users currently have to do this manually:
const timeout = (ms) => new Promise((_, reject) =>
setTimeout(() => reject(new Error('timeout')), ms)
);
const client = await Promise.race([
PythLazerClient.create({ token, webSocketPoolConfig: { urls } }),
timeout(5000)
]);
// Problem: WebSocket connections keep running in background after timeout
Use Case
A relayer service that needs high fault tolerance reported this issue. When Pyth Pro endpoints are temporarily unavailable, their service hangs on startup instead of gracefully degrading to alternative data sources.
This is a standard pattern for async operations in modern JavaScript/TypeScript — fetch(), ReadableStream, and many other APIs support AbortSignal for cancellation.
Additional Context
- SDK version: 6.0.0
- The
AbortSignal pattern aligns with web platform standards
- Both options (
signal and connectionTimeoutMs) provide flexibility for different use cases
Problem
PythLazerClient.create()blocks indefinitely when WebSocket endpoints are unreachable. TheWebSocketPool.create()method contains this loop:This causes issues for fault-tolerant services (e.g., relayers) that need to:
Proposed Solution
Add optional
AbortSignalandconnectionTimeoutMsparameters toWebSocketPoolConfig:Implementation
In
WebSocketPool.create():Usage Examples
With AbortSignal
With timeout (simpler API)
Current workaround
Use Case
A relayer service that needs high fault tolerance reported this issue. When Pyth Pro endpoints are temporarily unavailable, their service hangs on startup instead of gracefully degrading to alternative data sources.
This is a standard pattern for async operations in modern JavaScript/TypeScript —
fetch(),ReadableStream, and many other APIs supportAbortSignalfor cancellation.Additional Context
AbortSignalpattern aligns with web platform standardssignalandconnectionTimeoutMs) provide flexibility for different use cases