Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Job JSON, and Status one-shot #300

Merged
merged 2 commits into from
May 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions manager.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import argparse

from plotmanager.library.utilities.exceptions import InvalidArgumentException
from plotmanager.library.utilities.commands import start_manager, stop_manager, view, analyze_logs
from plotmanager.library.utilities.commands import start_manager, stop_manager, view, jsonout, analyze_logs


parser = argparse.ArgumentParser(description='This is the central manager for Swar\'s Chia Plot Manager.')
Expand Down Expand Up @@ -33,10 +33,14 @@
elif args.action == 'stop':
stop_manager()
elif args.action == 'view':
view()
view(False)
elif args.action == 'json':
jsonout()
elif args.action == 'status':
view(True)
elif args.action == 'analyze_logs':
analyze_logs()
else:
error_message = 'Invalid action provided. The valid options are "start", "restart", "stop", "view", and ' \
error_message = 'Invalid action provided. The valid options are "start", "restart", "stop", "view", "status", "json" and ' \
'"analyze_logs".'
raise InvalidArgumentException(error_message)
63 changes: 59 additions & 4 deletions plotmanager/library/utilities/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
from plotmanager.library.utilities.jobs import load_jobs
from plotmanager.library.utilities.log import analyze_log_dates, check_log_progress, analyze_log_times
from plotmanager.library.utilities.notifications import send_notifications
from plotmanager.library.utilities.print import print_view
from plotmanager.library.utilities.print import print_view, print_json
from plotmanager.library.utilities.processes import is_windows, get_manager_processes, get_running_plots, start_process


def start_manager():
if get_manager_processes():
raise ManagerError('Manager is already running.')
raise ManagerError('Manger is already running.')

directory = pathlib.Path().resolve()
stateless_manager_path = os.path.join(directory, 'stateless-manager.py')
Expand Down Expand Up @@ -74,8 +74,61 @@ def stop_manager():
raise TerminationException("Failed to stop manager processes.")
print("Successfully stopped manager processes.")

def jsonout():
chia_location, log_directory, config_jobs, manager_check_interval, max_concurrent, progress_settings, \
notification_settings, debug_level, view_settings = get_config_info()
view_check_interval = view_settings['check_interval']
analysis = {'files': {}}
drives = {'temp': [], 'temp2': [], 'dest': []}
jobs = load_jobs(config_jobs)
for job in jobs:
drive = job.temporary_directory.split('\\')[0]
drives['temp'].append(drive)
directories = {
'dest': job.destination_directory,
'temp2': job.temporary2_directory,
}
for key, directory_list in directories.items():
if directory_list is None:
continue
if isinstance(directory_list, list):
for directory in directory_list:
drive = directory.split('\\')[0]
if drive in drives[key]:
continue
drives[key].append(drive)
else:
drive = directory_list.split('\\')[0]
if drive in drives[key]:
continue
drives[key].append(drive)

def view():
running_work = {}

analysis = analyze_log_dates(log_directory=log_directory, analysis=analysis)
jobs = load_jobs(config_jobs)
jobs, running_work = get_running_plots(jobs=jobs, running_work=running_work)
check_log_progress(jobs=jobs, running_work=running_work, progress_settings=progress_settings,
notification_settings=notification_settings, view_settings=view_settings)
print_json(jobs=jobs, running_work=running_work, analysis=analysis, drives=drives,
next_log_check=datetime.now() + timedelta(seconds=60), view_settings=view_settings)

has_file = False
if len(running_work.values()) == 0:
has_file = True
for work in running_work.values():
if not work.log_file:
continue
has_file = True
break
if not has_file:
print("Restarting view due to psutil going stale...")
system_args = [f'"{sys.executable}"'] + sys.argv
os.execv(sys.executable, system_args)

exit()

