async function* lookupIpsStream() {
const concurrency = 1
const callGeoLookupsStream = transform(concurrency, async ip => {
const baiduApiUrl = `${geoApiBaseUrl}/baidu/${ip}`
try {
const baidu = await (await fetch(
baiduApiUrl,
{ headers: new Headers({ "Authorization": `Basic ${basicAuthToken}` }) }
)).json()
const result = {
ip,
baidu
}
if (baidu.content) {
if (baidu.content.address_detail) {
const cityCode = baidu.content.address_detail.city_code
if (baiduCities[cityCode]) {
result.city = baiduCities[cityCode]
}
}
if (baidu.content.point) {
result.long = Number(baidu.content.point.x)
result.lat = Number(baidu.content.point.y)
}
}
return result
} catch (e) {
console.info('IP lookup error', ip, e.message)
return {
error: `${e.message}, ${baiduApiUrl}`
}
}
})
const startTime = new Date()
let counter = 0
let hits = 0
let errors = 0
let lastError = ''
for await (const geoLookup of callGeoLookupsStream([...newIps])) {
const now = new Date()
if (now - startTime > maxElapsed || counter >= maxLookups) {
yield {
done: true,
timeout: true,
counter,
hits,
errors,
lastError
}
return
}
if (geoLookup.ip) {
hits++
yield {
counter,
hits,
errors,
lastError,
...geoLookup
}
} else {
errors++
if (geoLookup.error) {
lastError = geoLookup.error
}
yield {
counter,
hits,
errors,
lastError
}
}
counter++
}
yield {
done: true,
counter,
hits,
errors,
lastError
}
}