Add DNS retry logic to Drift initialization
- Handles transient network failures (EAI_AGAIN, ENOTFOUND, ETIMEDOUT) - Automatically retries up to 3 times with 2s delay between attempts - Logs retry attempts for monitoring - Prevents 500 errors from temporary DNS hiccups - Fixes: n8n workflow failures during brief network issues Impact: - Improves reliability during DNS/network instability - Reduces false negatives (missed trades due to transient errors) - User-friendly retry logs for diagnostics
This commit is contained in:
@@ -75,8 +75,52 @@ export class DriftService {
|
|||||||
console.log('✅ Drift service created for wallet:', this.wallet.publicKey.toString())
|
console.log('✅ Drift service created for wallet:', this.wallet.publicKey.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retry helper for handling transient network failures (DNS, timeouts)
|
||||||
|
*/
|
||||||
|
private async retryOperation<T>(
|
||||||
|
operation: () => Promise<T>,
|
||||||
|
maxRetries: number = 3,
|
||||||
|
delayMs: number = 2000,
|
||||||
|
operationName: string = 'operation'
|
||||||
|
): Promise<T> {
|
||||||
|
let lastError: Error | null = null
|
||||||
|
|
||||||
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
|
try {
|
||||||
|
return await operation()
|
||||||
|
} catch (error: any) {
|
||||||
|
lastError = error
|
||||||
|
|
||||||
|
// Check if it's a transient network error
|
||||||
|
const isTransient =
|
||||||
|
error?.message?.includes('fetch failed') ||
|
||||||
|
error?.message?.includes('EAI_AGAIN') ||
|
||||||
|
error?.message?.includes('ENOTFOUND') ||
|
||||||
|
error?.message?.includes('ETIMEDOUT') ||
|
||||||
|
error?.message?.includes('ECONNREFUSED') ||
|
||||||
|
error?.code === 'EAI_AGAIN' ||
|
||||||
|
error?.cause?.code === 'EAI_AGAIN'
|
||||||
|
|
||||||
|
if (!isTransient || attempt === maxRetries) {
|
||||||
|
// Non-transient error or max retries reached - fail immediately
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`⚠️ ${operationName} failed (attempt ${attempt}/${maxRetries}): ${error?.message || error}`)
|
||||||
|
console.log(`⏳ Retrying in ${delayMs}ms...`)
|
||||||
|
|
||||||
|
// Wait before retry
|
||||||
|
await new Promise(resolve => setTimeout(resolve, delayMs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw lastError || new Error(`${operationName} failed after ${maxRetries} retries`)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Drift client and subscribe to account updates
|
* Initialize Drift client and subscribe to account updates
|
||||||
|
* Includes automatic retry for transient network failures (DNS, timeouts)
|
||||||
*/
|
*/
|
||||||
async initialize(): Promise<void> {
|
async initialize(): Promise<void> {
|
||||||
if (this.isInitialized) {
|
if (this.isInitialized) {
|
||||||
@@ -87,6 +131,8 @@ export class DriftService {
|
|||||||
try {
|
try {
|
||||||
console.log('🚀 Initializing Drift Protocol client...')
|
console.log('🚀 Initializing Drift Protocol client...')
|
||||||
|
|
||||||
|
// Wrap initialization in retry logic to handle DNS failures
|
||||||
|
await this.retryOperation(async () => {
|
||||||
// Initialize Drift SDK (gets program IDs and config)
|
// Initialize Drift SDK (gets program IDs and config)
|
||||||
const sdkConfig = initialize({
|
const sdkConfig = initialize({
|
||||||
env: this.config.env === 'devnet' ? 'devnet' : 'mainnet-beta'
|
env: this.config.env === 'devnet' ? 'devnet' : 'mainnet-beta'
|
||||||
@@ -102,18 +148,19 @@ export class DriftService {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// Subscribe to Drift account updates
|
// Subscribe to Drift account updates (this makes RPC calls)
|
||||||
await this.driftClient.subscribe()
|
await this.driftClient.subscribe()
|
||||||
console.log('✅ Drift client subscribed to account updates')
|
console.log('✅ Drift client subscribed to account updates')
|
||||||
|
|
||||||
// Get user account
|
// Get user account
|
||||||
this.user = this.driftClient.getUser()
|
this.user = this.driftClient.getUser()
|
||||||
|
}, 3, 2000, 'Drift initialization')
|
||||||
|
|
||||||
this.isInitialized = true
|
this.isInitialized = true
|
||||||
console.log('✅ Drift service initialized successfully')
|
console.log('✅ Drift service initialized successfully')
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Failed to initialize Drift service:', error)
|
console.error('❌ Failed to initialize Drift service after retries:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user