From 09226edeceeb6fef77a1083395e7493854d54225 Mon Sep 17 00:00:00 2001 From: bohanjason Date: Fri, 29 May 2020 00:17:35 -0400 Subject: [PATCH] support monitor --- .../src/main/java/com/controller/Main.java | 17 +++++++------ client/driver/driver_config.py | 4 ++++ client/driver/fabfile.py | 24 +++++++++++++++---- server/website/website/views.py | 16 ++++++------- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/client/controller/src/main/java/com/controller/Main.java b/client/controller/src/main/java/com/controller/Main.java index b248dbb..63d8362 100644 --- a/client/controller/src/main/java/com/controller/Main.java +++ b/client/controller/src/main/java/com/controller/Main.java @@ -56,6 +56,7 @@ public class Main { private static boolean keepRunning = true; private static boolean firstCollecting = false; + @SuppressWarnings("restriction") public static void main(String[] args) { // Initialize log4j @@ -137,13 +138,13 @@ public class Main { } DBCollector collector = getCollector(config); + File f = new File("pid.txt"); try { - // add a signal handler - Signal.handle(new Signal("INT"), signal -> firstCollecting = true); - File f = new File("pid.txt"); - // get pid of this process and write the pid to a file before recording the start time if (time < 0) { + // add a signal handler + Signal.handle(new Signal("INT"), signal -> firstCollecting = true); + String vmName = ManagementFactory.getRuntimeMXBean().getName(); int p = vmName.indexOf("@"); int pid = Integer.valueOf(vmName.substring(0, p)); @@ -157,6 +158,9 @@ public class Main { ioe.printStackTrace(); } } + else { + firstCollecting = true; + } LOG.info("Output the process pid to pid.txt"); while (!firstCollecting) { @@ -185,9 +189,6 @@ public class Main { knobsWriter.println(knobs); knobsWriter.close(); - // add a signal handler - Signal.handle(new Signal("INT"), signal -> keepRunning = false); - // record start time long startTime = System.currentTimeMillis(); LOG.info("Starting the experiment ..."); @@ -196,6 +197,8 @@ public class Main { if (time >= 0) { Thread.sleep(time * TO_MILLISECONDS); } else { + // add a signal handler + Signal.handle(new Signal("INT"), signal -> keepRunning = false); while (keepRunning) { Thread.sleep(1); } diff --git a/client/driver/driver_config.py b/client/driver/driver_config.py index 37be5b3..582787e 100644 --- a/client/driver/driver_config.py +++ b/client/driver/driver_config.py @@ -153,6 +153,10 @@ OLTPBENCH_BENCH = 'tpcc' # CONTROLLER OPTIONS #========================================================== +# Controller observation time, OLTPBench will be disabled for +# monitoring if the time is specified +CONTROLLER_OBSERVE_SEC = 100 + # Path to the controller directory CONTROLLER_HOME = DRIVER_HOME + '/../controller' diff --git a/client/driver/fabfile.py b/client/driver/fabfile.py index b244c47..6b6b073 100644 --- a/client/driver/fabfile.py +++ b/client/driver/fabfile.py @@ -308,11 +308,11 @@ def run_oltpbench_bg(): @task -def run_controller(): +def run_controller(interval_sec=-1): LOG.info('Controller config path: %s', dconf.CONTROLLER_CONFIG) create_controller_config() - cmd = 'gradle run -PappArgs="-c {} -d output/" --no-daemon > {}'.\ - format(dconf.CONTROLLER_CONFIG, dconf.CONTROLLER_LOG) + cmd = 'gradle run -PappArgs="-c {} -t {} -d output/" --no-daemon > {}'.\ + format(dconf.CONTROLLER_CONFIG, interval_sec, dconf.CONTROLLER_LOG) with lcd(dconf.CONTROLLER_HOME): # pylint: disable=not-context-manager local(cmd) @@ -642,7 +642,13 @@ def clean_logs(): @task def clean_oltpbench_results(): # remove oltpbench result files - local('rm -f {}/results/*'.format(dconf.OLTPBENCH_HOME)) + local('rm -f {}/results/outputfile*'.format(dconf.OLTPBENCH_HOME)) + + +@task +def clean_controller_results(): + # remove oltpbench result files + local('rm -f {}/output/*.json'.format(dconf.CONTROLLER_HOME)) def _set_oltpbench_property(name, line): @@ -820,6 +826,16 @@ def run_loops(max_iter=10): LOG.info('The %s-th Loop Ends / Total Loops %s', i + 1, max_iter) +@task +def monitor(max_iter=1): + for i in range(int(max_iter)): + LOG.info('The %s-th Monitor Loop Starts / Total Loops %s', i + 1, max_iter) + clean_controller_results() + run_controller(interval_sec=dconf.CONTROLLER_OBSERVE_SEC) + upload_result() + LOG.info('The %s-th Monitor Loop Ends / Total Loops %s', i + 1, max_iter) + + @task def rename_batch(result_dir=None): result_dir = result_dir or dconf.RESULT_DIR diff --git a/server/website/website/views.py b/server/website/website/views.py index 2242283..6e9c6ba 100644 --- a/server/website/website/views.py +++ b/server/website/website/views.py @@ -205,8 +205,8 @@ def project_sessions_view(request, project_id): 'button_create': 'create a new session', })) form_labels['title'] = "Your Sessions" - form_labels['description'] = "description" - form_labels['result_count'] = "# result" + form_labels['description'] = "Description" + form_labels['result_count'] = "# Result" for session in sessions: session.session_type_name = Session.TUNING_OPTIONS[session.tuning_session] session.algorithm_name = AlgorithmType.name(session.algorithm) @@ -506,13 +506,13 @@ def handle_result_files(session, files, execution_times=None): target_instance = target_objectives.get_instance(dbms_id, target_name) if target_instance.is_udf() and len(udm_all) == 0: return HttpResponse('ERROR: user defined target objective {} is not uploaded!'.format( - target_name)) + target_name), status=400) if len(udm_all) > 0: # Note: Here we assume that for sessions with same dbms, user defined metrics are same. # Otherwise there may exist inconsistency, it becomes worse after restarting web server. if target_instance.is_udf() and (target_name not in udm_all.keys()): return HttpResponse('ERROR: user defined target objective {} is not uploaded!'.format( - target_name)) + target_name), status=400) if not target_objectives.udm_registered(dbms_id): target_objectives.register_udm(dbms_id, udm_all) for name, info in udm_all.items(): @@ -646,7 +646,7 @@ def handle_result_files(session, files, execution_times=None): if not re.match('^[a-zA-Z0-9_-]+$', workload_name): return HttpResponse('Your workload name ' + workload_name + ' contains ' 'invalid characters! It should only contain ' - 'alpha-numeric, underscore(_) and hyphen(-)') + 'alpha-numeric, underscore(_) and hyphen(-)', status=400) try: # Check that we support this DBMS and version @@ -658,20 +658,20 @@ def handle_result_files(session, files, execution_times=None): except Exception: # pylint: disable=broad-except LOG.warning('Cannot parse dbms version %s', dbms_version) return HttpResponse('{} v{} is not yet supported.'.format( - dbms_type, dbms_version)) + dbms_type, dbms_version), status=400) try: # Check that we support this DBMS and version dbms = DBMSCatalog.objects.get( type=dbms_type, version=dbms_version) except ObjectDoesNotExist: return HttpResponse('{} v{} is not yet supported.'.format( - dbms_type, dbms_version)) + dbms_type, dbms_version), status=400) if dbms != session.dbms: return HttpResponse('The DBMS must match the type and version ' 'specified when creating the session. ' '(expected=' + session.dbms.full_name + ') ' - '(actual=' + dbms.full_name + ')') + '(actual=' + dbms.full_name + ')', status=400) # Load, process, and store the knobs in the DBMS's configuration knob_dict, knob_diffs = parser.parse_dbms_knobs(