Spaces:
Running
Running
Update main.py
Browse files
main.py
CHANGED
|
@@ -127,6 +127,9 @@ def health():
|
|
| 127 |
# Global engine instances to save memory and improve performance
|
| 128 |
_GLOBAL_DEEPCASTLE_ENGINE = None
|
| 129 |
_ENGINE_LOCK = asyncio.Lock()
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
|
| 132 |
def _engine_hash_mb() -> int:
|
|
@@ -243,10 +246,11 @@ async def get_move(request: MoveRequest):
|
|
| 243 |
limit = chess.engine.Limit(time=request.time, depth=request.depth)
|
| 244 |
|
| 245 |
# One search: stats must come from this run (not a separate short analyse).
|
| 246 |
-
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
|
|
|
|
| 250 |
|
| 251 |
# From White's perspective in CP -> converted to Pawns for UI
|
| 252 |
score_cp, mate_in = get_normalized_score(info)
|
|
@@ -294,10 +298,11 @@ async def get_analysis_move(request: MoveRequest):
|
|
| 294 |
board = chess.Board(request.fen)
|
| 295 |
limit = chess.engine.Limit(time=request.time, depth=request.depth)
|
| 296 |
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
|
|
|
| 301 |
|
| 302 |
score_cp, mate_in = get_normalized_score(info)
|
| 303 |
|
|
@@ -487,7 +492,8 @@ async def analyze_game(request: AnalyzeRequest):
|
|
| 487 |
|
| 488 |
analysis_results = []
|
| 489 |
|
| 490 |
-
|
|
|
|
| 491 |
infos_before = infos_before if isinstance(infos_before, list) else [infos_before]
|
| 492 |
|
| 493 |
counts = {
|
|
@@ -535,7 +541,8 @@ async def analyze_game(request: AnalyzeRequest):
|
|
| 535 |
move_history.append(move)
|
| 536 |
fen_history.append(board.fen())
|
| 537 |
|
| 538 |
-
|
|
|
|
| 539 |
infos_after: List[dict] = infos_after_raw if isinstance(infos_after_raw, list) else [infos_after_raw]
|
| 540 |
|
| 541 |
info_after_dict: dict = infos_after[0]
|
|
|
|
| 127 |
# Global engine instances to save memory and improve performance
|
| 128 |
_GLOBAL_DEEPCASTLE_ENGINE = None
|
| 129 |
_ENGINE_LOCK = asyncio.Lock()
|
| 130 |
+
# UCI engines handle one search at a time; concurrent play/analyse on the same process
|
| 131 |
+
# corrupts the protocol and can crash the binary — serialize all I/O.
|
| 132 |
+
_ENGINE_IO_LOCK = asyncio.Lock()
|
| 133 |
|
| 134 |
|
| 135 |
def _engine_hash_mb() -> int:
|
|
|
|
| 246 |
limit = chess.engine.Limit(time=request.time, depth=request.depth)
|
| 247 |
|
| 248 |
# One search: stats must come from this run (not a separate short analyse).
|
| 249 |
+
async with _ENGINE_IO_LOCK:
|
| 250 |
+
result = await engine.play(board, limit, info=chess.engine.INFO_ALL)
|
| 251 |
+
info = dict(result.info)
|
| 252 |
+
if not info:
|
| 253 |
+
info = await engine.analyse(board, limit, info=chess.engine.INFO_ALL)
|
| 254 |
|
| 255 |
# From White's perspective in CP -> converted to Pawns for UI
|
| 256 |
score_cp, mate_in = get_normalized_score(info)
|
|
|
|
| 298 |
board = chess.Board(request.fen)
|
| 299 |
limit = chess.engine.Limit(time=request.time, depth=request.depth)
|
| 300 |
|
| 301 |
+
async with _ENGINE_IO_LOCK:
|
| 302 |
+
result = await engine.play(board, limit, info=chess.engine.INFO_ALL)
|
| 303 |
+
info = dict(result.info)
|
| 304 |
+
if not info:
|
| 305 |
+
info = await engine.analyse(board, limit, info=chess.engine.INFO_ALL)
|
| 306 |
|
| 307 |
score_cp, mate_in = get_normalized_score(info)
|
| 308 |
|
|
|
|
| 492 |
|
| 493 |
analysis_results = []
|
| 494 |
|
| 495 |
+
async with _ENGINE_IO_LOCK:
|
| 496 |
+
infos_before = await engine.analyse(board, limit, multipv=2)
|
| 497 |
infos_before = infos_before if isinstance(infos_before, list) else [infos_before]
|
| 498 |
|
| 499 |
counts = {
|
|
|
|
| 541 |
move_history.append(move)
|
| 542 |
fen_history.append(board.fen())
|
| 543 |
|
| 544 |
+
async with _ENGINE_IO_LOCK:
|
| 545 |
+
infos_after_raw = await engine.analyse(board, limit, multipv=2)
|
| 546 |
infos_after: List[dict] = infos_after_raw if isinstance(infos_after_raw, list) else [infos_after_raw]
|
| 547 |
|
| 548 |
info_after_dict: dict = infos_after[0]
|