Skip to content

Commit 8e148b6

Browse files
committed
Time limit for resource_allocation_plot
1. Created time limit for resource_allocation_plot using signal library. 2. Don’t show failures in legend if no failures. 3. Added more robust print statements with timestamps. 4. Only populate commands to qiita_pet when plots were created.
1 parent 4032ed5 commit 8e148b6

File tree

2 files changed

+81
-32
lines changed

2 files changed

+81
-32
lines changed

qiita_db/meta_util.py

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
from hashlib import md5
3737
from re import sub
3838
from json import loads, dump, dumps
39+
import signal
40+
import traceback
3941

4042
from qiita_db.util import create_nested_path, retrieve_resource_data
4143
from qiita_db.util import resource_allocation_plot
@@ -555,7 +557,8 @@ def generate_plugin_releases():
555557
f(redis_key, v)
556558

557559

558-
def update_resource_allocation_redis(active=True, verbose=False):
560+
def update_resource_allocation_redis(active=True, verbose=False,
561+
time_limit=300):
559562
"""Updates redis with plots and information about current software.
560563
561564
Parameters
@@ -564,7 +567,11 @@ def update_resource_allocation_redis(active=True, verbose=False):
564567
Defaults to True. Should only be False when testing.
565568
566569
verbose: boolean, optional
567-
Defaults to False. Prints status on what function
570+
Defaults to False. Prints status on what function is running.
571+
572+
time_limit: integer, optional
573+
Defaults to 300, representing 5 minutes. This is the limit for how long
574+
resource_allocation_plot function will run.
568575
569576
"""
570577
time = datetime.now().strftime('%m-%d-%y')
@@ -592,24 +599,24 @@ def update_resource_allocation_redis(active=True, verbose=False):
592599
cmd_name = command.name
593600
scommands[sname][sversion][cmd_name] = col_names
594601

595-
redis_key = 'resources:commands'
596-
r_client.set(redis_key, str(scommands))
597-
602+
# software commands for which resource allocations were sucessfully
603+
# calculated
604+
scommands_allocation = {}
598605
for sname, versions in scommands.items():
599606
for version, commands in versions.items():
600607
for cname, col_names in commands.items():
601608
df = retrieve_resource_data(cname, sname, version, COLUMNS)
602609
if verbose:
603-
print(("Retrieving allocation resources for " +
604-
f" software: {sname}" +
605-
f" version: {version}" +
606-
f" command: {cname}"))
610+
print(("\nRetrieving allocation resources for:\n" +
611+
f" software: {sname}\n" +
612+
f" version: {version}\n" +
613+
f" command: {cname}"))
607614
if len(df) == 0:
608615
if verbose:
609-
print(("No allocation resources available for" +
616+
print(("\nNo allocation resources available for" +
610617
f" software: {sname}" +
611618
f" version: {version}" +
612-
f" command: {cname}"))
619+
f" command: {cname}\n"))
613620
continue
614621
# column_name_str looks like col1*col2*col3, etc
615622
for col_name in col_names:
@@ -624,16 +631,38 @@ def update_resource_allocation_redis(active=True, verbose=False):
624631
else:
625632
new_column *= df_copy[curr_column]
626633
if verbose:
627-
print(("Building resource allocation plot for " +
628-
f" software: {sname}" +
629-
f" version: {version}" +
630-
f" command: {cname}" +
631-
f" column name: {col_name}"))
634+
print(
635+
("\nBuilding resource allocation plot for:\n" +
636+
f" software: {sname}\n" +
637+
f" version: {version}\n" +
638+
f" command: {cname}\n" +
639+
f" column name: {col_name}\n" +
640+
f" {datetime.now().strftime('%b %d %H:%M:%S')}"))
641+
642+
def timeout_handler(signum, frame):
643+
raise TimeoutError((
644+
"\nresource_allocation_plot " +
645+
"execution exceeded time limit." +
646+
"For:\n"
647+
f" software: {sname}\n" +
648+
f" version: {version}\n" +
649+
f" command: {cname}\n" +
650+
f" column name: {col_name}\n" +
651+
f" {datetime.now().strftime('%b %d %H:%M:%S')}"))
652+
653+
signal.signal(signal.SIGALRM, timeout_handler)
654+
signal.alarm(time_limit)
655+
try:
656+
fig, axs = resource_allocation_plot(df_copy,
657+
col_name,
658+
new_column,
659+
verbose=verbose)
660+
signal.alarm(0)
661+
except TimeoutError:
662+
print("Timeout reached!")
663+
traceback.print_exc()
664+
continue
632665

