DrValera commited on
Commit
06298fc
·
verified ·
1 Parent(s): b632be5

Adjusted ping every 270 seconds for large computations up to 900 seconds

Browse files
Files changed (1) hide show
  1. main.py +73 -27
main.py CHANGED
@@ -38,7 +38,7 @@ SDK_MAX_BODY_BYTES = int(os.getenv("SDK_MAX_BODY_BYTES", "25000000")) # 25MB de
38
  SDK_MAX_BODY_BYTES_extended = int(os.getenv("SDK_MAX_BODY_BYTES_extended", "125000000")) # 125MB default for prod
39
 
40
  # How long to wait for upstream (API) response; long runs may need 30+ min (1800+)
41
- UPSTREAM_TIMEOUT = float(os.getenv("UPSTREAM_TIMEOUT", "1800"))
42
  # While waiting for a response, ping upstream every N seconds so the backend Space does not sleep
43
  PING_UPSTREAM_INTERVAL = float(os.getenv("PING_UPSTREAM_INTERVAL", "270"))
44
 
@@ -173,22 +173,44 @@ async def _forward_stream(path: str, files=None, data=None, user_token: str | No
173
  headers_holder = {}
174
 
175
  async def body_iter():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  try:
177
- async with stream_ctx as resp:
178
- status_holder["code"] = resp.status_code
179
- media_type_holder["ct"] = resp.headers.get("content-type", "application/octet-stream")
180
- headers_holder.update(_filter_resp_headers(resp.headers))
181
-
182
- # If upstream already returned an error, buffer it (short text/json)
183
- if resp.status_code >= 400:
184
- # Buffer entire payload and yield once
185
- chunk = await resp.aread()
186
- yield chunk
187
- return
188
-
189
- async for chunk in resp.aiter_raw():
190
- yield chunk
191
  finally:
 
 
 
 
 
192
  await _cancel_ping_task(ping_task)
193
  await client.aclose()
194
 
@@ -251,20 +273,44 @@ async def _forward_demo_stream(path: str, *, files: dict | None, data: dict | No
251
  headers_holder = {}
252
 
253
  async def body_iter():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  try:
255
- async with stream_ctx as resp:
256
- status_holder["code"] = resp.status_code
257
- media_type_holder["ct"] = resp.headers.get("content-type", "application/octet-stream")
258
- headers_holder.update(_filter_resp_headers(resp.headers))
259
-
260
- if resp.status_code >= 400:
261
- chunk = await resp.aread()
262
- yield chunk
263
- return
264
-
265
- async for chunk in resp.aiter_raw():
266
- yield chunk
267
  finally:
 
 
 
 
 
268
  await _cancel_ping_task(ping_task)
269
  await client.aclose()
270
 
 
38
  SDK_MAX_BODY_BYTES_extended = int(os.getenv("SDK_MAX_BODY_BYTES_extended", "125000000")) # 125MB default for prod
39
 
40
  # How long to wait for upstream (API) response; long runs may need 30+ min (1800+)
41
+ UPSTREAM_TIMEOUT = float(os.getenv("UPSTREAM_TIMEOUT", "900")) # 15 minutes
42
  # While waiting for a response, ping upstream every N seconds so the backend Space does not sleep
43
  PING_UPSTREAM_INTERVAL = float(os.getenv("PING_UPSTREAM_INTERVAL", "270"))
44
 
 
173
  headers_holder = {}
174
 
175
  async def body_iter():
176
+ chunk_queue: asyncio.Queue = asyncio.Queue()
177
+ stream_done = {"done": False, "exc": None}
178
+
179
+ async def stream_reader():
180
+ try:
181
+ async with stream_ctx as resp:
182
+ status_holder["code"] = resp.status_code
183
+ media_type_holder["ct"] = resp.headers.get("content-type", "application/octet-stream")
184
+ headers_holder.update(_filter_resp_headers(resp.headers))
185
+ if resp.status_code >= 400:
186
+ chunk = await resp.aread()
187
+ await chunk_queue.put(chunk)
188
+ await chunk_queue.put(None)
189
+ return
190
+ async for chunk in resp.aiter_raw():
191
+ await chunk_queue.put(chunk)
192
+ await chunk_queue.put(None)
193
+ except Exception as e:
194
+ stream_done["exc"] = e
195
+ await chunk_queue.put(None)
196
+ finally:
197
+ stream_done["done"] = True
198
+
199
+ reader_task = asyncio.create_task(stream_reader())
200
  try:
201
+ while True:
202
+ chunk = await chunk_queue.get()
203
+ if chunk is None:
204
+ if stream_done["exc"]:
205
+ raise stream_done["exc"]
206
+ break
207
+ yield chunk
 
 
 
 
 
 
 
208
  finally:
209
+ reader_task.cancel()
210
+ try:
211
+ await reader_task
212
+ except asyncio.CancelledError:
213
+ pass
214
  await _cancel_ping_task(ping_task)
215
  await client.aclose()
216
 
 
273
  headers_holder = {}
274
 
275
  async def body_iter():
276
+ chunk_queue: asyncio.Queue = asyncio.Queue()
277
+ stream_done = {"done": False, "exc": None}
278
+
279
+ async def stream_reader():
280
+ try:
281
+ async with stream_ctx as resp:
282
+ status_holder["code"] = resp.status_code
283
+ media_type_holder["ct"] = resp.headers.get("content-type", "application/octet-stream")
284
+ headers_holder.update(_filter_resp_headers(resp.headers))
285
+ if resp.status_code >= 400:
286
+ chunk = await resp.aread()
287
+ await chunk_queue.put(chunk)
288
+ await chunk_queue.put(None)
289
+ return
290
+ async for chunk in resp.aiter_raw():
291
+ await chunk_queue.put(chunk)
292
+ await chunk_queue.put(None)
293
+ except Exception as e:
294
+ stream_done["exc"] = e
295
+ await chunk_queue.put(None)
296
+ finally:
297
+ stream_done["done"] = True
298
+
299
+ reader_task = asyncio.create_task(stream_reader())
300
  try:
301
+ while True:
302
+ chunk = await chunk_queue.get()
303
+ if chunk is None:
304
+ if stream_done["exc"]:
305
+ raise stream_done["exc"]
306
+ break
307
+ yield chunk
 
 
 
 
 
308
  finally:
309
+ reader_task.cancel()
310
+ try:
311
+ await reader_task
312
+ except asyncio.CancelledError:
313
+ pass
314
  await _cancel_ping_task(ping_task)
315
  await client.aclose()
316