source: trunk/misc/operations_helpers/provisioning/web_reliability.py

Last change on this file was fe1df149, checked in by Brian Warner <warner@…>, at 2012-02-16T22:29:05Z

make provisioning/reliability work in the new location, fix tests

  • Property mode set to 100644
File size: 6.2 KB
Line 
1
2from nevow import rend, loaders, tags as T
3from nevow.inevow import IRequest
4import reliability # requires NumPy
5import util
6
7def get_arg(ctx_or_req, argname, default=None, multiple=False):
8    """Extract an argument from either the query args (req.args) or the form
9    body fields (req.fields). If multiple=False, this returns a single value
10    (or the default, which defaults to None), and the query args take
11    precedence. If multiple=True, this returns a tuple of arguments (possibly
12    empty), starting with all those in the query args.
13    """
14    req = IRequest(ctx_or_req)
15    results = []
16    if argname in req.args:
17        results.extend(req.args[argname])
18    if req.fields and argname in req.fields:
19        results.append(req.fields[argname].value)
20    if multiple:
21        return tuple(results)
22    if results:
23        return results[0]
24    return default
25
26
27DAY=24*60*60
28MONTH=31*DAY
29YEAR=365*DAY
30
31def is_available():
32    if reliability:
33        return True
34    return False
35
36def yandm(seconds):
37    return "%dy.%dm" % (int(seconds/YEAR), int( (seconds%YEAR)/MONTH))
38
39class ReliabilityTool(rend.Page):
40    addSlash = True
41    docFactory = loaders.xmlfile(util.sibling("reliability.xhtml"))
42
43    DEFAULT_PARAMETERS = [
44        ("drive_lifetime", "8Y", "time",
45         "Average drive lifetime"),
46        ("k", 3, "int",
47         "Minimum number of shares needed to recover the file"),
48        ("R", 7, "int",
49         "Repair threshold: repair will not occur until fewer than R shares "
50         "are left"),
51        ("N", 10, "int",
52         "Total number of shares of the file generated"),
53        ("delta", "1M", "time", "Amount of time between each simulation step"),
54        ("check_period", "1M", "time",
55         "How often to run the checker and repair if fewer than R shares"),
56        ("report_period", "3M", "time",
57         "Amount of time between result rows in this report"),
58        ("report_span", "5Y", "time",
59         "Total amount of time covered by this report"),
60        ]
61
62    def parse_time(self, s):
63        if s.endswith("M"):
64            return int(s[:-1]) * MONTH
65        if s.endswith("Y"):
66            return int(s[:-1]) * YEAR
67        return int(s)
68
69    def format_time(self, s):
70        if s%YEAR == 0:
71            return "%dY" % (s/YEAR)
72        if s%MONTH == 0:
73            return "%dM" % (s/MONTH)
74        return "%d" % s
75
76    def get_parameters(self, ctx):
77        parameters = {}
78        for (name,default,argtype,description) in self.DEFAULT_PARAMETERS:
79            v = get_arg(ctx, name, default)
80            if argtype == "time":
81                value = self.parse_time(v)
82            else:
83                value = int(v)
84            parameters[name] = value
85        return parameters
86
87    def renderHTTP(self, ctx):
88        self.parameters = self.get_parameters(ctx)
89        self.results = reliability.ReliabilityModel.run(**self.parameters)
90        return rend.Page.renderHTTP(self, ctx)
91
92    def make_input(self, name, old_value):
93        return T.input(name=name, type="text", size="5",
94                       value=self.format_time(old_value))
95
96    def render_forms(self, ctx, data):
97        f = T.form(action=".", method="get")
98        table = []
99        for (name,default_value,argtype,description) in self.DEFAULT_PARAMETERS:
100            old_value = self.parameters[name]
101            i = self.make_input(name, old_value)
102            table.append(T.tr[T.td[name+":"], T.td[i], T.td[description]])
103        go = T.input(type="submit", value="Recompute")
104        return [T.h2["Simulation Parameters:"],
105                f[T.table[table], go],
106                ]
107
108    def data_simulation_table(self, ctx, data):
109        for row in self.results.samples:
110            yield row
111
112    def render_simulation_row(self, ctx, row):
113        (when, unmaintained_shareprobs, maintained_shareprobs,
114         P_repaired_last_check_period,
115         cumulative_number_of_repairs,
116         cumulative_number_of_new_shares,
117         P_dead_unmaintained, P_dead_maintained) = row
118        ctx.fillSlots("t", yandm(when))
119        ctx.fillSlots("P_repair", "%.6f" % P_repaired_last_check_period)
120        ctx.fillSlots("P_dead_unmaintained", "%.6g" % P_dead_unmaintained)
121        ctx.fillSlots("P_dead_maintained", "%.6g" % P_dead_maintained)
122        return ctx.tag
123
124    def render_report_span(self, ctx, row):
125        (when, unmaintained_shareprobs, maintained_shareprobs,
126         P_repaired_last_check_period,
127         cumulative_number_of_repairs,
128         cumulative_number_of_new_shares,
129         P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
130        return ctx.tag[yandm(when)]
131
132    def render_P_loss_unmaintained(self, ctx, row):
133        (when, unmaintained_shareprobs, maintained_shareprobs,
134         P_repaired_last_check_period,
135         cumulative_number_of_repairs,
136         cumulative_number_of_new_shares,
137         P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
138        return ctx.tag["%.6g (%1.8f%%)" % (P_dead_unmaintained,
139                                           100*P_dead_unmaintained)]
140
141    def render_P_loss_maintained(self, ctx, row):
142        (when, unmaintained_shareprobs, maintained_shareprobs,
143         P_repaired_last_check_period,
144         cumulative_number_of_repairs,
145         cumulative_number_of_new_shares,
146         P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
147        return ctx.tag["%.6g (%1.8f%%)" % (P_dead_maintained,
148                                           100*P_dead_maintained)]
149
150    def render_P_repair_rate(self, ctx, row):
151        (when, unmaintained_shareprobs, maintained_shareprobs,
152         P_repaired_last_check_period,
153         cumulative_number_of_repairs,
154         cumulative_number_of_new_shares,
155         P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
156        freq = when / cumulative_number_of_repairs
157        return ctx.tag["%.6g" % freq]
158
159    def render_P_repair_shares(self, ctx, row):
160        (when, unmaintained_shareprobs, maintained_shareprobs,
161         P_repaired_last_check_period,
162         cumulative_number_of_repairs,
163         cumulative_number_of_new_shares,
164         P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
165        generated_shares = cumulative_number_of_new_shares / cumulative_number_of_repairs
166        return ctx.tag["%1.2f" % generated_shares]
167
168
Note: See TracBrowser for help on using the repository browser.