def view(status=False):
chia_location, log_directory, config_jobs, manager_check_interval, max_concurrent, progress_settings, \
notification_settings, debug_level, view_settings, instrumentation_settings = get_config_info()
view_check_interval = view_settings['check_interval']
Expand Down Expand Up @@ -114,7 +167,9 @@ def view():
notification_settings=notification_settings, view_settings=view_settings,
instrumentation_settings=instrumentation_settings)
print_view(jobs=jobs, running_work=running_work, analysis=analysis, drives=drives,
next_log_check=datetime.now() + timedelta(seconds=view_check_interval), view_settings=view_settings)
next_log_check=datetime.now() + timedelta(seconds=view_check_interval), view_settings=view_settings, viewstatus=status)
if status:
break
time.sleep(view_check_interval)
has_file = False
if len(running_work.values()) == 0:
Expand Down
57 changes: 55 additions & 2 deletions plotmanager/library/utilities/print.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
import os
import psutil
import json

from datetime import datetime, timedelta

from plotmanager.library.utilities.processes import get_manager_processes, get_chia_drives

def _get_json(pid, running_work, view_settings):
work = running_work[pid]
phase_times = work.phase_times
elapsed_time = (datetime.now() - work.datetime_start)
elapsed_time = pretty_print_time(elapsed_time.seconds)
phase_time_log = []
for i in range(1, 5):
if phase_times.get(i):
phase_time_log.append(phase_times.get(i))

row = [
work.job.name if work.job else '?',
work.k_size,
pid,
work.datetime_start.strftime(view_settings['datetime_format']),
elapsed_time,
work.current_phase,
' / '.join(phase_time_log),
work.progress,
pretty_print_bytes(work.temp_file_size, 'gb', 0, " GiB"),
]

return (row)


def _get_row_info(pid, running_work, view_settings):
work = running_work[pid]
Expand Down Expand Up @@ -65,6 +90,31 @@ def pretty_print_table(rows):
console.append(separator)
return "\n".join(console)

def get_job_json(jobs, running_work, view_settings):
rows = []
rows2 = []
#headers = ['num', 'job', 'k', 'pid', 'start', 'elapsed_time', 'phase', 'phase_times', 'progress', 'temp_size']
added_pids = []
for job in jobs:
for pid in job.running_work:
if pid not in running_work:
continue
#rows.append(_get_json(pid, running_work, view_settings))
rows2.append(_get_json(pid, running_work, view_settings))
added_pids.append(pid)
for pid in running_work.keys():
if pid in added_pids:
continue
rows2.append(_get_json(pid, running_work, view_settings))
added_pids.append(pid)
rows2.sort(key=lambda x: (x[4]), reverse=True)
for i in range(len(rows2)):
rows2[i] = [str(i + 1)] + rows2[i]
#rows = [headers] + rows
rows2 = '{ "jobs": ' + json.dumps(rows2) + ' }'
print(rows2)
return(rows2)
#return pretty_print_table(rows2)

def get_job_data(jobs, running_work, view_settings):
rows = []
Expand Down Expand Up @@ -169,8 +219,10 @@ def get_drive_data(drives, running_work, job_data):
rows = [headers] + rows
return pretty_print_table(rows)

def print_json(jobs, running_work, analysis, drives, next_log_check, view_settings):
job_data2 = get_job_json(jobs=jobs, running_work=running_work, view_settings=view_settings)

def print_view(jobs, running_work, analysis, drives, next_log_check, view_settings):
def print_view(jobs, running_work, analysis, drives, next_log_check, view_settings, viewstatus):
# Job Table
job_data = get_job_data(jobs=jobs, running_work=running_work, view_settings=view_settings)

Expand Down Expand Up @@ -202,5 +254,6 @@ def print_view(jobs, running_work, analysis, drives, next_log_check, view_settin
print(f'Plots Completed Yesterday: {analysis["summary"].get(datetime.now().date() - timedelta(days=1), 0)}')
print(f'Plots Completed Today: {analysis["summary"].get(datetime.now().date(), 0)}')
print()
print(f"Next log check at {next_log_check.strftime('%Y-%m-%d %H:%M:%S')}")
if viewstatus == False:
print(f"Next log check at {next_log_check.strftime('%Y-%m-%d %H:%M:%S')}")
print()