components/ws-daemon/pkg/cpulimit/design.ipynb
This notebook takes the data produced by the tests and displays it, aiming to provide insight into the behaviour of the algorithm. For one, we can gain confidence that the algorithm works as expected. We might also use this analysis to inform the parameter choice in production.
Prior to running any of the analysis, we need to do some setup work.
!pip install pandas matplotlib
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
from IPython.display import display, HTML
matplotlib.rcParams['figure.figsize'] = (20, 10)
%%javascript
IPython.OutputArea.auto_scroll_threshold = 9999
def details(title, objs):
display(HTML("<details><summary><h1>%s</h1></summary>%s</details>" % (title, [ o._repr_html_() for o in objs ])))
The function below is our primary driver: it loads a CSV file produced by the tests and generates plots which aim to provide insight into the behaviour.
def analyse(fn):
display(HTML("<h1>"+fn+"</h1>"))
df = pd.read_csv(fn)
df["t"] = df["t"] / (1000.0*1000.0*1000.0)
df["dt"] = df['t'] - df.groupby("id")["t"].shift(1)
df['usage_lag'] = df.groupby("id")["usage"].shift(1)
df['usage_dt'] = df['usage'] - df['usage_lag']
df['usage_fair'] = (df['bwavail'] * df["t"]) / len(df.groupby("id"))
df['usage_avail'] = (df['bwavail'] * df["t"])
df['usage_total'] = [ df['usage'][df['t'] == t].sum() for t in df['t'] ]
df['desiredrate_diff'] = df['actualrate']-df['desiredrate']
display(HTML("<h3>Per Client</h3>"))
cs = pd.DataFrame()
cs["desiredrate_diff"] = df.groupby("id")['desiredrate_diff'].mean()
cs["total_usage"] = df.groupby("id")['usage'].sum()
cs["limit_lo"] = df.groupby("id")['limit'].min()
cs["limit_hi"] = df.groupby("id")['limit'].max()
cs.columns = ['Desired Date Diff', 'Total Usage', 'Min Limit', 'Max Limit']
display(cs)
display(HTML("<h3>Bandwidth</h3>"))
df["bwreq"].plot();
df["bwused"].plot();
df["bwavail"].plot();
df["bwbreak"].plot();
plt.legend();
plt.title(fn+": bandwidth use");
plt.show();
display(HTML("<h3>Usage</h3>"))
plt.figure();
df.groupby("id")['usage'].plot();
df['usage_fair'].plot();
plt.legend();
plt.title(fn+": usage");
plt.show();
plt.figure();
df['usage_avail'].plot();
df['usage_total'].plot();
plt.legend();
plt.title(fn+": total usage");
plt.show();
pd.pivot_table(df.reset_index(),
index='t', columns='id', values='usage_dt'
).plot(subplots=True, title=fn+": cycle usage", figsize=(20, 5*len(df.groupby("id"))));
plt.show();
pd.pivot_table(df.reset_index(),
index='t', columns='id', values='usage'
).plot(subplots=True, title=fn+": total usage", figsize=(20, 5*len(df.groupby("id"))));
plt.show();
display(HTML("<h3>Rates / Consumption</h3>"))
pd.pivot_table(df.reset_index(),
index='t', columns='id', values='desiredrate'
).plot(subplots=True, title=fn+": desired rate", figsize=(20, 5*len(df.groupby("id"))));
plt.show();
pd.pivot_table(df.reset_index(),
index='t', columns='id', values='desiredrate_diff'
).plot(subplots=True, title=fn+": desired rate diff", figsize=(20, 5*len(df.groupby("id"))));
plt.show();
pd.pivot_table(df.reset_index(),
index='t', columns='id', values='limit'
).plot(subplots=True, title=fn+": limit", figsize=(20, 5*len(df.groupby("id"))));
plt.show();
The cell below will run all tests and run the analyse function on their result.
!go test -v .
from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(".") if isfile(join(".", f)) and f.startswith("sim_") and f.endswith(".csv")]
for f in onlyfiles:
analyse(f)