633-
fig, axs = resource_allocation_plot(df_copy,
634-
col_name,
635-
new_column,
636-
verbose=verbose)
637666
titles = [0, 0]
638667
images = [0, 0]
639668

@@ -685,14 +714,28 @@ def update_resource_allocation_redis(active=True, verbose=False):
685714
("title_time", titles[1], r_client.set)
686715
]
687716
if verbose:
688-
print(("Saving resource allocation image for " +
689-
f" software: {sname}" +
690-
f" version: {version}" +
691-
f" command: {cname}" +
692-
f" column name: {col_name}"))
717+
print(
718+
("Saving resource allocation image for\n" +
719+
f" software: {sname}\n" +
720+
f" version: {version}\n" +
721+
f" command: {cname}\n" +
722+
f" column name: {col_name}\n" +
723+
f" {datetime.now().strftime('%b %d %H:%M:%S')}"))
693724

694725
for k, v, f in values:
695726
redis_key = 'resources$#%s$#%s$#%s$#%s:%s' % (
696727
cname, sname, version, col_name, k)
697728
r_client.delete(redis_key)
698729
f(redis_key, v)
730+
731+
if sname not in scommands_allocation:
732+
scommands_allocation[sname] = {}
733+
if version not in scommands_allocation[sname]:
734+
scommands_allocation[sname][version] = {}
735+
if cname not in scommands_allocation[sname][version]:
736+
scommands_allocation[sname][version][cname] = []
737+
scommands_allocation[sname][version][cname].append(
738+
col_name)
739+
740+
redis_key = 'resources:commands'
741+
r_client.set(redis_key, str(scommands_allocation))

qiita_db/util.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2527,7 +2527,7 @@ def _resource_allocation_plot_helper(
25272527
print(f"\t\tFitting best model for {curr}; column {col_name}")
25282528
# 50 - number of maximum iterations, 3 - number of failures we tolerate
25292529
best_model_name, best_model, options = _resource_allocation_calculate(
2530-
df, x_data, y_data, models, curr, col_name, 50, 3)
2530+
df, x_data, y_data, models, curr, col_name, 50, 3, verbose)
25312531
if verbose:
25322532
print(
25332533
f"\t\tSuccessfully chose best model for {curr}; column {col_name}")
@@ -2553,8 +2553,9 @@ def _resource_allocation_plot_helper(
25532553
success_df, failures_df = _resource_allocation_success_failures(
25542554
df, k, a, b, best_model, col_name, curr)
25552555
failures = failures_df.shape[0]
2556-
ax.scatter(failures_df[col_name], failures_df[curr], color='red', s=3,
2557-
label="failures")
2556+
if failures != 0:
2557+
ax.scatter(failures_df[col_name], failures_df[curr], color='red', s=3,
2558+
label="failures")
25582559

25592560
success_df['node_name'].fillna('unknown', inplace=True)
25602561

@@ -2580,7 +2581,7 @@ def _resource_allocation_plot_helper(
25802581

25812582

25822583
def _resource_allocation_calculate(
2583-
df, x, y, models, type_, col_name, depth, tolerance):
2584+
df, x, y, models, type_, col_name, depth, tolerance, verbose):
25842585
"""Helper function for resource allocation plot. Calculates best_model and
25852586
best_result given the models list and x,y data.
25862587
@@ -2621,6 +2622,11 @@ def _resource_allocation_calculate(
26212622
best_failures = np.inf
26222623
best_max = np.inf
26232624
for model_name, model in models.items():
2625+
if verbose:
2626+
print(
2627+
f"\t\t\tCalculating {model_name} for {type_}; "
2628+
f"{col_name} {datetime.now().strftime('%b %d %H:%M:%S')}"
2629+
)
26242630
model_equation = model['equation']
26252631
# start values for binary search, where sl is left, sr is right
26262632
# penalty weight must be positive & non-zero, hence, sl >= 1.
@@ -2763,9 +2769,9 @@ def _resource_allocation_success_failures(df, k, a, b, model, col_name, type_):
27632769
"""
27642770

27652771
x_plot = np.array(df[col_name])
2766-
df[f'c{type_}'] = model(x_plot, k, a, b)
2767-
success_df = df[df[type_] <= df[f'c{type_}']].copy()
2768-
failures_df = df[df[type_] > df[f'c{type_}']].copy()
2772+
y_plot = model(x_plot, k, a, b)
2773+
success_df = df[df[type_] <= y_plot].copy()
2774+
failures_df = df[df[type_] > y_plot].copy()
27692775
return (success_df, failures_df)
27702776

27712777

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy