diff --git a/src/apiutils.nim b/src/apiutils.nim index f6a4b47..21c25df 100644 --- a/src/apiutils.nim +++ b/src/apiutils.nim @@ -58,11 +58,17 @@ template fetchImpl(result, fetchBody) {.dirty.} = if token.tok.len == 0: raise rateLimitError() + var + client = pool.acquire(genHeaders(token)) + badClient = false + try: - var resp: AsyncResponse - result = pool.use(genHeaders(token)): - resp = await c.get($url) - await resp.body + let resp = await client.get($url) + result = await resp.body + + if resp.status == $Http503: + badClient = true + raise newException(InternalError, result) if result.len > 0: if resp.headers.getOrDefault("content-encoding") == "gzip": @@ -83,6 +89,8 @@ template fetchImpl(result, fetchBody) {.dirty.} = if "length" notin e.msg and "descriptor" notin e.msg: release(token, invalid=true) raise rateLimitError() + finally: + pool.release(client, badClient=badClient) proc fetch*(url: Uri; api: Api): Future[JsonNode] {.async.} = var body: string diff --git a/src/http_pool.nim b/src/http_pool.nim index 8f4bcda..a39918b 100644 --- a/src/http_pool.nim +++ b/src/http_pool.nim @@ -1,5 +1,5 @@ # SPDX-License-Identifier: AGPL-3.0-only -import asyncdispatch, httpclient +import httpclient type HttpPool* = ref object @@ -17,20 +17,22 @@ proc setHttpProxy*(url: string; auth: string) = else: proxy = nil -proc release*(pool: HttpPool; client: AsyncHttpClient) = - if pool.conns.len >= maxConns: - client.close() +proc release*(pool: HttpPool; client: AsyncHttpClient; badClient=false) = + if pool.conns.len >= maxConns or badClient: + try: client.close() + except: discard elif client != nil: pool.conns.insert(client) -template use*(pool: HttpPool; heads: HttpHeaders; body: untyped): untyped = - var c {.inject.}: AsyncHttpClient - +proc acquire*(pool: HttpPool; heads: HttpHeaders): AsyncHttpClient = if pool.conns.len == 0: - c = newAsyncHttpClient(headers=heads, proxy=proxy) + result = newAsyncHttpClient(headers=heads, proxy=proxy) else: - c = pool.conns.pop() - c.headers = heads + result = pool.conns.pop() + result.headers = heads + +template use*(pool: HttpPool; heads: HttpHeaders; body: untyped): untyped = + let c {.inject.} = pool.acquire(heads) try: body diff --git a/src/routes/timeline.nim b/src/routes/timeline.nim index 9eefc4e..815e08e 100644 --- a/src/routes/timeline.nim +++ b/src/routes/timeline.nim @@ -45,10 +45,15 @@ proc fetchTimeline*(after: string; query: Query; skipRail=false): else: rail = getCachedPhotoRail(name) + # var timeline = + # case query.kind + # of posts: await getTimeline(profileId, after) + # of replies: await getTimeline(profileId, after, replies=true) + # of media: await getMediaTimeline(profileId, after) + # else: await getSearch[Tweet](query, after) + var timeline = case query.kind - of posts: await getTimeline(profileId, after) - of replies: await getTimeline(profileId, after, replies=true) of media: await getMediaTimeline(profileId, after) else: await getSearch[Tweet](query, after)