Полировка: писать одну запись напрямую — убран вечный завис в join()
Редкая гонка spawn+mp.Queue вешала главный процесс НАВЕЧНО после полировки (22.5 часа простоя; /proc/*/stack: главный в do_wait, polish-писатель в pipe_read — данные из очереди не доехали). Для одной записи процесс-писатель и очередь не нужны вовсе: конкурентных писателей в этот момент нет, пишем insert_run'ом напрямую. Плюс возврат SIGTERM к SIG_DFL после дренажа — иначе фаза полировки неубиваема мягко. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,7 +22,7 @@ from gausse.optim import worker_context
|
|||||||
from gausse.optim.objective import EvaluationResult, build_run_record, evaluate
|
from gausse.optim.objective import EvaluationResult, build_run_record, evaluate
|
||||||
from gausse.optim.progress_log import ProgressLogger, default_log_path
|
from gausse.optim.progress_log import ProgressLogger, default_log_path
|
||||||
from gausse.optim.search_space import Genome, SearchBounds, crossover, mutate, repair, sample_genome
|
from gausse.optim.search_space import Genome, SearchBounds, crossover, mutate, repair, sample_genome
|
||||||
from gausse.storage.database import run_writer_process
|
from gausse.storage.database import insert_run, open_connection, run_writer_process
|
||||||
from gausse.storage.schema import RunRecord
|
from gausse.storage.schema import RunRecord
|
||||||
|
|
||||||
|
|
||||||
@@ -204,6 +204,9 @@ def run_evolution(
|
|||||||
# «Exception ignored … sem_unlink FileNotFoundError» после каждого цикла
|
# «Exception ignored … sem_unlink FileNotFoundError» после каждого цикла
|
||||||
queue.close()
|
queue.close()
|
||||||
queue.join_thread()
|
queue.join_thread()
|
||||||
|
# после дренажа возвращаем обработку SIGTERM по умолчанию: иначе
|
||||||
|
# процесс в фазе полировки нельзя остановить мягко (только SIGKILL)
|
||||||
|
signal.signal(signal.SIGTERM, signal.SIG_DFL)
|
||||||
logger._write("база дописана полностью")
|
logger._write("база дописана полностью")
|
||||||
|
|
||||||
assert best_pair is not None
|
assert best_pair is not None
|
||||||
@@ -214,14 +217,17 @@ def run_evolution(
|
|||||||
polished_genome, polished_result = polish_best(best_genome, db, bounds)
|
polished_genome, polished_result = polish_best(best_genome, db, bounds)
|
||||||
logger._write(f"полировка готова: КПД {best_result.fitness*100:.2f}% -> {polished_result.fitness*100:.2f}%")
|
logger._write(f"полировка готова: КПД {best_result.fitness*100:.2f}% -> {polished_result.fitness*100:.2f}%")
|
||||||
if polished_result.fitness > best_result.fitness:
|
if polished_result.fitness > best_result.fitness:
|
||||||
conn_queue = ctx.Queue()
|
# ОДНУ запись пишем напрямую, без процесса-писателя и очереди:
|
||||||
polish_writer = ctx.Process(target=run_writer_process, args=(conn_queue, db_path))
|
# конкурентных писателей в этот момент нет (основной уже завершён),
|
||||||
polish_writer.start()
|
# а редкая гонка spawn+Queue вешала главный процесс в join()
|
||||||
conn_queue.put(build_run_record(polished_genome, polished_result, db, search_mode="evolve-polish"))
|
# НАВЕЧНО (22.5 часа простоя, пойман по /proc/*/stack: главный в
|
||||||
conn_queue.put(None)
|
# do_wait, писатель в pipe_read — данные из очереди не доехали).
|
||||||
polish_writer.join()
|
conn = open_connection(db_path)
|
||||||
conn_queue.close()
|
try:
|
||||||
conn_queue.join_thread()
|
insert_run(conn, build_run_record(polished_genome, polished_result, db, search_mode="evolve-polish"))
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
logger._write("полированный геном записан в базу")
|
||||||
best_genome, best_result = polished_genome, polished_result
|
best_genome, best_result = polished_genome, polished_result
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user