-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #81 from punch-mission/mhughes-nov13
Prepare for End2End Test
- Loading branch information
Showing
30 changed files
with
420 additions
and
172 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,145 @@ | ||
import os | ||
import time | ||
import subprocess | ||
import multiprocessing as mp | ||
from pathlib import Path | ||
from datetime import datetime | ||
|
||
import click | ||
from prefect import flow, serve | ||
from prefect.variables import Variable | ||
|
||
from .monitor.app import create_app | ||
from punchpipe.control.health import update_machine_health_stats | ||
from punchpipe.control.launcher import launcher_flow | ||
from punchpipe.control.util import load_pipeline_configuration | ||
from punchpipe.flows.level1 import level1_process_flow, level1_scheduler_flow | ||
from punchpipe.flows.level2 import level2_process_flow, level2_scheduler_flow | ||
from punchpipe.flows.level3 import level3_PTM_process_flow, level3_PTM_scheduler_flow | ||
from punchpipe.flows.levelq import levelq_process_flow, levelq_scheduler_flow | ||
from punchpipe.monitor.app import create_app | ||
|
||
THIS_DIR = os.path.dirname(__file__) | ||
app = create_app() | ||
server = app.server | ||
|
||
@click.group | ||
def main(): | ||
"""Run the PUNCH automated pipeline""" | ||
|
||
def launch_monitor(): | ||
app = create_app() | ||
app.run_server(debug=False, port=8051) | ||
|
||
@flow | ||
def my_flow(): | ||
print("Hello, Prefect!") | ||
|
||
|
||
def serve_flows(configuration_path): | ||
config = load_pipeline_configuration.fn(configuration_path) | ||
launcher_deployment = launcher_flow.to_deployment(name="launcher-deployment", | ||
description="Launch a pipeline segment.", | ||
cron=config['launcher'].get("schedule", "* * * * *"), | ||
parameters={"pipeline_configuration_path": configuration_path} | ||
) | ||
|
||
level1_scheduler_deployment = level1_scheduler_flow.to_deployment(name="level1-scheduler-deployment", | ||
description="Schedule a Level 1 flow.", | ||
cron="* * * * *", | ||
parameters={"pipeline_config_path": configuration_path} | ||
) | ||
level1_process_deployment = level1_process_flow.to_deployment(name="level1_process_flow", | ||
description="Process a file from Level 0 to Level 1.", | ||
parameters={"pipeline_config_path": configuration_path} | ||
) | ||
|
||
level2_scheduler_deployment = level2_scheduler_flow.to_deployment(name="level2-scheduler-deployment", | ||
description="Schedule a Level 2 flow.", | ||
cron="* * * * *", | ||
parameters={ | ||
"pipeline_config_path": configuration_path} | ||
|
||
) | ||
level2_process_deployment = level2_process_flow.to_deployment(name="level2_process_flow", | ||
description="Process files from Level 1 to Level 2.", | ||
parameters={"pipeline_config_path": configuration_path} | ||
) | ||
|
||
levelq_scheduler_deployment = levelq_scheduler_flow.to_deployment(name="levelq-scheduler-deployment", | ||
description="Schedule a Level Q flow.", | ||
cron="* * * * *", | ||
parameters={ | ||
"pipeline_config_path": configuration_path} | ||
|
||
) | ||
levelq_process_deployment = levelq_process_flow.to_deployment(name="levelq_process_flow", | ||
description="Process files from Level 1 to Level Q.", | ||
parameters={"pipeline_config_path": configuration_path} | ||
) | ||
|
||
level3_PTM_scheduler_deployment = level3_PTM_scheduler_flow.to_deployment(name="level3-PTM-scheduler-deployment", | ||
description="Schedule a Level 3 flow to make PTM.", | ||
cron="* * * * *", | ||
parameters={ | ||
"pipeline_config_path": configuration_path} | ||
|
||
) | ||
level3_PTM_process_deployment = level3_PTM_process_flow.to_deployment(name="level3_PTM_process_flow", | ||
description="Process PTM files from Level 2 to Level 3.", | ||
parameters={ | ||
"pipeline_config_path": configuration_path} | ||
) | ||
|
||
health_deployment = update_machine_health_stats.to_deployment(name="update-health-stats-deployment", | ||
description="Update the health stats table data.", | ||
cron="* * * * *") | ||
|
||
serve(launcher_deployment, | ||
level1_scheduler_deployment, level1_process_deployment, | ||
level2_scheduler_deployment, level2_process_deployment, | ||
levelq_scheduler_deployment, levelq_process_deployment, | ||
level3_PTM_scheduler_deployment, level3_PTM_process_deployment, | ||
health_deployment, | ||
limit=1000 | ||
) | ||
|
||
|
||
@main.command | ||
def run(): | ||
print("Launching punchpipe monitor on http://localhost:8051/.") | ||
subprocess.Popen(["prefect", "server", "start"]) | ||
print("\npunchpipe Prefect flows must be stopped manually in Prefect.") | ||
mp.Process(target=launch_monitor, args=()).start() | ||
@click.argument("configuration_path", type=click.Path(exists=True)) | ||
def run(configuration_path): | ||
now = datetime.now() | ||
|
||
configuration_path = str(Path(configuration_path).resolve()) | ||
output_path = f"punchpipe_{now.strftime('%Y%m%d_%H%M%S')}.txt" | ||
|
||
print() | ||
print(f"Launching punchpipe at {now} with configuration: {configuration_path}") | ||
print(f"Terminal logs from punchpipe are in {output_path}") | ||
|
||
|
||
with open(output_path, "w") as f: | ||
try: | ||
prefect_process = subprocess.Popen(["prefect", "server", "start"], | ||
stdout=f, stderr=subprocess.STDOUT) | ||
time.sleep(10) | ||
monitor_process = subprocess.Popen(["gunicorn", | ||
"-b", "0.0.0.0:8050", | ||
"--chdir", THIS_DIR, | ||
"cli:server"], | ||
stdout=f, stderr=subprocess.STDOUT) | ||
Variable.set("punchpipe_config", configuration_path, overwrite=True) | ||
print("Launched Prefect dashboard on http://localhost:4200/") | ||
print("Launched punchpipe monitor on http://localhost:8050/") | ||
print("Use ctrl-c to exit.") | ||
|
||
serve_flows(configuration_path) | ||
prefect_process.wait() | ||
monitor_process.wait() | ||
except KeyboardInterrupt: | ||
print("Shutting down.") | ||
prefect_process.terminate() | ||
monitor_process.terminate() | ||
print() | ||
print("punchpipe safely shut down.") | ||
except Exception as e: | ||
print(f"Received error: {e}") | ||
prefect_process.terminate() | ||
monitor_process.terminate() | ||
print() | ||
print("punchpipe abruptly shut down.") |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
from datetime import datetime | ||
|
||
import psutil | ||
from prefect import flow | ||
|
||
from punchpipe.control.db import Health | ||
from punchpipe.control.util import get_database_session, load_pipeline_configuration | ||
|
||
|
||
@flow | ||
def update_machine_health_stats(): | ||
config = load_pipeline_configuration() | ||
|
||
now = datetime.now() | ||
cpu_usage = psutil.cpu_percent(interval=5) | ||
memory_usage = psutil.virtual_memory().used / 1E9 # store in GB | ||
memory_percentage = psutil.virtual_memory().percent | ||
disk_usage = psutil.disk_usage(config.get("root", "/")).used / 1E9 # store in GB | ||
disk_percentage = psutil.disk_usage(config.get("root", "/")).percent | ||
num_pids = len(psutil.pids()) | ||
|
||
with get_database_session() as session: | ||
new_health_entry = Health(datetime=now, | ||
cpu_usage=cpu_usage, | ||
memory_usage=memory_usage, | ||
memory_percentage=memory_percentage, | ||
disk_usage=disk_usage, | ||
disk_percentage=disk_percentage, | ||
num_pids=num_pids) | ||
session.add(new_health_entry) | ||
session.commit() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 4 additions & 3 deletions
7
punchpipe/controlsegment/scheduler.py → punchpipe/control/scheduler.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
Oops, something went wrong.