unrealon 1.0.9__py3-none-any.whl → 1.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. unrealon/__init__.py +23 -21
  2. unrealon-1.1.0.dist-info/METADATA +164 -0
  3. unrealon-1.1.0.dist-info/RECORD +82 -0
  4. {unrealon-1.0.9.dist-info → unrealon-1.1.0.dist-info}/WHEEL +1 -1
  5. unrealon-1.1.0.dist-info/entry_points.txt +9 -0
  6. {unrealon-1.0.9.dist-info → unrealon-1.1.0.dist-info/licenses}/LICENSE +1 -1
  7. unrealon_bridge/__init__.py +114 -0
  8. unrealon_bridge/cli.py +316 -0
  9. unrealon_bridge/client/__init__.py +93 -0
  10. unrealon_bridge/client/base.py +78 -0
  11. unrealon_bridge/client/commands.py +89 -0
  12. unrealon_bridge/client/connection.py +90 -0
  13. unrealon_bridge/client/events.py +65 -0
  14. unrealon_bridge/client/health.py +38 -0
  15. unrealon_bridge/client/html_parser.py +146 -0
  16. unrealon_bridge/client/logging.py +139 -0
  17. unrealon_bridge/client/proxy.py +70 -0
  18. unrealon_bridge/client/scheduler.py +450 -0
  19. unrealon_bridge/client/session.py +70 -0
  20. unrealon_bridge/configs/__init__.py +14 -0
  21. unrealon_bridge/configs/bridge_config.py +212 -0
  22. unrealon_bridge/configs/bridge_config.yaml +39 -0
  23. unrealon_bridge/models/__init__.py +138 -0
  24. unrealon_bridge/models/base.py +28 -0
  25. unrealon_bridge/models/command.py +41 -0
  26. unrealon_bridge/models/events.py +40 -0
  27. unrealon_bridge/models/html_parser.py +79 -0
  28. unrealon_bridge/models/logging.py +55 -0
  29. unrealon_bridge/models/parser.py +63 -0
  30. unrealon_bridge/models/proxy.py +41 -0
  31. unrealon_bridge/models/requests.py +95 -0
  32. unrealon_bridge/models/responses.py +88 -0
  33. unrealon_bridge/models/scheduler.py +592 -0
  34. unrealon_bridge/models/session.py +28 -0
  35. unrealon_bridge/server/__init__.py +91 -0
  36. unrealon_bridge/server/base.py +171 -0
  37. unrealon_bridge/server/handlers/__init__.py +23 -0
  38. unrealon_bridge/server/handlers/command.py +110 -0
  39. unrealon_bridge/server/handlers/html_parser.py +139 -0
  40. unrealon_bridge/server/handlers/logging.py +95 -0
  41. unrealon_bridge/server/handlers/parser.py +95 -0
  42. unrealon_bridge/server/handlers/proxy.py +75 -0
  43. unrealon_bridge/server/handlers/scheduler.py +545 -0
  44. unrealon_bridge/server/handlers/session.py +66 -0
  45. unrealon_browser/__init__.py +61 -18
  46. unrealon_browser/{src/cli → cli}/browser_cli.py +6 -13
  47. unrealon_browser/{src/cli → cli}/cookies_cli.py +5 -1
  48. unrealon_browser/{src/core → core}/browser_manager.py +2 -2
  49. unrealon_browser/{src/managers → managers}/captcha.py +1 -1
  50. unrealon_browser/{src/managers → managers}/cookies.py +1 -1
  51. unrealon_browser/managers/logger_bridge.py +231 -0
  52. unrealon_browser/{src/managers → managers}/profile.py +1 -1
  53. unrealon_driver/__init__.py +73 -19
  54. unrealon_driver/browser/__init__.py +8 -0
  55. unrealon_driver/browser/config.py +74 -0
  56. unrealon_driver/browser/manager.py +416 -0
  57. unrealon_driver/exceptions.py +28 -0
  58. unrealon_driver/parser/__init__.py +55 -0
  59. unrealon_driver/parser/cli_manager.py +141 -0
  60. unrealon_driver/parser/daemon_manager.py +227 -0
  61. unrealon_driver/parser/managers/__init__.py +46 -0
  62. unrealon_driver/parser/managers/browser.py +51 -0
  63. unrealon_driver/parser/managers/config.py +281 -0
  64. unrealon_driver/parser/managers/error.py +412 -0
  65. unrealon_driver/parser/managers/html.py +732 -0
  66. unrealon_driver/parser/managers/logging.py +609 -0
  67. unrealon_driver/parser/managers/result.py +321 -0
  68. unrealon_driver/parser/parser_manager.py +628 -0
  69. unrealon/sdk_config.py +0 -88
  70. unrealon-1.0.9.dist-info/METADATA +0 -810
  71. unrealon-1.0.9.dist-info/RECORD +0 -246
  72. unrealon_browser/pyproject.toml +0 -182
  73. unrealon_browser/src/__init__.py +0 -62
  74. unrealon_browser/src/managers/logger_bridge.py +0 -395
  75. unrealon_driver/README.md +0 -204
  76. unrealon_driver/pyproject.toml +0 -187
  77. unrealon_driver/src/__init__.py +0 -90
  78. unrealon_driver/src/cli/__init__.py +0 -10
  79. unrealon_driver/src/cli/main.py +0 -66
  80. unrealon_driver/src/cli/simple.py +0 -510
  81. unrealon_driver/src/config/__init__.py +0 -11
  82. unrealon_driver/src/config/auto_config.py +0 -478
  83. unrealon_driver/src/core/__init__.py +0 -18
  84. unrealon_driver/src/core/exceptions.py +0 -289
  85. unrealon_driver/src/core/parser.py +0 -638
  86. unrealon_driver/src/dto/__init__.py +0 -66
  87. unrealon_driver/src/dto/cli.py +0 -119
  88. unrealon_driver/src/dto/config.py +0 -18
  89. unrealon_driver/src/dto/events.py +0 -237
  90. unrealon_driver/src/dto/execution.py +0 -313
  91. unrealon_driver/src/dto/services.py +0 -311
  92. unrealon_driver/src/execution/__init__.py +0 -23
  93. unrealon_driver/src/execution/daemon_mode.py +0 -317
  94. unrealon_driver/src/execution/interactive_mode.py +0 -88
  95. unrealon_driver/src/execution/modes.py +0 -45
  96. unrealon_driver/src/execution/scheduled_mode.py +0 -209
  97. unrealon_driver/src/execution/test_mode.py +0 -250
  98. unrealon_driver/src/logging/__init__.py +0 -24
  99. unrealon_driver/src/logging/driver_logger.py +0 -512
  100. unrealon_driver/src/services/__init__.py +0 -24
  101. unrealon_driver/src/services/browser_service.py +0 -726
  102. unrealon_driver/src/services/llm/__init__.py +0 -15
  103. unrealon_driver/src/services/llm/browser_llm_service.py +0 -363
  104. unrealon_driver/src/services/llm/llm.py +0 -195
  105. unrealon_driver/src/services/logger_service.py +0 -232
  106. unrealon_driver/src/services/metrics_service.py +0 -185
  107. unrealon_driver/src/services/scheduler_service.py +0 -489
  108. unrealon_driver/src/services/websocket_service.py +0 -362
  109. unrealon_driver/src/utils/__init__.py +0 -16
  110. unrealon_driver/src/utils/service_factory.py +0 -317
  111. unrealon_driver/src/utils/time_formatter.py +0 -338
  112. unrealon_llm/README.md +0 -44
  113. unrealon_llm/__init__.py +0 -26
  114. unrealon_llm/pyproject.toml +0 -154
  115. unrealon_llm/src/__init__.py +0 -228
  116. unrealon_llm/src/cli/__init__.py +0 -0
  117. unrealon_llm/src/core/__init__.py +0 -11
  118. unrealon_llm/src/core/smart_client.py +0 -438
  119. unrealon_llm/src/dto/__init__.py +0 -155
  120. unrealon_llm/src/dto/models/__init__.py +0 -0
  121. unrealon_llm/src/dto/models/config.py +0 -343
  122. unrealon_llm/src/dto/models/core.py +0 -328
  123. unrealon_llm/src/dto/models/enums.py +0 -123
  124. unrealon_llm/src/dto/models/html_analysis.py +0 -345
  125. unrealon_llm/src/dto/models/statistics.py +0 -473
  126. unrealon_llm/src/dto/models/translation.py +0 -383
  127. unrealon_llm/src/dto/models/type_conversion.py +0 -462
  128. unrealon_llm/src/dto/schemas/__init__.py +0 -0
  129. unrealon_llm/src/exceptions.py +0 -392
  130. unrealon_llm/src/llm_config/__init__.py +0 -20
  131. unrealon_llm/src/llm_config/logging_config.py +0 -178
  132. unrealon_llm/src/llm_logging/__init__.py +0 -42
  133. unrealon_llm/src/llm_logging/llm_events.py +0 -107
  134. unrealon_llm/src/llm_logging/llm_logger.py +0 -466
  135. unrealon_llm/src/managers/__init__.py +0 -15
  136. unrealon_llm/src/managers/cache_manager.py +0 -67
  137. unrealon_llm/src/managers/cost_manager.py +0 -107
  138. unrealon_llm/src/managers/request_manager.py +0 -298
  139. unrealon_llm/src/modules/__init__.py +0 -0
  140. unrealon_llm/src/modules/html_processor/__init__.py +0 -25
  141. unrealon_llm/src/modules/html_processor/base_processor.py +0 -415
  142. unrealon_llm/src/modules/html_processor/details_processor.py +0 -85
  143. unrealon_llm/src/modules/html_processor/listing_processor.py +0 -91
  144. unrealon_llm/src/modules/html_processor/models/__init__.py +0 -20
  145. unrealon_llm/src/modules/html_processor/models/processing_models.py +0 -40
  146. unrealon_llm/src/modules/html_processor/models/universal_model.py +0 -56
  147. unrealon_llm/src/modules/html_processor/processor.py +0 -102
  148. unrealon_llm/src/modules/llm/__init__.py +0 -0
  149. unrealon_llm/src/modules/translator/__init__.py +0 -0
  150. unrealon_llm/src/provider.py +0 -116
  151. unrealon_llm/src/utils/__init__.py +0 -95
  152. unrealon_llm/src/utils/common.py +0 -64
  153. unrealon_llm/src/utils/data_extractor.py +0 -188
  154. unrealon_llm/src/utils/html_cleaner.py +0 -767
  155. unrealon_llm/src/utils/language_detector.py +0 -308
  156. unrealon_llm/src/utils/models_cache.py +0 -592
  157. unrealon_llm/src/utils/smart_counter.py +0 -229
  158. unrealon_llm/src/utils/token_counter.py +0 -189
  159. unrealon_sdk/README.md +0 -25
  160. unrealon_sdk/__init__.py +0 -30
  161. unrealon_sdk/pyproject.toml +0 -231
  162. unrealon_sdk/src/__init__.py +0 -150
  163. unrealon_sdk/src/cli/__init__.py +0 -12
  164. unrealon_sdk/src/cli/commands/__init__.py +0 -22
  165. unrealon_sdk/src/cli/commands/benchmark.py +0 -42
  166. unrealon_sdk/src/cli/commands/diagnostics.py +0 -573
  167. unrealon_sdk/src/cli/commands/health.py +0 -46
  168. unrealon_sdk/src/cli/commands/integration.py +0 -498
  169. unrealon_sdk/src/cli/commands/reports.py +0 -43
  170. unrealon_sdk/src/cli/commands/security.py +0 -36
  171. unrealon_sdk/src/cli/commands/server.py +0 -483
  172. unrealon_sdk/src/cli/commands/servers.py +0 -56
  173. unrealon_sdk/src/cli/commands/tests.py +0 -55
  174. unrealon_sdk/src/cli/main.py +0 -126
  175. unrealon_sdk/src/cli/utils/reporter.py +0 -519
  176. unrealon_sdk/src/clients/openapi.yaml +0 -3347
  177. unrealon_sdk/src/clients/python_http/__init__.py +0 -3
  178. unrealon_sdk/src/clients/python_http/api_config.py +0 -228
  179. unrealon_sdk/src/clients/python_http/models/BaseModel.py +0 -12
  180. unrealon_sdk/src/clients/python_http/models/BroadcastDeliveryStats.py +0 -33
  181. unrealon_sdk/src/clients/python_http/models/BroadcastMessage.py +0 -17
  182. unrealon_sdk/src/clients/python_http/models/BroadcastMessageRequest.py +0 -35
  183. unrealon_sdk/src/clients/python_http/models/BroadcastPriority.py +0 -10
  184. unrealon_sdk/src/clients/python_http/models/BroadcastResponse.py +0 -21
  185. unrealon_sdk/src/clients/python_http/models/BroadcastResultResponse.py +0 -33
  186. unrealon_sdk/src/clients/python_http/models/BroadcastTarget.py +0 -11
  187. unrealon_sdk/src/clients/python_http/models/ConnectionStats.py +0 -27
  188. unrealon_sdk/src/clients/python_http/models/ConnectionsResponse.py +0 -21
  189. unrealon_sdk/src/clients/python_http/models/DeveloperMessageResponse.py +0 -23
  190. unrealon_sdk/src/clients/python_http/models/ErrorResponse.py +0 -25
  191. unrealon_sdk/src/clients/python_http/models/HTTPValidationError.py +0 -16
  192. unrealon_sdk/src/clients/python_http/models/HealthResponse.py +0 -23
  193. unrealon_sdk/src/clients/python_http/models/HealthStatus.py +0 -33
  194. unrealon_sdk/src/clients/python_http/models/LogLevel.py +0 -10
  195. unrealon_sdk/src/clients/python_http/models/LoggingRequest.py +0 -27
  196. unrealon_sdk/src/clients/python_http/models/LoggingResponse.py +0 -23
  197. unrealon_sdk/src/clients/python_http/models/MaintenanceMode.py +0 -9
  198. unrealon_sdk/src/clients/python_http/models/MaintenanceModeRequest.py +0 -33
  199. unrealon_sdk/src/clients/python_http/models/MaintenanceStatusResponse.py +0 -39
  200. unrealon_sdk/src/clients/python_http/models/ParserCommandRequest.py +0 -25
  201. unrealon_sdk/src/clients/python_http/models/ParserMessageResponse.py +0 -21
  202. unrealon_sdk/src/clients/python_http/models/ParserRegistrationRequest.py +0 -28
  203. unrealon_sdk/src/clients/python_http/models/ParserRegistrationResponse.py +0 -25
  204. unrealon_sdk/src/clients/python_http/models/ParserType.py +0 -10
  205. unrealon_sdk/src/clients/python_http/models/ProxyBlockRequest.py +0 -19
  206. unrealon_sdk/src/clients/python_http/models/ProxyEndpointResponse.py +0 -20
  207. unrealon_sdk/src/clients/python_http/models/ProxyListResponse.py +0 -19
  208. unrealon_sdk/src/clients/python_http/models/ProxyProvider.py +0 -10
  209. unrealon_sdk/src/clients/python_http/models/ProxyPurchaseRequest.py +0 -25
  210. unrealon_sdk/src/clients/python_http/models/ProxyResponse.py +0 -47
  211. unrealon_sdk/src/clients/python_http/models/ProxyRotationRequest.py +0 -23
  212. unrealon_sdk/src/clients/python_http/models/ProxyStatus.py +0 -10
  213. unrealon_sdk/src/clients/python_http/models/ProxyUsageRequest.py +0 -19
  214. unrealon_sdk/src/clients/python_http/models/ProxyUsageStatsResponse.py +0 -26
  215. unrealon_sdk/src/clients/python_http/models/ServiceRegistrationDto.py +0 -23
  216. unrealon_sdk/src/clients/python_http/models/ServiceStatsResponse.py +0 -31
  217. unrealon_sdk/src/clients/python_http/models/SessionStartRequest.py +0 -23
  218. unrealon_sdk/src/clients/python_http/models/SuccessResponse.py +0 -25
  219. unrealon_sdk/src/clients/python_http/models/SystemNotificationResponse.py +0 -23
  220. unrealon_sdk/src/clients/python_http/models/ValidationError.py +0 -18
  221. unrealon_sdk/src/clients/python_http/models/ValidationErrorResponse.py +0 -21
  222. unrealon_sdk/src/clients/python_http/models/WebSocketMetrics.py +0 -21
  223. unrealon_sdk/src/clients/python_http/models/__init__.py +0 -44
  224. unrealon_sdk/src/clients/python_http/services/None_service.py +0 -35
  225. unrealon_sdk/src/clients/python_http/services/ParserManagement_service.py +0 -190
  226. unrealon_sdk/src/clients/python_http/services/ProxyManagement_service.py +0 -289
  227. unrealon_sdk/src/clients/python_http/services/SocketLogging_service.py +0 -187
  228. unrealon_sdk/src/clients/python_http/services/SystemHealth_service.py +0 -119
  229. unrealon_sdk/src/clients/python_http/services/WebSocketAPI_service.py +0 -198
  230. unrealon_sdk/src/clients/python_http/services/__init__.py +0 -0
  231. unrealon_sdk/src/clients/python_http/services/admin_service.py +0 -125
  232. unrealon_sdk/src/clients/python_http/services/async_None_service.py +0 -35
  233. unrealon_sdk/src/clients/python_http/services/async_ParserManagement_service.py +0 -190
  234. unrealon_sdk/src/clients/python_http/services/async_ProxyManagement_service.py +0 -289
  235. unrealon_sdk/src/clients/python_http/services/async_SocketLogging_service.py +0 -189
  236. unrealon_sdk/src/clients/python_http/services/async_SystemHealth_service.py +0 -123
  237. unrealon_sdk/src/clients/python_http/services/async_WebSocketAPI_service.py +0 -200
  238. unrealon_sdk/src/clients/python_http/services/async_admin_service.py +0 -125
  239. unrealon_sdk/src/clients/python_websocket/__init__.py +0 -28
  240. unrealon_sdk/src/clients/python_websocket/client.py +0 -490
  241. unrealon_sdk/src/clients/python_websocket/events.py +0 -732
  242. unrealon_sdk/src/clients/python_websocket/example.py +0 -136
  243. unrealon_sdk/src/clients/python_websocket/types.py +0 -871
  244. unrealon_sdk/src/core/__init__.py +0 -64
  245. unrealon_sdk/src/core/client.py +0 -556
  246. unrealon_sdk/src/core/config.py +0 -465
  247. unrealon_sdk/src/core/exceptions.py +0 -239
  248. unrealon_sdk/src/core/metadata.py +0 -191
  249. unrealon_sdk/src/core/models.py +0 -142
  250. unrealon_sdk/src/core/types.py +0 -68
  251. unrealon_sdk/src/dto/__init__.py +0 -268
  252. unrealon_sdk/src/dto/authentication.py +0 -108
  253. unrealon_sdk/src/dto/cache.py +0 -208
  254. unrealon_sdk/src/dto/common.py +0 -19
  255. unrealon_sdk/src/dto/concurrency.py +0 -393
  256. unrealon_sdk/src/dto/events.py +0 -108
  257. unrealon_sdk/src/dto/health.py +0 -339
  258. unrealon_sdk/src/dto/load_balancing.py +0 -336
  259. unrealon_sdk/src/dto/logging.py +0 -230
  260. unrealon_sdk/src/dto/performance.py +0 -165
  261. unrealon_sdk/src/dto/rate_limiting.py +0 -295
  262. unrealon_sdk/src/dto/resource_pooling.py +0 -128
  263. unrealon_sdk/src/dto/structured_logging.py +0 -112
  264. unrealon_sdk/src/dto/task_scheduling.py +0 -121
  265. unrealon_sdk/src/dto/websocket.py +0 -55
  266. unrealon_sdk/src/enterprise/__init__.py +0 -59
  267. unrealon_sdk/src/enterprise/authentication.py +0 -401
  268. unrealon_sdk/src/enterprise/cache_manager.py +0 -578
  269. unrealon_sdk/src/enterprise/error_recovery.py +0 -494
  270. unrealon_sdk/src/enterprise/event_system.py +0 -549
  271. unrealon_sdk/src/enterprise/health_monitor.py +0 -747
  272. unrealon_sdk/src/enterprise/load_balancer.py +0 -964
  273. unrealon_sdk/src/enterprise/logging/__init__.py +0 -68
  274. unrealon_sdk/src/enterprise/logging/cleanup.py +0 -156
  275. unrealon_sdk/src/enterprise/logging/development.py +0 -744
  276. unrealon_sdk/src/enterprise/logging/service.py +0 -410
  277. unrealon_sdk/src/enterprise/multithreading_manager.py +0 -853
  278. unrealon_sdk/src/enterprise/performance_monitor.py +0 -539
  279. unrealon_sdk/src/enterprise/proxy_manager.py +0 -696
  280. unrealon_sdk/src/enterprise/rate_limiter.py +0 -652
  281. unrealon_sdk/src/enterprise/resource_pool.py +0 -763
  282. unrealon_sdk/src/enterprise/task_scheduler.py +0 -709
  283. unrealon_sdk/src/internal/__init__.py +0 -10
  284. unrealon_sdk/src/internal/command_router.py +0 -497
  285. unrealon_sdk/src/internal/connection_manager.py +0 -397
  286. unrealon_sdk/src/internal/http_client.py +0 -446
  287. unrealon_sdk/src/internal/websocket_client.py +0 -420
  288. unrealon_sdk/src/provider.py +0 -471
  289. unrealon_sdk/src/utils.py +0 -234
  290. /unrealon_browser/{src/cli → cli}/__init__.py +0 -0
  291. /unrealon_browser/{src/cli → cli}/interactive_mode.py +0 -0
  292. /unrealon_browser/{src/cli → cli}/main.py +0 -0
  293. /unrealon_browser/{src/core → core}/__init__.py +0 -0
  294. /unrealon_browser/{src/dto → dto}/__init__.py +0 -0
  295. /unrealon_browser/{src/dto → dto}/models/config.py +0 -0
  296. /unrealon_browser/{src/dto → dto}/models/core.py +0 -0
  297. /unrealon_browser/{src/dto → dto}/models/dataclasses.py +0 -0
  298. /unrealon_browser/{src/dto → dto}/models/detection.py +0 -0
  299. /unrealon_browser/{src/dto → dto}/models/enums.py +0 -0
  300. /unrealon_browser/{src/dto → dto}/models/statistics.py +0 -0
  301. /unrealon_browser/{src/managers → managers}/__init__.py +0 -0
  302. /unrealon_browser/{src/managers → managers}/stealth.py +0 -0
