[ВОЛК] Socker timeout
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
2026-01-10 18:35:10 +03:00
parent 9580d167bd
commit 906aa4ed93
+180 -17
View File
@@ -211,7 +211,48 @@ def _send_photo_sync(send_photo_url, image_data, caption, chat_id, disable_notif
read=max_timeout
)
return super().init_poolmanager(*args, **kwargs)
pool = super().init_poolmanager(*args, **kwargs)
# Устанавливаем socket timeout для всех соединений в пуле
# Это критично для операций записи в сокет
# Используем несколько подходов для надежности
try:
if hasattr(pool, 'ConnectionCls') and pool.ConnectionCls:
original_connect = pool.ConnectionCls.connect
def connect_with_socket_timeout(self):
result = original_connect(self)
# Устанавливаем socket timeout после подключения
# Это применяется ко всем операциям с сокетом (read и write)
if hasattr(self, 'sock') and self.sock:
self.sock.settimeout(write_timeout)
return result
pool.ConnectionCls.connect = connect_with_socket_timeout
except Exception:
# Если не удалось установить через ConnectionCls, используем другой подход
pass
return pool
def _new_conn(self):
"""Создаем новое соединение с установкой socket timeout"""
conn = super()._new_conn()
# Устанавливаем socket timeout для операций записи
try:
if hasattr(conn, 'sock') and conn.sock:
conn.sock.settimeout(write_timeout)
elif hasattr(conn, 'connect'):
# Если соединение еще не создано, перехватываем метод connect
original_connect = conn.connect
def connect_with_timeout():
result = original_connect()
if hasattr(conn, 'sock') and conn.sock:
conn.sock.settimeout(write_timeout)
return result
conn.connect = connect_with_timeout
except Exception:
# Игнорируем ошибки при установке timeout
pass
return conn
# Монтируем кастомный адаптер
adapter = CustomHTTPAdapter(max_retries=Retry(total=0))
@@ -260,6 +301,8 @@ def _edit_caption_sync(edit_caption_url, chat_id, message_id, caption, timeout):
Returns:
requests.Response объект
"""
import socket
try:
data = {
'chat_id': chat_id,
@@ -268,21 +311,77 @@ def _edit_caption_sync(edit_caption_url, chat_id, message_id, caption, timeout):
'parse_mode': 'HTML'
}
# Преобразуем timeout в формат, который принимает requests
# requests принимает либо число, либо кортеж (connect, read)
# Извлекаем таймауты
if isinstance(timeout, tuple):
if len(timeout) >= 3:
# Используем максимальный из read и write timeout
connect_timeout, read_timeout, write_timeout = timeout[0], timeout[1], timeout[2]
requests_timeout = (connect_timeout, max(read_timeout, write_timeout))
elif len(timeout) == 2:
requests_timeout = timeout
connect_timeout, read_timeout = timeout[0], timeout[1]
write_timeout = read_timeout
else:
requests_timeout = timeout[0]
connect_timeout = read_timeout = write_timeout = timeout[0]
else:
requests_timeout = timeout
connect_timeout = read_timeout = write_timeout = timeout
response = requests.post(
# Преобразуем timeout в формат, который принимает requests
requests_timeout = (connect_timeout, max(read_timeout, write_timeout))
# Создаем сессию с кастомным адаптером для установки socket timeout
session = requests.Session()
class CustomHTTPAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
socket_options = kwargs.get('socket_options', [])
socket_options.append((socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1))
kwargs['socket_options'] = socket_options
max_timeout = max(connect_timeout, read_timeout, write_timeout)
if 'timeout' not in kwargs:
kwargs['timeout'] = Urllib3Timeout(
connect=connect_timeout,
read=max_timeout
)
pool = super().init_poolmanager(*args, **kwargs)
# Устанавливаем socket timeout для всех соединений в пуле
try:
if hasattr(pool, 'ConnectionCls') and pool.ConnectionCls:
original_connect = pool.ConnectionCls.connect
def connect_with_socket_timeout(self):
result = original_connect(self)
if hasattr(self, 'sock') and self.sock:
self.sock.settimeout(write_timeout)
return result
pool.ConnectionCls.connect = connect_with_socket_timeout
except Exception:
pass
return pool
def _new_conn(self):
"""Создаем новое соединение с установкой socket timeout"""
conn = super()._new_conn()
try:
if hasattr(conn, 'sock') and conn.sock:
conn.sock.settimeout(write_timeout)
elif hasattr(conn, 'connect'):
original_connect = conn.connect
def connect_with_timeout():
result = original_connect()
if hasattr(conn, 'sock') and conn.sock:
conn.sock.settimeout(write_timeout)
return result
conn.connect = connect_with_timeout
except Exception:
pass
return conn
adapter = CustomHTTPAdapter(max_retries=Retry(total=0))
session.mount('http://', adapter)
session.mount('https://', adapter)
response = session.post(
edit_caption_url,
json=data,
timeout=requests_timeout
@@ -295,6 +394,9 @@ def _edit_caption_sync(edit_caption_url, chat_id, message_id, caption, timeout):
raise
except Exception as e:
raise
finally:
if 'session' in locals():
session.close()
def _edit_text_sync(edit_text_url, chat_id, message_id, text, timeout):
"""
@@ -311,6 +413,8 @@ def _edit_text_sync(edit_text_url, chat_id, message_id, text, timeout):
Returns:
requests.Response объект
"""
import socket
try:
data = {
'chat_id': chat_id,
@@ -320,21 +424,77 @@ def _edit_text_sync(edit_text_url, chat_id, message_id, text, timeout):
'disable_web_page_preview': True
}
# Преобразуем timeout в формат, который принимает requests
# requests принимает либо число, либо кортеж (connect, read)
# Извлекаем таймауты
if isinstance(timeout, tuple):
if len(timeout) >= 3:
# Используем максимальный из read и write timeout
connect_timeout, read_timeout, write_timeout = timeout[0], timeout[1], timeout[2]
requests_timeout = (connect_timeout, max(read_timeout, write_timeout))
elif len(timeout) == 2:
requests_timeout = timeout
connect_timeout, read_timeout = timeout[0], timeout[1]
write_timeout = read_timeout
else:
requests_timeout = timeout[0]
connect_timeout = read_timeout = write_timeout = timeout[0]
else:
requests_timeout = timeout
connect_timeout = read_timeout = write_timeout = timeout
response = requests.post(
# Преобразуем timeout в формат, который принимает requests
requests_timeout = (connect_timeout, max(read_timeout, write_timeout))
# Создаем сессию с кастомным адаптером для установки socket timeout
session = requests.Session()
class CustomHTTPAdapter(HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
socket_options = kwargs.get('socket_options', [])
socket_options.append((socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1))
kwargs['socket_options'] = socket_options
max_timeout = max(connect_timeout, read_timeout, write_timeout)
if 'timeout' not in kwargs:
kwargs['timeout'] = Urllib3Timeout(
connect=connect_timeout,
read=max_timeout
)
pool = super().init_poolmanager(*args, **kwargs)
# Устанавливаем socket timeout для всех соединений в пуле
try:
if hasattr(pool, 'ConnectionCls') and pool.ConnectionCls:
original_connect = pool.ConnectionCls.connect
def connect_with_socket_timeout(self):
result = original_connect(self)
if hasattr(self, 'sock') and self.sock:
self.sock.settimeout(write_timeout)
return result
pool.ConnectionCls.connect = connect_with_socket_timeout
except Exception:
pass
return pool
def _new_conn(self):
"""Создаем новое соединение с установкой socket timeout"""
conn = super()._new_conn()
try:
if hasattr(conn, 'sock') and conn.sock:
conn.sock.settimeout(write_timeout)
elif hasattr(conn, 'connect'):
original_connect = conn.connect
def connect_with_timeout():
result = original_connect()
if hasattr(conn, 'sock') and conn.sock:
conn.sock.settimeout(write_timeout)
return result
conn.connect = connect_with_timeout
except Exception:
pass
return conn
adapter = CustomHTTPAdapter(max_retries=Retry(total=0))
session.mount('http://', adapter)
session.mount('https://', adapter)
response = session.post(
edit_text_url,
json=data,
timeout=requests_timeout
@@ -347,6 +507,9 @@ def _edit_text_sync(edit_text_url, chat_id, message_id, text, timeout):
raise
except Exception as e:
raise
finally:
if 'session' in locals():
session.close()
async def publish_to_tg(vk_post_id):
"""Публикация одной записи по VK post ID"""