]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - misc/operations_helpers/provisioning/web_reliability.py
d5d340615a4c33ebf5f86a586cef220fc924c443
[tahoe-lafs/tahoe-lafs.git] / misc / operations_helpers / provisioning / web_reliability.py
1
2 from nevow import rend, tags as T
3 reliability = None # might not be usable
4 try:
5     from allmydata import reliability # requires NumPy
6 except ImportError:
7     pass
8 from allmydata.web.common import getxmlfile, get_arg
9
10
11 DAY=24*60*60
12 MONTH=31*DAY
13 YEAR=365*DAY
14
15 def is_available():
16     if reliability:
17         return True
18     return False
19
20 def yandm(seconds):
21     return "%dy.%dm" % (int(seconds/YEAR), int( (seconds%YEAR)/MONTH))
22
23 class ReliabilityTool(rend.Page):
24     addSlash = True
25     docFactory = getxmlfile("reliability.xhtml")
26
27     DEFAULT_PARAMETERS = [
28         ("drive_lifetime", "8Y", "time",
29          "Average drive lifetime"),
30         ("k", 3, "int",
31          "Minimum number of shares needed to recover the file"),
32         ("R", 7, "int",
33          "Repair threshold: repair will not occur until fewer than R shares "
34          "are left"),
35         ("N", 10, "int",
36          "Total number of shares of the file generated"),
37         ("delta", "1M", "time", "Amount of time between each simulation step"),
38         ("check_period", "1M", "time",
39          "How often to run the checker and repair if fewer than R shares"),
40         ("report_period", "3M", "time",
41          "Amount of time between result rows in this report"),
42         ("report_span", "5Y", "time",
43          "Total amount of time covered by this report"),
44         ]
45
46     def parse_time(self, s):
47         if s.endswith("M"):
48             return int(s[:-1]) * MONTH
49         if s.endswith("Y"):
50             return int(s[:-1]) * YEAR
51         return int(s)
52
53     def format_time(self, s):
54         if s%YEAR == 0:
55             return "%dY" % (s/YEAR)
56         if s%MONTH == 0:
57             return "%dM" % (s/MONTH)
58         return "%d" % s
59
60     def get_parameters(self, ctx):
61         parameters = {}
62         for (name,default,argtype,description) in self.DEFAULT_PARAMETERS:
63             v = get_arg(ctx, name, default)
64             if argtype == "time":
65                 value = self.parse_time(v)
66             else:
67                 value = int(v)
68             parameters[name] = value
69         return parameters
70
71     def renderHTTP(self, ctx):
72         self.parameters = self.get_parameters(ctx)
73         self.results = reliability.ReliabilityModel.run(**self.parameters)
74         return rend.Page.renderHTTP(self, ctx)
75
76     def make_input(self, name, old_value):
77         return T.input(name=name, type="text", size="5",
78                        value=self.format_time(old_value))
79
80     def render_forms(self, ctx, data):
81         f = T.form(action=".", method="get")
82         table = []
83         for (name,default_value,argtype,description) in self.DEFAULT_PARAMETERS:
84             old_value = self.parameters[name]
85             i = self.make_input(name, old_value)
86             table.append(T.tr[T.td[name+":"], T.td[i], T.td[description]])
87         go = T.input(type="submit", value="Recompute")
88         return [T.h2["Simulation Parameters:"],
89                 f[T.table[table], go],
90                 ]
91
92     def data_simulation_table(self, ctx, data):
93         for row in self.results.samples:
94             yield row
95
96     def render_simulation_row(self, ctx, row):
97         (when, unmaintained_shareprobs, maintained_shareprobs,
98          P_repaired_last_check_period,
99          cumulative_number_of_repairs,
100          cumulative_number_of_new_shares,
101          P_dead_unmaintained, P_dead_maintained) = row
102         ctx.fillSlots("t", yandm(when))
103         ctx.fillSlots("P_repair", "%.6f" % P_repaired_last_check_period)
104         ctx.fillSlots("P_dead_unmaintained", "%.6g" % P_dead_unmaintained)
105         ctx.fillSlots("P_dead_maintained", "%.6g" % P_dead_maintained)
106         return ctx.tag
107
108     def render_report_span(self, ctx, row):
109         (when, unmaintained_shareprobs, maintained_shareprobs,
110          P_repaired_last_check_period,
111          cumulative_number_of_repairs,
112          cumulative_number_of_new_shares,
113          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
114         return ctx.tag[yandm(when)]
115
116     def render_P_loss_unmaintained(self, ctx, row):
117         (when, unmaintained_shareprobs, maintained_shareprobs,
118          P_repaired_last_check_period,
119          cumulative_number_of_repairs,
120          cumulative_number_of_new_shares,
121          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
122         return ctx.tag["%.6g (%1.8f%%)" % (P_dead_unmaintained,
123                                            100*P_dead_unmaintained)]
124
125     def render_P_loss_maintained(self, ctx, row):
126         (when, unmaintained_shareprobs, maintained_shareprobs,
127          P_repaired_last_check_period,
128          cumulative_number_of_repairs,
129          cumulative_number_of_new_shares,
130          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
131         return ctx.tag["%.6g (%1.8f%%)" % (P_dead_maintained,
132                                            100*P_dead_maintained)]
133
134     def render_P_repair_rate(self, ctx, row):
135         (when, unmaintained_shareprobs, maintained_shareprobs,
136          P_repaired_last_check_period,
137          cumulative_number_of_repairs,
138          cumulative_number_of_new_shares,
139          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
140         freq = when / cumulative_number_of_repairs
141         return ctx.tag["%.6g" % freq]
142
143     def render_P_repair_shares(self, ctx, row):
144         (when, unmaintained_shareprobs, maintained_shareprobs,
145          P_repaired_last_check_period,
146          cumulative_number_of_repairs,
147          cumulative_number_of_new_shares,
148          P_dead_unmaintained, P_dead_maintained) = self.results.samples[-1]
149         generated_shares = cumulative_number_of_new_shares / cumulative_number_of_repairs
150         return ctx.tag["%1.2f" % generated_shares]
151
152