Skip to content

Commit 3c34584

Browse files
Milvus-doc-botMilvus-doc-bot
authored andcommitted
Release new docs to master
1 parent d54db7a commit 3c34584

13 files changed

Lines changed: 3609 additions & 571 deletions

v3.0.x/scripts/lib/feishuFetch.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
const fetch = require('node-fetch')
2+
3+
const DEFAULT_RETRIES = parseInt(process.env.FEISHU_FETCH_RETRIES || '5', 10)
4+
const DEFAULT_BASE_DELAY_MS = parseInt(process.env.FEISHU_FETCH_BASE_DELAY_MS || '1000', 10)
5+
const DEFAULT_TIMEOUT_MS = parseInt(process.env.FEISHU_FETCH_TIMEOUT_MS || '60000', 10)
6+
7+
function sleep(ms) {
8+
return new Promise(resolve => setTimeout(resolve, ms))
9+
}
10+
11+
function retryAfterMs(res) {
12+
const value = res.headers?.get?.('retry-after')
13+
if (!value) return null
14+
15+
const seconds = Number(value)
16+
if (Number.isFinite(seconds)) return seconds * 1000
17+
18+
const date = Date.parse(value)
19+
if (Number.isFinite(date)) return Math.max(0, date - Date.now())
20+
21+
return null
22+
}
23+
24+
function retryDelayMs(attempt, res) {
25+
const retryAfter = res ? retryAfterMs(res) : null
26+
if (retryAfter !== null) return retryAfter
27+
28+
const jitter = Math.floor(Math.random() * 250)
29+
return DEFAULT_BASE_DELAY_MS * Math.pow(2, attempt - 1) + jitter
30+
}
31+
32+
function shouldRetryStatus(status) {
33+
return status === 408 || status === 425 || status === 429 || status >= 500
34+
}
35+
36+
async function fetchFeishuJsonWithRetry(url, options = {}, label = url) {
37+
const retries = Number.isInteger(options.retries) ? options.retries : DEFAULT_RETRIES
38+
const timeoutMs = Number.isInteger(options.timeoutMs) ? options.timeoutMs : DEFAULT_TIMEOUT_MS
39+
const fetchOptions = { ...options }
40+
delete fetchOptions.retries
41+
delete fetchOptions.timeoutMs
42+
43+
let lastError = null
44+
45+
for (let attempt = 1; attempt <= retries + 1; attempt++) {
46+
const controller = new AbortController()
47+
const timeout = setTimeout(() => controller.abort(), timeoutMs)
48+
49+
try {
50+
const res = await fetch(url, { ...fetchOptions, signal: fetchOptions.signal || controller.signal })
51+
const text = await res.text()
52+
let json
53+
54+
try {
55+
json = text ? JSON.parse(text) : {}
56+
} catch (error) {
57+
error.message = `[feishu] ${label} returned invalid JSON: ${error.message}`
58+
throw error
59+
}
60+
61+
if (!res.ok && shouldRetryStatus(res.status) && attempt <= retries + 1) {
62+
lastError = new Error(`[feishu] ${label} HTTP ${res.status}: ${text.slice(0, 500)}`)
63+
if (attempt <= retries) {
64+
await sleep(retryDelayMs(attempt, res))
65+
continue
66+
}
67+
}
68+
69+
return json
70+
} catch (error) {
71+
lastError = error
72+
if (attempt > retries) break
73+
await sleep(retryDelayMs(attempt))
74+
} finally {
75+
clearTimeout(timeout)
76+
}
77+
}
78+
79+
throw lastError || new Error(`[feishu] ${label} failed`)
80+
}
81+
82+
module.exports = {
83+
fetchFeishuJsonWithRetry,
84+
}

0 commit comments

Comments
 (0)