Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit 78b30a9

Browse files
authored
Synchronize the access to the tree, views and measures for Statsz. (#1006)
1 parent a20ca2e commit 78b30a9

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

contrib/zpages/src/main/java/io/opencensus/contrib/zpages/StatszZPageHandler.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import java.util.Map.Entry;
6060
import java.util.Set;
6161
import java.util.SortedMap;
62+
import javax.annotation.concurrent.GuardedBy;
6263

6364
/*>>>
6465
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -67,9 +68,22 @@
6768
/** HTML page formatter for all exported {@link View}s. */
6869
final class StatszZPageHandler extends ZPageHandler {
6970

71+
private static final Object monitor = new Object();
72+
7073
private final ViewManager viewManager;
74+
75+
// measures, cachedViews and root are created when StatszZPageHandler is initialized, and will
76+
// be updated every time when there's a new View from viewManager.getAllExportedViews().
77+
// viewManager.getAllExportedViews() will be called every time when the StatsZ page is
78+
// re-rendered, like refreshing or navigating to other paths.
79+
80+
@GuardedBy("monitor")
7181
private final Map<String, Measure> measures = Maps.newTreeMap();
82+
83+
@GuardedBy("monitor")
7284
private final Set<View> cachedViews = Sets.newHashSet();
85+
86+
@GuardedBy("monitor")
7387
private final TreeNode root = new TreeNode();
7488

7589
@VisibleForTesting static final String QUERY_PATH = "path";
@@ -139,18 +153,20 @@ private static void emitStyles(PrintWriter out, Formatter formatter) {
139153
}
140154

141155
private void emitHtmlBody(Map<String, String> queryMap, PrintWriter out, Formatter formatter) {
142-
groupViewsByDirectoriesAndGetMeasures(
143-
viewManager.getAllExportedViews(), root, measures, cachedViews);
144-
out.write("<h1><a href='?'>StatsZ</a></h1>");
145-
out.write("<p></p>");
146-
String path = queryMap.get(QUERY_PATH);
147-
TreeNode current = findNode(path);
148-
emitDirectoryTable(current, path, out, formatter);
149-
if (current != null && current.view != null) {
150-
ViewData viewData = viewManager.getView(current.view.getName());
151-
emitViewData(viewData, current.view.getName(), out, formatter);
156+
synchronized (monitor) {
157+
groupViewsByDirectoriesAndGetMeasures(
158+
viewManager.getAllExportedViews(), root, measures, cachedViews);
159+
out.write("<h1><a href='?'>StatsZ</a></h1>");
160+
out.write("<p></p>");
161+
String path = queryMap.get(QUERY_PATH);
162+
TreeNode current = findNode(path);
163+
emitDirectoryTable(current, path, out, formatter);
164+
if (current != null && current.view != null) {
165+
ViewData viewData = viewManager.getView(current.view.getName());
166+
emitViewData(viewData, current.view.getName(), out, formatter);
167+
}
168+
emitMeasureTable(measures, out, formatter);
152169
}
153-
emitMeasureTable(measures, out, formatter);
154170
}
155171

156172
// Parses view names, creates a tree that represents the directory structure and put each view
@@ -188,6 +204,7 @@ private static void groupViewsByDirectoriesAndGetMeasures(
188204
}
189205
}
190206

207+
@GuardedBy("monitor")
191208
private void emitDirectoryTable(
192209
/*@Nullable*/ TreeNode currentNode,
193210
/*@Nullable*/ String path,
@@ -223,13 +240,13 @@ private void emitDirectoryTable(
223240
CLASS_LARGER_TR, QUERY_PATH, path + '/' + relativePath, viewName);
224241
}
225242
}
226-
227243
out.write("</table>");
228244
out.write("<p></p>");
229245
}
230246

231247
// Searches the TreeNode whose absolute path matches the given path, started from root.
232248
// Returns null if such a TreeNode doesn't exist.
249+
@GuardedBy("monitor")
233250
private /*@Nullable*/ TreeNode findNode(/*@Nullable*/ String path) {
234251
if (Strings.isNullOrEmpty(path) || "/".equals(path)) { // Go back to the root directory.
235252
return root;
@@ -485,7 +502,8 @@ private static void emitHistogramBuckets(
485502

486503
private static void emitMeasureTable(
487504
Map<String, Measure> measures, PrintWriter out, Formatter formatter) {
488-
out.write("<h2>Measures</h2>");
505+
out.write("<h2>Measures with Views</h2>");
506+
out.write("<p>Below are the measures used in registered views.</p>");
489507
out.write("<p></p>");
490508
formatter.format("<table %s frame=box cellspacing=0 cellpadding=2>", TABLE_BORDER);
491509
emitMeasureTableHeader(out, formatter);

0 commit comments

Comments
 (0)