Skip to content

Commit 3be2d99

Browse files
Remove the everserver status file (#12115)
1 parent eae89c6 commit 3be2d99

12 files changed

Lines changed: 51 additions & 320 deletions

File tree

src/ert/dark_storage/endpoints/experiment_server.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ def __init__(
297297

298298
async def run(self) -> None:
299299
status_queue: SimpleQueue[StatusEvents] = SimpleQueue()
300+
run_model: EverestRunModel | None = None
300301
try:
301302
with ErtPluginContext() as runtime_plugins:
302303
run_model = EverestRunModel.create(
@@ -356,6 +357,9 @@ async def run(self) -> None:
356357
status=ExperimentState.failed,
357358
)
358359
finally:
360+
if run_model and run_model._experiment:
361+
run_model._experiment.status = shared_data.status
362+
359363
logging.getLogger(EXPERIMENT_SERVER).info(
360364
f"ExperimentRunner done. Items left in queue: {status_queue.qsize()}"
361365
)

src/everest/bin/monitor_script.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from pathlib import Path
88

99
from ert.services import StorageService
10+
from ert.storage import ExperimentState
1011
from everest.config import EverestConfig, ServerConfig
11-
from everest.detached import ExperimentState
1212
from everest.everest_storage import EverestStorage
1313

1414
from .utils import (

src/everest/config/server_config.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
CERTIFICATE_DIR,
1919
DETACHED_NODE_DIR,
2020
HOSTFILE_NAME,
21-
SERVER_STATUS,
2221
SESSION_DIR,
2322
)
2423
from .simulator_config import check_removed_config
@@ -130,11 +129,6 @@ def get_session_dir(output_dir: str) -> str:
130129
certificates and host information"""
131130
return os.path.join(ServerConfig.get_detached_node_dir(output_dir), SESSION_DIR)
132131

133-
@staticmethod
134-
def get_everserver_status_path(output_dir: str) -> str:
135-
"""Returns path to the everest server status file"""
136-
return os.path.join(ServerConfig.get_session_dir(output_dir), SERVER_STATUS)
137-
138132
@staticmethod
139133
def get_certificate_dir(output_dir: str) -> str:
140134
"""Return the path to certificate folder"""

src/everest/detached/__init__.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,22 @@
44

55
from .client import (
66
PROXY,
7-
ExperimentState,
8-
everserver_status,
97
server_is_running,
108
start_experiment,
119
start_monitor,
1210
start_server,
1311
stop_server,
14-
update_everserver_status,
1512
wait_for_server,
1613
wait_for_server_to_stop,
1714
)
1815

1916
__all__ = [
2017
"PROXY",
21-
"ExperimentState",
22-
"everserver_status",
2318
"server_is_running",
2419
"start_experiment",
2520
"start_monitor",
2621
"start_server",
2722
"stop_server",
28-
"update_everserver_status",
2923
"wait_for_server",
3024
"wait_for_server_to_stop",
3125
]

src/everest/detached/client.py

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import asyncio
2-
import json
32
import logging
4-
import os
53
import re
64
import ssl
75
import time
@@ -21,7 +19,6 @@
2119
from ert.scheduler import create_driver
2220
from ert.scheduler.driver import Driver, FailedSubmit
2321
from ert.scheduler.event import StartedEvent
24-
from ert.storage import ExperimentState
2522
from ert.trace import get_traceparent
2623
from everest.config import EverestConfig, ServerConfig
2724
from everest.strings import (
@@ -261,40 +258,3 @@ def start_monitor(
261258

262259
except Exception:
263260
logger.exception(traceback.format_exc())
264-
265-
266-
def update_everserver_status(
267-
everserver_status_path: str, status: ExperimentState, message: str | None = None
268-
) -> None:
269-
"""Update the everest server status with new status information"""
270-
new_status = {"status": status, "message": message}
271-
path = everserver_status_path
272-
if not os.path.exists(os.path.dirname(path)):
273-
os.makedirs(os.path.dirname(path))
274-
Path(path).write_text(json.dumps(new_status), encoding="utf-8")
275-
elif os.path.exists(path):
276-
server_status = everserver_status(path)
277-
if server_status["message"] is not None:
278-
if message is not None:
279-
new_status["message"] = "{}\n{}".format(
280-
server_status["message"], message
281-
)
282-
else:
283-
new_status["message"] = server_status["message"]
284-
Path(path).write_text(json.dumps(new_status), encoding="utf-8")
285-
286-
287-
def everserver_status(everserver_status_path: str) -> dict[str, Any]:
288-
"""Returns a dictionary representing the everest server status. If the
289-
status file is not found we assume the server has never ran before, and will
290-
return a status of ServerStatus.never_run
291-
292-
Example: {
293-
'status': ServerStatus.completed
294-
'message': None
295-
}
296-
"""
297-
if os.path.exists(everserver_status_path):
298-
return json.loads(Path(everserver_status_path).read_text(encoding="utf-8"))
299-
else:
300-
return {"status": ExperimentState.never_run, "message": None}

src/everest/detached/everserver.py

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import os
55
import pathlib
66
import time
7-
import traceback
87
from pathlib import Path
98
from tempfile import NamedTemporaryFile
109
from typing import Any
@@ -16,13 +15,9 @@
1615
from ert.services import StorageService
1716
from ert.services._base_service import BaseServiceExit
1817
from ert.storage import ExperimentStatus
18+
from ert.storage.local_experiment import ExperimentState
1919
from ert.trace import tracer
2020
from everest.config import ServerConfig
21-
from everest.detached import (
22-
ExperimentState,
23-
everserver_status,
24-
update_everserver_status,
25-
)
2621
from everest.strings import (
2722
DEFAULT_LOGGING_FORMAT,
2823
EVEREST,
@@ -142,8 +137,6 @@ def main() -> None:
142137

143138
output_dir = options.output_dir
144139

145-
status_path = ServerConfig.get_everserver_status_path(output_dir)
146-
147140
ctx = (
148141
TraceContextTextMapPropagator().extract(
149142
carrier={"traceparent": options.traceparent}
@@ -165,7 +158,6 @@ def main() -> None:
165158
)
166159

167160
logging.getLogger(EVERSERVER).info("Everserver starting ...")
168-
update_everserver_status(status_path, ExperimentState.pending)
169161
logger.info(version_info())
170162
logger.info(f"Output directory: {output_dir}")
171163
# Starting the server
@@ -175,8 +167,7 @@ def main() -> None:
175167
timeout=240, project=server_path, logging_config=log_file.name
176168
) as server:
177169
server.fetch_conn_info()
178-
with StorageService.session(project=server_path) as client:
179-
update_everserver_status(status_path, ExperimentState.running)
170+
with StorageService.session(project=Path(server_path)) as client:
180171
done = False
181172
while not done:
182173
response = client.get(
@@ -188,33 +179,10 @@ def main() -> None:
188179
ExperimentState.running,
189180
}
190181
time.sleep(0.5)
191-
if status.status == ExperimentState.completed:
192-
update_everserver_status(
193-
status_path,
194-
ExperimentState.completed,
195-
message=status.message,
196-
)
197-
elif status.status == ExperimentState.stopped:
198-
update_everserver_status(
199-
status_path,
200-
ExperimentState.stopped,
201-
message=status.message,
202-
)
203-
elif status.status == ExperimentState.failed:
204-
update_everserver_status(
205-
status_path, ExperimentState.failed, message=status.message
206-
)
207182
except BaseServiceExit:
208183
# Server exit, happens on normal shutdown and keyboard interrupt
209-
server_status = everserver_status(status_path)
210-
if server_status["status"] == ExperimentState.running:
211-
update_everserver_status(status_path, ExperimentState.stopped)
184+
logging.getLogger(EVERSERVER).info("Everserver stopped by user")
212185
except Exception as e:
213-
update_everserver_status(
214-
status_path,
215-
ExperimentState.failed,
216-
message=traceback.format_exc(),
217-
)
218186
logging.getLogger(EVERSERVER).exception(e)
219187

220188

src/everest/strings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
OPT_FAILURE_ALL_REALIZATIONS = "Optimization failed: all realizations failed."
2424

2525
SESSION_DIR = ".session"
26-
SERVER_STATUS = "status"
2726
SIMULATION = "simulation"
2827
SIMULATOR_START = "start"
2928
SIMULATOR_UPDATE = "update"

tests/everest/entry_points/test_everest_entry.py

Lines changed: 4 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,11 @@
88
import everest
99
from ert.config import QueueSystem
1010
from ert.run_models.everest_run_model import ExperimentStatus
11+
from ert.storage import ExperimentState
1112
from everest.bin.everest_script import everest_entry
1213
from everest.bin.kill_script import kill_entry
1314
from everest.bin.monitor_script import monitor_entry
14-
from everest.config import EverestConfig, ServerConfig
15-
from everest.detached import (
16-
ExperimentState,
17-
everserver_status,
18-
update_everserver_status,
19-
)
15+
from everest.config import EverestConfig
2016
from tests.everest.utils import capture_streams
2117

2218
CONFIG_FILE_MINIMAL = "config_minimal.yml"
@@ -26,13 +22,6 @@ def raise_system_error(*args, **kwargs):
2622
raise SystemError("Reality was ripped to shreds!")
2723

2824

29-
def run_detached_monitor_mock(status=ExperimentState.completed, error=None, **kwargs):
30-
path = os.path.join(
31-
os.getcwd(), "everest_output/detached_node_output/.session/status"
32-
)
33-
update_everserver_status(path, status, message=error)
34-
35-
3625
@patch("everest.bin.everest_script.run_detached_monitor")
3726
@patch("everest.bin.everest_script.wait_for_server")
3827
@patch("everest.bin.everest_script.start_server")
@@ -281,7 +270,7 @@ def test_everest_entry_detached_running_monitor(
281270
def test_everest_entry_monitor_already_run(
282271
session_mock,
283272
get_server_context_from_conn_info_mock,
284-
everserver_status_mock,
273+
get_experiment_status_mock,
285274
start_monitor_mock,
286275
change_to_tmpdir,
287276
):
@@ -293,7 +282,7 @@ def test_everest_entry_monitor_already_run(
293282
monitor_entry(["config.yml"])
294283
assert "Optimization already completed." in out.getvalue()
295284
start_monitor_mock.assert_not_called()
296-
everserver_status_mock.assert_called()
285+
get_experiment_status_mock.assert_called()
297286
session_mock.assert_called_once()
298287
get_server_context_from_conn_info_mock.assert_not_called()
299288

@@ -352,66 +341,6 @@ def test_exception_raised_when_server_run_fails_monitor(
352341
monitor_entry(["config.yml"])
353342

354343

355-
@patch(
356-
"everest.bin.everest_script.run_detached_monitor",
357-
side_effect=run_detached_monitor_mock,
358-
)
359-
@patch("everest.bin.everest_script.wait_for_server")
360-
@patch("everest.bin.everest_script.start_server")
361-
@patch("everest.bin.everest_script.start_experiment")
362-
@patch(
363-
"ert.services.StorageService.session",
364-
side_effect=[TimeoutError(), MagicMock()],
365-
)
366-
@patch("everest.config.ServerConfig.get_server_context_from_conn_info")
367-
def test_complete_status_for_normal_run(
368-
get_server_context_from_conn_info_mock,
369-
session_mock,
370-
start_experiment_mock,
371-
start_server_mock,
372-
wait_for_server_mock,
373-
start_monitor_mock,
374-
change_to_tmpdir,
375-
):
376-
Path("config.yml").touch()
377-
config = EverestConfig.with_defaults(config_path="./config.yml")
378-
config.dump("config.yml")
379-
380-
everest_entry(["config.yml", "--skip-prompt"])
381-
status_path = ServerConfig.get_everserver_status_path(config.output_dir)
382-
status = everserver_status(status_path)
383-
expected_status = ExperimentState.completed
384-
expected_error = None
385-
386-
assert expected_status == status["status"]
387-
assert expected_error == status["message"]
388-
389-
390-
@patch(
391-
"everest.bin.monitor_script.run_detached_monitor",
392-
side_effect=run_detached_monitor_mock,
393-
)
394-
@patch("ert.services.StorageService.session")
395-
@patch("everest.config.ServerConfig.get_server_context_from_conn_info")
396-
def test_complete_status_for_normal_run_monitor(
397-
get_server_context_from_conn_info_mock,
398-
session_mock,
399-
start_monitor_mock,
400-
change_to_tmpdir,
401-
):
402-
Path("config.yml").touch()
403-
config = EverestConfig.with_defaults(config_path="./config.yml")
404-
config.dump("config.yml")
405-
monitor_entry(["config.yml"])
406-
status_path = ServerConfig.get_everserver_status_path(config.output_dir)
407-
status = everserver_status(status_path)
408-
expected_status = ExperimentState.completed
409-
expected_error = None
410-
411-
assert expected_status == status["status"]
412-
assert expected_error == status["message"]
413-
414-
415344
class ServerStatus:
416345
pass
417346

0 commit comments

Comments
 (0)