2 from nevow import rend, tags as T
3 reliability = None # might not be usable
5 from allmydata import reliability # requires NumPy
8 from allmydata.web.common import getxmlfile, get_arg
21 return "%dy.%dm" % (int(seconds/YEAR), int( (seconds%YEAR)/MONTH))
23 class ReliabilityTool(rend.Page):
25 docFactory = getxmlfile("reliability.xhtml")
27 DEFAULT_PARAMETERS = [
28 ("drive_lifetime", "8Y", "time",
29 "Average drive lifetime"),
31 "Minimum number of shares needed to recover the file"),
33 "Repair threshold: repair will not occur until fewer than R shares "
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"),
46 def parse_time(self, s):
48 return int(s[:-1]) * MONTH
50 return int(s[:-1]) * YEAR
53 def format_time(self, s):
55 return "%dY" % (s/YEAR)
57 return "%dM" % (s/MONTH)
60 def get_parameters(self, ctx):
62 for (name,default,argtype,description) in self.DEFAULT_PARAMETERS:
63 v = get_arg(ctx, name, default)
65 value = self.parse_time(v)
68 parameters[name] = value
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)
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))
80 def render_forms(self, ctx, data):
81 f = T.form(action=".", method="get")
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],
92 def data_simulation_table(self, ctx, data):
93 for row in self.results.samples:
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)
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)]
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)]
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)]
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]
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]