[tor-commits] [tor/master] Separate generation of a buffer-stats string from writing it to disk.
nickm at torproject.org
nickm at torproject.org
Thu Aug 4 19:47:08 UTC 2011
commit 07dc46e7fc7275fa1fcd365e34f318aa164fe7f1
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Wed Aug 3 13:26:49 2011 +0200
Separate generation of a buffer-stats string from writing it to disk.
The new rep_hist_format_buffer_stats() generates a buffer-stats string
that rep_hist_buffer_stats_write() writes to disk. All the state
changing (e.g., resetting the buffer-stats history and initializing
the next measurement interval) takes place in
rep_hist_buffer_stats_write(). That allows us to finally test the
buffer-stats code better.
---
src/or/rephist.c | 119 +++++++++++++++++++++++++++++++-----------------------
src/or/rephist.h | 2 +
2 files changed, 71 insertions(+), 50 deletions(-)
diff --git a/src/or/rephist.c b/src/or/rephist.c
index ce0152e..1b43e5c 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -2420,42 +2420,41 @@ _buffer_stats_compare_entries(const void **_a, const void **_b)
void
rep_hist_buffer_stats_term(void)
{
- start_of_buffer_stats_interval = 0;
+ rep_hist_reset_buffer_stats(0);
+}
+
+/** Clear history of circuit statistics and set the measurement interval
+ * start to <b>now</b>. */
+void
+rep_hist_reset_buffer_stats(time_t now)
+{
if (!circuits_for_buffer_stats)
circuits_for_buffer_stats = smartlist_create();
SMARTLIST_FOREACH(circuits_for_buffer_stats, circ_buffer_stats_t *,
stat, tor_free(stat));
smartlist_clear(circuits_for_buffer_stats);
+ start_of_buffer_stats_interval = now;
}
-/** Write buffer statistics to $DATADIR/stats/buffer-stats and return when
- * we would next want to write exit stats. */
-time_t
-rep_hist_buffer_stats_write(time_t now)
+/** Return a newly allocated string containing the buffer statistics until
+ * <b>now</b>, or NULL if we're not collecting buffer stats. */
+char *
+rep_hist_format_buffer_stats(time_t now)
{
- char *statsdir = NULL, *filename = NULL;
- open_file_t *open_file = NULL;
- FILE *out;
#define SHARES 10
int processed_cells[SHARES], circs_in_share[SHARES],
number_of_circuits, i;
double queued_cells[SHARES], time_in_queue[SHARES];
char *buf = NULL;
- circuit_t *circ;
smartlist_t *processed_cells_strings, *queued_cells_strings,
*time_in_queue_strings;
char *processed_cells_string, *queued_cells_string,
*time_in_queue_string;
char t[ISO_TIME_LEN+1];
+ char *result;
if (!start_of_buffer_stats_interval)
- return 0; /* Not initialized. */
- if (start_of_buffer_stats_interval + WRITE_STATS_INTERVAL > now)
- goto done; /* Not ready to write */
-
- /* add current circuits to stats */
- for (circ = _circuit_get_global_list(); circ; circ = circ->next)
- rep_hist_buffer_stats_add_circ(circ, now);
+ return NULL; /* Not initialized. */
/* Calculate deciles if we saw at least one circuit. */
memset(processed_cells, 0, SHARES * sizeof(int));
@@ -2481,11 +2480,6 @@ rep_hist_buffer_stats_write(time_t now)
SMARTLIST_FOREACH_END(stat);
}
- /* clear buffer stats history */
- SMARTLIST_FOREACH(circuits_for_buffer_stats, circ_buffer_stats_t *,
- stat, tor_free(stat));
- smartlist_clear(circuits_for_buffer_stats);
-
/* Write deciles to strings. */
processed_cells_strings = smartlist_create();
queued_cells_strings = smartlist_create();
@@ -2520,41 +2514,66 @@ rep_hist_buffer_stats_write(time_t now)
smartlist_free(queued_cells_strings);
smartlist_free(time_in_queue_strings);
- /* Write everything to disk. */
+ /* Put everything together. */
+ format_iso_time(t, now);
+ tor_asprintf(&result, "cell-stats-end %s (%d s)\n"
+ "cell-processed-cells %s\n"
+ "cell-queued-cells %s\n"
+ "cell-time-in-queue %s\n"
+ "cell-circuits-per-decile %d\n",
+ t, (unsigned) (now - start_of_buffer_stats_interval),
+ processed_cells_string,
+ queued_cells_string,
+ time_in_queue_string,
+ (number_of_circuits + SHARES - 1) / SHARES);
+ tor_free(processed_cells_string);
+ tor_free(queued_cells_string);
+ tor_free(time_in_queue_string);
+ return result;
+#undef SHARES
+}
+
+/** If 24 hours have passed since the beginning of the current buffer
+ * stats period, write buffer stats to $DATADIR/stats/buffer-stats
+ * (possibly overwriting an existing file) and reset counters. Return
+ * when we would next want to write buffer stats or 0 if we never want to
+ * write. */
+time_t
+rep_hist_buffer_stats_write(time_t now)
+{
+ circuit_t *circ;
+ char *statsdir = NULL, *filename = NULL, *str = NULL;
+
+ if (!start_of_buffer_stats_interval)
+ return 0; /* Not initialized. */
+ if (start_of_buffer_stats_interval + WRITE_STATS_INTERVAL > now)
+ goto done; /* Not ready to write */
+
+ /* Add open circuits to the history. */
+ for (circ = _circuit_get_global_list(); circ; circ = circ->next) {
+ rep_hist_buffer_stats_add_circ(circ, now);
+ }
+
+ /* Generate history string. */
+ str = rep_hist_format_buffer_stats(now);
+
+ /* Reset both buffer history and counters of open circuits. */
+ rep_hist_reset_buffer_stats(now);
+
+ /* Try to write to disk. */
statsdir = get_datadir_fname("stats");
- if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0)
+ if (check_private_dir(statsdir, CPD_CREATE, get_options()->User) < 0) {
+ log_warn(LD_HIST, "Unable to create stats/ directory!");
goto done;
+ }
filename = get_datadir_fname2("stats", "buffer-stats");
- out = start_writing_to_stdio_file(filename, OPEN_FLAGS_REPLACE | O_TEXT,
- 0600, &open_file);
- if (!out)
- goto done;
- format_iso_time(t, now);
- if (fprintf(out, "cell-stats-end %s (%d s)\n", t,
- (unsigned) (now - start_of_buffer_stats_interval)) < 0)
- goto done;
- if (fprintf(out, "cell-processed-cells %s\n", processed_cells_string)
- < 0)
- goto done;
- if (fprintf(out, "cell-queued-cells %s\n", queued_cells_string) < 0)
- goto done;
- if (fprintf(out, "cell-time-in-queue %s\n", time_in_queue_string) < 0)
- goto done;
- if (fprintf(out, "cell-circuits-per-decile %d\n",
- (number_of_circuits + SHARES - 1) / SHARES) < 0)
- goto done;
- finish_writing_to_file(open_file);
- open_file = NULL;
- start_of_buffer_stats_interval = now;
+ if (write_str_to_file(filename, str, 0) < 0)
+ log_warn(LD_HIST, "Unable to write buffer stats to disk!");
+
done:
- if (open_file)
- abort_writing_to_file(open_file);
+ tor_free(str);
tor_free(filename);
tor_free(statsdir);
- tor_free(processed_cells_string);
- tor_free(queued_cells_string);
- tor_free(time_in_queue_string);
-#undef SHARES
return start_of_buffer_stats_interval + WRITE_STATS_INTERVAL;
}
diff --git a/src/or/rephist.h b/src/or/rephist.h
index 5748748..13dee15 100644
--- a/src/or/rephist.h
+++ b/src/or/rephist.h
@@ -77,6 +77,8 @@ void rep_hist_buffer_stats_add_circ(circuit_t *circ,
time_t end_of_interval);
time_t rep_hist_buffer_stats_write(time_t now);
void rep_hist_buffer_stats_term(void);
+char *rep_hist_format_buffer_stats(time_t now);
+void rep_hist_reset_buffer_stats(time_t now);
void rep_hist_conn_stats_init(time_t now);
void rep_hist_note_or_conn_bytes(uint64_t conn_id, size_t num_read,
More information about the tor-commits
mailing list