@@ -1,763 +0,0 @@
1
- """
2
- Resource Pool - Layer 4 Concurrency Service
3
-
4
- Enterprise-grade resource pooling system with intelligent lifecycle management,
5
- health monitoring, and automatic optimization. Provides efficient resource
6
- utilization with connection pooling, thread management, and memory optimization.
7
-
8
- Features:
9
- - Multi-type resource pooling (connections, threads, memory, files)
10
- - Dynamic pool sizing with auto-scaling capabilities
11
- - Health monitoring and automatic resource validation
12
- - Resource lifecycle management with cleanup
13
- - Pool exhaustion handling with queuing and overflow
14
- - Performance optimization with usage analytics
15
- - Leak detection and automatic resource recovery
16
- - Pool warmup and preemptive resource allocation
17
- - Resource tagging and categorization
18
- - Integration with monitoring and alerting systems
19
- """
20
-
21
- import asyncio
22
- import logging
23
- import threading
24
- import time
25
- import weakref
26
- from typing import Dict, List, Optional, Any, Callable, Set, Union, TypeVar, Generic
27
- from datetime import datetime, timezone, timedelta
28
- from collections import defaultdict, deque
29
- from dataclasses import dataclass, field
30
- from contextlib import asynccontextmanager, contextmanager
31
- from enum import Enum
32
- import uuid
33
-
34
- # Core SDK components
35
- from unrealon_sdk.src.core.config import AdapterConfig
36
- from unrealon_sdk.src.utils import generate_correlation_id
37
-
38
- # DTO models
39
- from unrealon_sdk.src.dto.logging import SDKEventType, SDKSeverity
40
- from unrealon_sdk.src.dto.concurrency import (
41
- ResourceType,
42
- ResourceStatus,
43
- ConcurrencyEventType,
44
- ResourcePool as ResourcePoolDTO,
45
- ConcurrencyMetrics,
46
- )
47
- from unrealon_sdk.src.dto.resource_pooling import (
48
- ResourceLifecycleState,
49
- PoolScalingStrategy,
50
- ResourceMetadata,
51
- PoolConfig,
52
- )
53
-
54
- # Development logging
55
- from typing import TYPE_CHECKING
56
-
57
- if TYPE_CHECKING:
58
- from unrealon_sdk.src.enterprise.logging import DevelopmentLogger
59
-
60
- logger = logging.getLogger(__name__)
61
-
62
- T = TypeVar("T")
63
-
64
-
65
- class ManagedResource(Generic[T]):
66
- """Wrapper for managed resources with metadata."""
67
-
68
- def __init__(
69
- self,
70
- resource: T,
71
- metadata: ResourceMetadata,
72
- validator: Optional[Callable[[T], bool]] = None,
73
- cleanup_func: Optional[Callable[[T], None]] = None,
74
- ):
75
- self.resource = resource
76
- self.metadata = metadata
77
- self._validator = validator
78
- self._cleanup_func = cleanup_func
79
- self._in_use = False
80
- self._acquired_at: Optional[datetime] = None
81
- self._acquired_by: Optional[str] = None
82
-
83
- def acquire(self, client_id: str) -> T:
84
- """Acquire resource for use."""
85
- if self._in_use:
86
- raise RuntimeError(f"Resource {self.metadata.resource_id} is already in use")
87
-
88
- self._in_use = True
89
- self._acquired_at = datetime.now(timezone.utc)
90
- self._acquired_by = client_id
91
- self.metadata.last_used = self._acquired_at
92
- self.metadata.usage_count += 1
93
- self.metadata.lifecycle_state = ResourceLifecycleState.IN_USE
94
-
95
- return self.resource
96
-
97
- def release(self) -> None:
98
- """Release resource back to pool."""
99
- self._in_use = False
100
- self._acquired_at = None
101
- self._acquired_by = None
102
- self.metadata.lifecycle_state = ResourceLifecycleState.IDLE
103
-
104
- def is_valid(self) -> bool:
105
- """Check if resource is valid."""
106
- if self._validator:
107
- try:
108
- return self._validator(self.resource)
109
- except Exception as e:
110
- self.metadata.error_count += 1
111
- self.metadata.last_error = str(e)
112
- return False
113
- return True
114
-
115
- def cleanup(self) -> None:
116
- """Cleanup resource."""
117
- if self._cleanup_func:
118
- try:
119
- self._cleanup_func(self.resource)
120
- except Exception as e:
121
- logger.error(f"Error cleaning up resource {self.metadata.resource_id}: {e}")
122
-
123
- self.metadata.lifecycle_state = ResourceLifecycleState.DESTROYED
124
-
125
- @property
126
- def is_in_use(self) -> bool:
127
- """Check if resource is currently in use."""
128
- return self._in_use
129
-
130
- @property
131
- def acquired_duration(self) -> Optional[timedelta]:
132
- """Get how long resource has been acquired."""
133
- if self._acquired_at:
134
- return datetime.now(timezone.utc) - self._acquired_at
135
- return None
136
-
137
-
138
- class ResourcePoolManager:
139
- """
140
- Enterprise-grade resource pool manager.
141
-
142
- Manages multiple resource pools with intelligent lifecycle management,
143
- health monitoring, and performance optimization.
144
- """
145
-
146
- def __init__(
147
- self,
148
- config: AdapterConfig,
149
- dev_logger: Optional["DevelopmentLogger"] = None,
150
- ):
151
- """Initialize resource pool manager."""
152
- self.config = config
153
- self.dev_logger = dev_logger
154
-
155
- # Pool management
156
- self._pools: Dict[str, "ResourcePoolInstance"] = {}
157
- self._pool_configs: Dict[str, PoolConfig] = {}
158
-
159
- # Resource factories
160
- self._resource_factories: Dict[str, Callable[[], Any]] = {}
161
- self._resource_validators: Dict[str, Callable[[Any], bool]] = {}
162
- self._resource_cleanup_funcs: Dict[str, Callable[[Any], None]] = {}
163
-
164
- # Global metrics
165
- self._global_metrics = ConcurrencyMetrics()
166
-
167
- # Background tasks
168
- self._monitor_task: Optional[asyncio.Task[None]] = None
169
- self._cleanup_task: Optional[asyncio.Task[None]] = None
170
- self._scaling_task: Optional[asyncio.Task[None]] = None
171
- self._shutdown = False
172
-
173
- # Thread safety
174
- self._lock = threading.RLock()
175
-
176
- self._log_info("Resource pool manager initialized")
177
-
178
- async def start(self) -> None:
179
- """Start resource pool manager."""
180
- # Start background tasks
181
- if self._monitor_task is None:
182
- self._monitor_task = asyncio.create_task(self._monitoring_loop())
183
-
184
- if self._cleanup_task is None:
185
- self._cleanup_task = asyncio.create_task(self._cleanup_loop())
186
-
187
- if self._scaling_task is None:
188
- self._scaling_task = asyncio.create_task(self._scaling_loop())
189
-
190
- self._log_info("Resource pool manager started")
191
-
192
- async def stop(self) -> None:
193
- """Stop resource pool manager and cleanup all pools."""
194
- self._shutdown = True
195
-
196
- # Cancel background tasks
197
- for task in [self._monitor_task, self._cleanup_task, self._scaling_task]:
198
- if task:
199
- task.cancel()
200
- try:
201
- await task
202
- except asyncio.CancelledError:
203
- pass
204
-
205
- # Shutdown all pools
206
- for pool_name, pool in list(self._pools.items()):
207
- await pool.shutdown()
208
-
209
- self._log_info("Resource pool manager stopped")
210
-
211
- def create_pool(
212
- self,
213
- pool_config: PoolConfig,
214
- resource_factory: Callable[[], T],
215
- validator: Optional[Callable[[T], bool]] = None,
216
- cleanup_func: Optional[Callable[[T], None]] = None,
217
- ) -> None:
218
- """Create new resource pool."""
219
-
220
- with self._lock:
221
- if pool_config.pool_name in self._pools:
222
- raise ValueError(f"Pool '{pool_config.pool_name}' already exists")
223
-
224
- # Store configuration and factories
225
- self._pool_configs[pool_config.pool_name] = pool_config
226
- self._resource_factories[pool_config.pool_name] = resource_factory
227
- if validator:
228
- self._resource_validators[pool_config.pool_name] = validator
229
- if cleanup_func:
230
- self._resource_cleanup_funcs[pool_config.pool_name] = cleanup_func
231
-
232
- # Create pool instance
233
- pool = ResourcePoolInstance(
234
- config=pool_config,
235
- resource_factory=resource_factory,
236
- validator=validator,
237
- cleanup_func=cleanup_func,
238
- dev_logger=self.dev_logger,
239
- )
240
-
241
- self._pools[pool_config.pool_name] = pool
242
-
243
- # Initialize pool
244
- asyncio.create_task(pool.initialize())
245
-
246
- self._log_info(
247
- f"Created resource pool '{pool_config.pool_name}' for {pool_config.resource_type.value}"
248
- )
249
-
250
- @asynccontextmanager
251
- async def acquire_resource(
252
- self,
253
- pool_name: str,
254
- timeout_seconds: Optional[float] = None,
255
- client_id: Optional[str] = None,
256
- ):
257
- """Acquire resource from pool with context manager."""
258
-
259
- if pool_name not in self._pools:
260
- raise ValueError(f"Pool '{pool_name}' does not exist")
261
-
262
- pool = self._pools[pool_name]
263
- client_id = client_id or generate_correlation_id()
264
-
265
- # Acquire resource
266
- managed_resource = await pool.acquire_resource(client_id, timeout_seconds)
267
-
268
- try:
269
- yield managed_resource.resource
270
- finally:
271
- # Always return resource to pool
272
- await pool.return_resource(managed_resource)
273
-
274
- async def get_pool_status(self, pool_name: str) -> Optional[ResourcePoolDTO]:
275
- """Get pool status information."""
276
- if pool_name not in self._pools:
277
- return None
278
-
279
- pool = self._pools[pool_name]
280
- return await pool.get_status()
281
-
282
- async def get_all_pools_status(self) -> List[ResourcePoolDTO]:
283
- """Get status for all pools."""
284
- statuses = []
285
- for pool in self._pools.values():
286
- status = await pool.get_status()
287
- statuses.append(status)
288
- return statuses
289
-
290
- def get_global_metrics(self) -> ConcurrencyMetrics:
291
- """Get global resource pool metrics."""
292
- return self._global_metrics.model_copy()
293
-
294
- async def _monitoring_loop(self) -> None:
295
- """Background monitoring loop."""
296
- while not self._shutdown:
297
- try:
298
- await asyncio.sleep(30) # Monitor every 30 seconds
299
- await self._collect_global_metrics()
300
- await self._check_pool_health()
301
- except asyncio.CancelledError:
302
- break
303
- except Exception as e:
304
- logger.error(f"Error in resource pool monitoring: {e}")
305
-
306
- async def _cleanup_loop(self) -> None:
307
- """Background cleanup loop."""
308
- while not self._shutdown:
309
- try:
310
- await asyncio.sleep(60) # Cleanup every minute
311
- await self._cleanup_pools()
312
- except asyncio.CancelledError:
313
- break
314
- except Exception as e:
315
- logger.error(f"Error in resource pool cleanup: {e}")
316
-
317
- async def _scaling_loop(self) -> None:
318
- """Background scaling loop."""
319
- while not self._shutdown:
320
- try:
321
- await asyncio.sleep(45) # Scale every 45 seconds
322
- await self._auto_scale_pools()
323
- except asyncio.CancelledError:
324
- break
325
- except Exception as e:
326
- logger.error(f"Error in resource pool scaling: {e}")
327
-
328
- async def _collect_global_metrics(self) -> None:
329
- """Collect global metrics from all pools."""
330
- total_resources = 0
331
- available_resources = 0
332
-
333
- for pool in self._pools.values():
334
- status = await pool.get_status()
335
- total_resources += status.current_size
336
- available_resources += status.available_resources
337
-
338
- # Update global metrics
339
- self._global_metrics.total_resources = total_resources
340
- self._global_metrics.available_resources = available_resources
341
-
342
- if total_resources > 0:
343
- self._global_metrics.resource_utilization_percent = (
344
- (total_resources - available_resources) / total_resources * 100
345
- )
346
-
347
- async def _check_pool_health(self) -> None:
348
- """Check health of all pools."""
349
- for pool_name, pool in self._pools.items():
350
- try:
351
- await pool.health_check()
352
- except Exception as e:
353
- logger.error(f"Health check failed for pool '{pool_name}': {e}")
354
-
355
- async def _cleanup_pools(self) -> None:
356
- """Cleanup all pools."""
357
- for pool in self._pools.values():
358
- await pool.cleanup()
359
-
360
- async def _auto_scale_pools(self) -> None:
361
- """Auto-scale all pools based on their configurations."""
362
- for pool in self._pools.values():
363
- await pool.auto_scale()
364
-
365
- def _log_info(self, message: str, **kwargs: Any) -> None:
366
- """Log info message."""
367
- if self.dev_logger:
368
- self.dev_logger.log_info(
369
- SDKEventType.PERFORMANCE_OPTIMIZATION_APPLIED, message, **kwargs
370
- )
371
- else:
372
- logger.info(message)
373
-
374
-
375
- class ResourcePoolInstance(Generic[T]):
376
- """Individual resource pool instance."""
377
-
378
- def __init__(
379
- self,
380
- config: PoolConfig,
381
- resource_factory: Callable[[], T],
382
- validator: Optional[Callable[[T], bool]] = None,
383
- cleanup_func: Optional[Callable[[T], None]] = None,
384
- dev_logger: Optional["DevelopmentLogger"] = None,
385
- ):
386
- self.config = config
387
- self._resource_factory = resource_factory
388
- self._validator = validator
389
- self._cleanup_func = cleanup_func
390
- self.dev_logger = dev_logger
391
-
392
- # Resource storage
393
- self._resources: Dict[str, ManagedResource[T]] = {}
394
- self._available: deque[str] = deque()
395
- self._in_use: Set[str] = set()
396
-
397
- # Acquisition queue
398
- self._acquisition_queue: deque[asyncio.Future] = deque()
399
-
400
- # Metrics
401
- self._metrics = ResourcePoolDTO(
402
- pool_id=config.pool_name,
403
- pool_name=config.pool_name,
404
- resource_type=config.resource_type,
405
- min_size=config.min_size,
406
- max_size=config.max_size,
407
- )
408
-
409
- # Performance tracking
410
- self._acquisition_times: deque[float] = deque(maxlen=100)
411
- self._last_scale_time: Optional[datetime] = None
412
-
413
- # Thread safety
414
- self._lock = asyncio.Lock()
415
-
416
- # Initialization state
417
- self._initialized = False
418
-
419
- async def initialize(self) -> None:
420
- """Initialize pool with initial resources."""
421
- async with self._lock:
422
- if self._initialized:
423
- return
424
-
425
- # Create initial resources
426
- for i in range(self.config.initial_size):
427
- try:
428
- resource_id = await self._create_resource()
429
- if resource_id:
430
- self._available.append(resource_id)
431
- except Exception as e:
432
- logger.error(f"Failed to create initial resource {i}: {e}")
433
-
434
- # Warmup if enabled
435
- if self.config.enable_warmup:
436
- await self._warmup_pool()
437
-
438
- self._initialized = True
439
- self._update_metrics()
440
-
441
- async def acquire_resource(
442
- self,
443
- client_id: str,
444
- timeout_seconds: Optional[float] = None,
445
- ) -> ManagedResource[T]:
446
- """Acquire resource from pool."""
447
-
448
- timeout_seconds = timeout_seconds or self.config.acquisition_timeout_seconds
449
- start_time = time.time()
450
-
451
- try:
452
- # Try to get available resource
453
- async with asyncio.wait_for(self._lock, timeout=timeout_seconds):
454
-
455
- # Check for available resources
456
- while self._available:
457
- resource_id = self._available.popleft()
458
- managed_resource = self._resources[resource_id]
459
-
460
- # Validate resource if configured
461
- if self.config.validation_on_acquire and not managed_resource.is_valid():
462
- await self._destroy_resource(resource_id)
463
- continue
464
-
465
- # Acquire resource
466
- managed_resource.acquire(client_id)
467
- self._in_use.add(resource_id)
468
-
469
- # Track acquisition time
470
- acquisition_time = (time.time() - start_time) * 1000
471
- self._acquisition_times.append(acquisition_time)
472
-
473
- self._update_metrics()
474
- return managed_resource
475
-
476
- # No available resources, try to create new one
477
- if len(self._resources) < self.config.max_size:
478
- resource_id = await self._create_resource()
479
- if resource_id:
480
- managed_resource = self._resources[resource_id]
481
- managed_resource.acquire(client_id)
482
- self._in_use.add(resource_id)
483
-
484
- acquisition_time = (time.time() - start_time) * 1000
485
- self._acquisition_times.append(acquisition_time)
486
-
487
- self._update_metrics()
488
- return managed_resource
489
-
490
- # Pool exhausted, add to queue
491
- future = asyncio.Future()
492
- self._acquisition_queue.append(future)
493
-
494
- # Wait for resource to become available
495
- try:
496
- managed_resource = await asyncio.wait_for(future, timeout=timeout_seconds)
497
- managed_resource.acquire(client_id)
498
-
499
- acquisition_time = (time.time() - start_time) * 1000
500
- self._acquisition_times.append(acquisition_time)
501
-
502
- return managed_resource
503
-
504
- except asyncio.TimeoutError:
505
- # Remove from queue if still there
506
- try:
507
- self._acquisition_queue.remove(future)
508
- except ValueError:
509
- pass
510
- raise
511
-
512
- except asyncio.TimeoutError:
513
- self._metrics.failed_acquisitions += 1
514
- raise RuntimeError(
515
- f"Failed to acquire resource from pool '{self.config.pool_name}' within {timeout_seconds}s"
516
- )
517
-
518
- async def return_resource(self, managed_resource: ManagedResource[T]) -> None:
519
- """Return resource to pool."""
520
-
521
- async with self._lock:
522
- resource_id = managed_resource.metadata.resource_id
523
-
524
- if resource_id not in self._resources:
525
- return # Resource was already destroyed
526
-
527
- # Validate resource if configured
528
- if self.config.validation_on_return and not managed_resource.is_valid():
529
- await self._destroy_resource(resource_id)
530
- return
531
-
532
- # Release resource
533
- managed_resource.release()
534
- self._in_use.discard(resource_id)
535
-
536
- # Check if someone is waiting
537
- if self._acquisition_queue:
538
- future = self._acquisition_queue.popleft()
539
- if not future.cancelled():
540
- future.set_result(managed_resource)
541
- return
542
-
543
- # Return to available pool
544
- self._available.append(resource_id)
545
- self._update_metrics()
546
-
547
- async def _create_resource(self) -> Optional[str]:
548
- """Create new resource."""
549
- try:
550
- # Create resource using factory
551
- resource = self._resource_factory()
552
- resource_id = str(uuid.uuid4())
553
-
554
- # Create metadata
555
- metadata = ResourceMetadata(
556
- resource_id=resource_id,
557
- resource_type=self.config.resource_type,
558
- created_at=datetime.now(timezone.utc),
559
- last_used=datetime.now(timezone.utc),
560
- lifecycle_state=ResourceLifecycleState.READY,
561
- )
562
-
563
- # Create managed resource
564
- managed_resource = ManagedResource(
565
- resource=resource,
566
- metadata=metadata,
567
- validator=self._validator,
568
- cleanup_func=self._cleanup_func,
569
- )
570
-
571
- self._resources[resource_id] = managed_resource
572
- return resource_id
573
-
574
- except Exception as e:
575
- logger.error(f"Failed to create resource: {e}")
576
- return None
577
-
578
- async def _destroy_resource(self, resource_id: str) -> None:
579
- """Destroy resource and clean up."""
580
- if resource_id in self._resources:
581
- managed_resource = self._resources[resource_id]
582
-
583
- # Clean up resource
584
- try:
585
- managed_resource.cleanup()
586
- except Exception as e:
587
- logger.error(f"Error during resource cleanup: {e}")
588
-
589
- # Remove from all collections
590
- del self._resources[resource_id]
591
- self._in_use.discard(resource_id)
592
-
593
- # Remove from available queue if present
594
- try:
595
- self._available.remove(resource_id)
596
- except ValueError:
597
- pass
598
-
599
- async def _warmup_pool(self) -> None:
600
- """Warm up pool by pre-creating resources."""
601
- warmup_count = min(self.config.warmup_size, self.config.max_size - len(self._resources))
602
-
603
- for _ in range(warmup_count):
604
- resource_id = await self._create_resource()
605
- if resource_id:
606
- self._available.append(resource_id)
607
-
608
- async def health_check(self) -> None:
609
- """Perform health check on pool resources."""
610
- if not self.config.enable_health_checks:
611
- return
612
-
613
- unhealthy_resources = []
614
-
615
- async with self._lock:
616
- for resource_id, managed_resource in self._resources.items():
617
- if resource_id not in self._in_use: # Only check idle resources
618
- if not managed_resource.is_valid():
619
- unhealthy_resources.append(resource_id)
620
-
621
- # Remove unhealthy resources
622
- for resource_id in unhealthy_resources:
623
- await self._destroy_resource(resource_id)
624
-
625
- if unhealthy_resources:
626
- logger.info(
627
- f"Removed {len(unhealthy_resources)} unhealthy resources from pool '{self.config.pool_name}'"
628
- )
629
-
630
- async def auto_scale(self) -> None:
631
- """Auto-scale pool based on configuration."""
632
- if self.config.scaling_strategy == PoolScalingStrategy.FIXED:
633
- return
634
-
635
- async with self._lock:
636
- current_size = len(self._resources)
637
- available_count = len(self._available)
638
- in_use_count = len(self._in_use)
639
-
640
- utilization = in_use_count / current_size if current_size > 0 else 0.0
641
-
642
- # Check if scaling is needed
643
- should_scale_up = (
644
- utilization > self.config.scale_up_threshold
645
- and current_size < self.config.max_size
646
- and available_count == 0
647
- )
648
-
649
- should_scale_down = (
650
- utilization < self.config.scale_down_threshold
651
- and current_size > self.config.min_size
652
- and available_count > (current_size * 0.5) # More than 50% are idle
653
- )
654
-
655
- # Scale up
656
- if should_scale_up:
657
- new_size = min(int(current_size * self.config.scale_factor), self.config.max_size)
658
- resources_to_add = new_size - current_size
659
-
660
- for _ in range(resources_to_add):
661
- resource_id = await self._create_resource()
662
- if resource_id:
663
- self._available.append(resource_id)
664
-
665
- self._last_scale_time = datetime.now(timezone.utc)
666
- logger.info(
667
- f"Scaled up pool '{self.config.pool_name}' from {current_size} to {len(self._resources)}"
668
- )
669
-
670
- # Scale down
671
- elif should_scale_down:
672
- new_size = max(int(current_size / self.config.scale_factor), self.config.min_size)
673
- resources_to_remove = current_size - new_size
674
-
675
- # Remove only idle resources
676
- removed_count = 0
677
- while removed_count < resources_to_remove and self._available:
678
- resource_id = self._available.popleft()
679
- await self._destroy_resource(resource_id)
680
- removed_count += 1
681
-
682
- if removed_count > 0:
683
- self._last_scale_time = datetime.now(timezone.utc)
684
- logger.info(
685
- f"Scaled down pool '{self.config.pool_name}' by {removed_count} resources"
686
- )
687
-
688
- async def cleanup(self) -> None:
689
- """Cleanup idle and expired resources."""
690
- expired_resources = []
691
-
692
- async with self._lock:
693
- current_time = datetime.now(timezone.utc)
694
-
695
- for resource_id, managed_resource in self._resources.items():
696
- if resource_id not in self._in_use: # Only cleanup idle resources
697
- metadata = managed_resource.metadata
698
-
699
- # Check idle timeout
700
- idle_time = (current_time - metadata.last_used).total_seconds()
701
- if idle_time > self.config.idle_timeout_seconds:
702
- expired_resources.append(resource_id)
703
-
704
- # Check max lifetime
705
- elif (
706
- self.config.max_lifetime_seconds
707
- and (current_time - metadata.created_at).total_seconds()
708
- > self.config.max_lifetime_seconds
709
- ):
710
- expired_resources.append(resource_id)
711
-
712
- # Remove expired resources
713
- for resource_id in expired_resources:
714
- await self._destroy_resource(resource_id)
715
-
716
- if expired_resources:
717
- logger.info(
718
- f"Cleaned up {len(expired_resources)} expired resources from pool '{self.config.pool_name}'"
719
- )
720
-
721
- async def get_status(self) -> ResourcePoolDTO:
722
- """Get current pool status."""
723
- self._update_metrics()
724
- return self._metrics.model_copy()
725
-
726
- async def shutdown(self) -> None:
727
- """Shutdown pool and cleanup all resources."""
728
- async with self._lock:
729
- # Cancel all waiting acquisitions
730
- while self._acquisition_queue:
731
- future = self._acquisition_queue.popleft()
732
- if not future.cancelled():
733
- future.cancel()
734
-
735
- # Destroy all resources
736
- for resource_id in list(self._resources.keys()):
737
- await self._destroy_resource(resource_id)
738
-
739
- self._available.clear()
740
- self._in_use.clear()
741
-
742
- def _update_metrics(self) -> None:
743
- """Update pool metrics."""
744
- self._metrics.current_size = len(self._resources)
745
- self._metrics.available_resources = len(self._available)
746
- self._metrics.in_use_resources = len(self._in_use)
747
- self._metrics.total_requests += 1
748
-
749
- if self._acquisition_times:
750
- self._metrics.avg_acquisition_time_ms = sum(self._acquisition_times) / len(
751
- self._acquisition_times
752
- )
753
-
754
-
755
- __all__ = [
756
- # Main classes
757
- "ResourcePoolManager",
758
- "ResourcePoolInstance",
759
- "ManagedResource",
760
- # Note: Resource pooling models are available via DTO imports:
761
- # from unrealon_sdk.src.dto.resource_pooling import ...
762
- # from unrealon_sdk.src.dto.concurrency import ...
763
- ]