abort(): register live socket at urllib3 request() so Force Stop wakes recv() even while waiting for response headers (was only after headers via active_response)
This commit is contained in:
1 parent
96be94586f
commit
f07bfc57a2
2 files changed
+9
-5
No files matched your search
+3
-5
@@ -116,12 +116,10 @@ class GenericAgent:
|
||||
if self.handler is not None: self.handler.code_stop_signal.append(1)
|
||||
for sess in getattr(self.llmclient.backend, '_sessions', [self.llmclient.backend]):
|
||||
sess.should_stop = lambda: self.stop_sig # live read; cleared by run()'s finally
|
||||
try: # wake a recv() blocked in another thread. Verified on Windows: shutdown()/close() do NOT
|
||||
# wake it (makefile refcount defers real closesocket); _real_close() does -> ChunkedEncodingError
|
||||
try: # wake a recv() blocked in another thread (waiting headers OR reading stream). Verified on Windows:
|
||||
# shutdown()/close() do NOT wake it (makefile refcount defers closesocket); _real_close() does
|
||||
import socket as _socket
|
||||
raw = sess.active_response.raw
|
||||
fp = getattr(getattr(raw, '_fp', None), 'fp', None) # http.client response -> buffered socket file
|
||||
sock = fp.raw._sock if fp else raw.connection.sock # SocketIO._sock (SSL-wrapped OK); fallback urllib3 conn
|
||||
sock = sys.modules['llmcore']._INFLIGHT[sess._tid] # socket registered at urllib3 request() time, before headers
|
||||
try: sock.shutdown(_socket.SHUT_RDWR) # for non-Windows semantics
|
||||
except OSError: pass
|
||||
try: sock._real_close() # CPython internal; bypasses refcount -> actual closesocket
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import os, json, re, time, requests, sys, threading, urllib3, base64, importlib, uuid, pathlib, copy
|
||||
from datetime import datetime
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
_INFLIGHT = {} # thread ident -> live socket; lets abort() close it even before response headers arrive
|
||||
_orig_conn_request = urllib3.connection.HTTPConnection.request
|
||||
def _conn_request_hook(self, *a, **k): # after request() the socket is connected+sent; conn.sock may later be None'd by http.client
|
||||
r = _orig_conn_request(self, *a, **k); _INFLIGHT[threading.get_ident()] = self.sock; return r
|
||||
urllib3.connection.HTTPConnection.request = _conn_request_hook
|
||||
_RESP_CACHE_KEY = str(uuid.uuid4()); _RESP_CODEX_KEY = str(uuid.uuid4())
|
||||
_ROOT = os.path.dirname(os.path.abspath(__file__))
|
||||
if _ROOT not in sys.path: sys.path.append(_ROOT)
|
||||
@@ -459,6 +464,7 @@ def _stream_with_retry(sess, url, headers, payload, parse_fn):
|
||||
STATS.update(t_start=time.time(), t_ttft=None)
|
||||
if not sess.stream: STATS['t_ttft'] = STATS['t_start']
|
||||
try:
|
||||
sess._tid = threading.get_ident() # abort() looks up _INFLIGHT[_tid]
|
||||
with requests.post(url, headers=headers, json=payload, stream=sess.stream,
|
||||
timeout=(sess.connect_timeout, sess.read_timeout), proxies=sess.proxies, verify=sess.verify) as r:
|
||||
sess.active_response = r
|
||||
|
||||
Reference in new issue
Block a user