Repository: incubator-wave Updated Branches: refs/heads/master b77f7f5e0 -> 5abfce6c7
Improves/refactors profiling code. https://reviews.apache.org/r/23166/ Project: http://git-wip-us.apache.org/repos/asf/incubator-wave/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-wave/commit/5abfce6c Tree: http://git-wip-us.apache.org/repos/asf/incubator-wave/tree/5abfce6c Diff: http://git-wip-us.apache.org/repos/asf/incubator-wave/diff/5abfce6c Branch: refs/heads/master Commit: 5abfce6c7059e7abdb17c847687e9c1f6a93b689 Parents: b77f7f5 Author: Andrew Kaplanov <[email protected]> Authored: Wed Jul 9 21:08:19 2014 +0300 Committer: Yuri Zelikov <[email protected]> Committed: Wed Jul 9 21:08:19 2014 +0300 ---------------------------------------------------------------------- .../server/executor/RequestScopeExecutor.java | 2 +- .../executor/ScheduledRequestScopeExecutor.java | 13 ++- .../box/server/rpc/WebSocketChannel.java | 4 +- .../server/stat/MultiThreadedRequestScope.java | 9 -- .../box/server/stat/RequestScopeFilter.java | 2 +- .../waveprotocol/box/stat/AsyncCallContext.java | 2 +- .../box/stat/SingleThreadedRequestScope.java | 86 ------------------- src/org/waveprotocol/box/stat/StatRecorder.java | 2 +- src/org/waveprotocol/box/stat/Timing.java | 59 ++++++++++--- .../box/webclient/client/WebClient.java | 7 +- .../stat/SingleThreadedRequestScope.java | 90 ++++++++++++++++++++ .../wave/client/scheduler/TaskInfo.java | 2 +- .../client/wavepanel/event/FocusManager.java | 2 +- 13 files changed, 157 insertions(+), 123 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/server/executor/RequestScopeExecutor.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/executor/RequestScopeExecutor.java b/src/org/waveprotocol/box/server/executor/RequestScopeExecutor.java index 9b2c935..40c2039 100644 --- a/src/org/waveprotocol/box/server/executor/RequestScopeExecutor.java +++ b/src/org/waveprotocol/box/server/executor/RequestScopeExecutor.java @@ -57,7 +57,7 @@ public class RequestScopeExecutor implements Executor { Preconditions.checkNotNull(executor, "Executor is not defined."); final Map<Class, RequestScope.Value> values = - Timing.isEnabled() ? Timing.getScope().cloneValues() : null; + Timing.isEnabled() ? Timing.cloneScopeValues() : null; executor.submit(new Runnable() { @Override http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/server/executor/ScheduledRequestScopeExecutor.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/executor/ScheduledRequestScopeExecutor.java b/src/org/waveprotocol/box/server/executor/ScheduledRequestScopeExecutor.java index 824a7d5..f841667 100644 --- a/src/org/waveprotocol/box/server/executor/ScheduledRequestScopeExecutor.java +++ b/src/org/waveprotocol/box/server/executor/ScheduledRequestScopeExecutor.java @@ -30,7 +30,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.logging.Level; import java.util.logging.Logger; import org.waveprotocol.box.stat.RequestScope; @@ -150,16 +149,16 @@ public class ScheduledRequestScopeExecutor implements ScheduledExecutorService { public void execute(Runnable r) { throw new UnsupportedOperationException(); } - + private Runnable makeScopedRunnable(final Runnable runnable) { final Map<Class, RequestScope.Value> scopeValues - = (Timing.isEnabled()) ? Timing.getScope().cloneValues() : null; + = (Timing.isEnabled()) ? Timing.cloneScopeValues() : null; return new Runnable() { @Override public void run() { if (scopeValues != null) { - Timing.getScope().enter(scopeValues); + Timing.enterScope(scopeValues); } try { runnable.run(); @@ -169,16 +168,16 @@ public class ScheduledRequestScopeExecutor implements ScheduledExecutorService { } }; } - + private <T> Callable<T> makeScopedCallable(final Callable<T> callable) { final Map<Class, RequestScope.Value> scopeValues - = (Timing.isEnabled()) ? Timing.getScope().cloneValues() : null; + = (Timing.isEnabled()) ? Timing.cloneScopeValues() : null; return new Callable<T> () { @Override public T call() throws Exception { if (scopeValues != null) { - Timing.getScope().enter(scopeValues); + Timing.enterScope(scopeValues); } try { return callable.call(); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/server/rpc/WebSocketChannel.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/rpc/WebSocketChannel.java b/src/org/waveprotocol/box/server/rpc/WebSocketChannel.java index 7b55dac..619b84e 100644 --- a/src/org/waveprotocol/box/server/rpc/WebSocketChannel.java +++ b/src/org/waveprotocol/box/server/rpc/WebSocketChannel.java @@ -95,7 +95,7 @@ public abstract class WebSocketChannel extends MessageExpectingChannel { public WebSocketChannel(ProtoCallback callback) { this.callback = callback; this.sessionContext = - Timing.isEnabled() ? Timing.getScope().get(SessionContext.class) : null; + Timing.isEnabled() ? Timing.getScopeValue(SessionContext.class) : null; // The ProtoSerializer could really be singleton. // TODO: Figure out a way to inject a singleton instance using Guice this.serializer = new ProtoSerializer(); @@ -105,7 +105,7 @@ public abstract class WebSocketChannel extends MessageExpectingChannel { LOG.fine("received JSON message " + data); if (Timing.isEnabled()) { Timing.enterScope(); - Timing.getScope().set(SessionContext.class, sessionContext); + Timing.setScopeValue(SessionContext.class, sessionContext); } try { Message message; http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/server/stat/MultiThreadedRequestScope.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/stat/MultiThreadedRequestScope.java b/src/org/waveprotocol/box/server/stat/MultiThreadedRequestScope.java index b473f6a..14bb168 100644 --- a/src/org/waveprotocol/box/server/stat/MultiThreadedRequestScope.java +++ b/src/org/waveprotocol/box/server/stat/MultiThreadedRequestScope.java @@ -61,29 +61,20 @@ public class MultiThreadedRequestScope implements RequestScope { @Override public <T extends RequestScope.Value> void set(Class<T> clazz, T value) { - enterIfOutOfScope(); values.get().put(clazz, value); } @Override public <T extends RequestScope.Value> T get(Class<T> clazz) { - enterIfOutOfScope(); return (T)values.get().get(clazz); } @Override public Map<Class, RequestScope.Value> cloneValues() { - enterIfOutOfScope(); Map<Class, Value> map = Maps.<Class, Value>newHashMap(); for (Map.Entry<Class, Value> entry : values.get().entrySet()) { map.put(entry.getKey(), entry.getValue().clone()); } return map; } - - private void enterIfOutOfScope() { - if (values.get() == null) { - enter(); - } - } } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/server/stat/RequestScopeFilter.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/server/stat/RequestScopeFilter.java b/src/org/waveprotocol/box/server/stat/RequestScopeFilter.java index 021739b..b925f78 100644 --- a/src/org/waveprotocol/box/server/stat/RequestScopeFilter.java +++ b/src/org/waveprotocol/box/server/stat/RequestScopeFilter.java @@ -54,7 +54,7 @@ public class RequestScopeFilter implements Filter { Timing.enterScope(); final HttpSession session = ((HttpServletRequest)request).getSession(); final ParticipantId loggedInUser = (ParticipantId)session.getAttribute(SessionManager.USER_FIELD); - Timing.getScope().set(SessionContext.class, new SessionContext() { + Timing.setScopeValue(SessionContext.class, new SessionContext() { @Override public boolean isAuthenticated() { return session != null; http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/stat/AsyncCallContext.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/stat/AsyncCallContext.java b/src/org/waveprotocol/box/stat/AsyncCallContext.java index 2f487b5..5243415 100644 --- a/src/org/waveprotocol/box/stat/AsyncCallContext.java +++ b/src/org/waveprotocol/box/stat/AsyncCallContext.java @@ -45,7 +45,7 @@ public class AsyncCallContext { Map<Class, RequestScope.Value> values = null; Timer timer = null; if (Timing.isEnabled()) { - values = Timing.getScope().cloneValues(); + values = Timing.cloneScopeValues(); ExecutionTree tree = (ExecutionTree)values.get(ExecutionTree.class); if (tree != null) { timer = tree.start(name); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/stat/SingleThreadedRequestScope.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/stat/SingleThreadedRequestScope.java b/src/org/waveprotocol/box/stat/SingleThreadedRequestScope.java deleted file mode 100644 index 6a113af..0000000 --- a/src/org/waveprotocol/box/stat/SingleThreadedRequestScope.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.waveprotocol.box.stat; - -import com.google.common.collect.Maps; -import java.util.Map; - -/** - * Request scope with execution tree and current execution node for use in single-thread environment. - * - * @author [email protected] (A. Kaplanov) - */ -@SuppressWarnings({"unchecked", "rawtypes"}) -class SingleThreadedRequestScope implements RequestScope { - - private Map<Class, Value> values; - - SingleThreadedRequestScope() { - } - - @Override - public void enter() { - values = Maps.<Class, Value>newHashMap(); - values.put(ExecutionTree.class, new ExecutionTree()); - } - - @Override - public void enter(Map<Class, Value> values) { - this.values = Maps.<Class, Value>newHashMap(values); - } - - @Override - public boolean isEntered() { - return values != null; - } - - @Override - public void exit() { - checkScoping(); - values = null; - } - - @Override - public <T extends Value> void set(Class<T> clazz, T value) { - checkScoping(); - values.put(clazz, value); - } - - @Override - public <T extends Value> T get(Class<T> clazz) { - checkScoping(); - return (T)values.get(clazz); - } - - @Override - public Map<Class, Value> cloneValues() { - checkScoping(); - Map<Class, Value> map = Maps.<Class, Value>newHashMap(); - for (Map.Entry<Class, Value> entry : values.entrySet()) { - map.put(entry.getKey(), entry.getValue().clone()); - } - return map; - } - - private void checkScoping() { - if (values == null) { - enter(); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/stat/StatRecorder.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/stat/StatRecorder.java b/src/org/waveprotocol/box/stat/StatRecorder.java index bb85ee1..9e2f9b8 100644 --- a/src/org/waveprotocol/box/stat/StatRecorder.java +++ b/src/org/waveprotocol/box/stat/StatRecorder.java @@ -75,6 +75,6 @@ class StatRecorder { } private SessionContext getSessionContext() { - return Timing.getScope().get(SessionContext.class); + return Timing.getScopeValue(SessionContext.class); } } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/stat/Timing.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/stat/Timing.java b/src/org/waveprotocol/box/stat/Timing.java index 98273b7..3ef587b 100644 --- a/src/org/waveprotocol/box/stat/Timing.java +++ b/src/org/waveprotocol/box/stat/Timing.java @@ -30,9 +30,9 @@ import java.util.Map; public class Timing { static private final StatRecorder statsRecorder = new StatRecorder(); static private final StatRenderer renderer = new StatRenderer(); - static private RequestScope scope = new SingleThreadedRequestScope(); + static private RequestScope scope; - static private boolean enabled = true; + static private boolean enabled = false; /** * Gets recorder of statistic. @@ -59,7 +59,7 @@ public class Timing { * Initializes scope. */ static public void enterScope() { - if (enabled) { + if (enabled && scope != null) { scope.enter(); } } @@ -67,9 +67,9 @@ public class Timing { /** * Initializes scope with specified data. */ - static public void enterScope(Map<Class, RequestScope.Value> scopeData) { - if (enabled) { - scope.enter(scopeData); + static public void enterScope(Map<Class, RequestScope.Value> scopeValues) { + if (enabled && scope != null && scopeValues != null) { + scope.enter(scopeValues); } } @@ -77,7 +77,9 @@ public class Timing { * Clears scope. */ static public void exitScope() { - scope.exit(); + if (scope != null) { + scope.exit(); + } } /** @@ -88,10 +90,35 @@ public class Timing { } /** - * Gets scope. + * Gets scope value. + */ + static public <T extends RequestScope.Value> T getScopeValue(Class<T> clazz) { + if (scope != null) { + enterIfOutOfScope(); + return scope.get(clazz); + } + return null; + } + + /** + * Sets scope value. + */ + static public <T extends RequestScope.Value> void setScopeValue(Class<T> clazz, T value) { + if (scope != null) { + enterIfOutOfScope(); + scope.set(clazz, value); + } + } + + /** + * Clones scope values. */ - static public RequestScope getScope() { - return scope; + static public Map<Class, RequestScope.Value> cloneScopeValues() { + if (scope != null) { + enterIfOutOfScope(); + return scope.cloneValues(); + } + return null; } /** @@ -235,6 +262,16 @@ public class Timing { * Gets execution tree. */ static private ExecutionTree getExecutionTree() { - return scope.get(ExecutionTree.class); + if (scope != null) { + enterIfOutOfScope(); + return scope.get(ExecutionTree.class); + } + return null; + } + + static private void enterIfOutOfScope() { + if (!scope.isEntered()) { + scope.enter(); + } } } http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/webclient/client/WebClient.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/webclient/client/WebClient.java b/src/org/waveprotocol/box/webclient/client/WebClient.java index 1c377fb..2a7af76 100644 --- a/src/org/waveprotocol/box/webclient/client/WebClient.java +++ b/src/org/waveprotocol/box/webclient/client/WebClient.java @@ -90,6 +90,7 @@ import java.util.Date; import java.util.Set; import java.util.logging.Logger; import org.waveprotocol.box.stat.Timing; +import org.waveprotocol.box.webclient.stat.SingleThreadedRequestScope; import org.waveprotocol.box.webclient.stat.gwtevent.GwtStatisticsEventSystem; import org.waveprotocol.box.webclient.stat.gwtevent.GwtStatisticsHandler; @@ -203,7 +204,7 @@ public class WebClient implements EntryPoint { } setupUi(); - setupGwtStatistics(); + setupStatistics(); History.fireCurrentHistoryState(); LOG.info("SimpleWebClient.onModuleLoad() done"); @@ -329,7 +330,9 @@ public class WebClient implements EntryPoint { }); } - private void setupGwtStatistics() { + private void setupStatistics() { + Timing.setScope(new SingleThreadedRequestScope()); + Timing.setEnabled(true); GwtStatisticsEventSystem eventSystem = new GwtStatisticsEventSystem(); eventSystem.addListener(new GwtStatisticsHandler(), true); eventSystem.enable(true); http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/box/webclient/stat/SingleThreadedRequestScope.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/box/webclient/stat/SingleThreadedRequestScope.java b/src/org/waveprotocol/box/webclient/stat/SingleThreadedRequestScope.java new file mode 100644 index 0000000..2dea436 --- /dev/null +++ b/src/org/waveprotocol/box/webclient/stat/SingleThreadedRequestScope.java @@ -0,0 +1,90 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.waveprotocol.box.webclient.stat; + +import com.google.common.collect.Maps; + +import org.waveprotocol.box.stat.ExecutionTree; +import org.waveprotocol.box.stat.RequestScope; + +import java.util.Map; + +/** + * Request scope with execution tree and current execution node for use in single-thread environment. + * + * @author [email protected] (A. Kaplanov) + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public class SingleThreadedRequestScope implements RequestScope { + + private Map<Class, Value> values; + + public SingleThreadedRequestScope() { + } + + @Override + public void enter() { + values = Maps.<Class, Value>newHashMap(); + values.put(ExecutionTree.class, new ExecutionTree()); + } + + @Override + public void enter(Map<Class, Value> values) { + this.values = Maps.<Class, Value>newHashMap(values); + } + + @Override + public boolean isEntered() { + return values != null; + } + + @Override + public void exit() { + checkScoping(); + values = null; + } + + @Override + public <T extends Value> void set(Class<T> clazz, T value) { + checkScoping(); + values.put(clazz, value); + } + + @Override + public <T extends Value> T get(Class<T> clazz) { + checkScoping(); + return (T)values.get(clazz); + } + + @Override + public Map<Class, Value> cloneValues() { + checkScoping(); + Map<Class, Value> map = Maps.<Class, Value>newHashMap(); + for (Map.Entry<Class, Value> entry : values.entrySet()) { + map.put(entry.getKey(), entry.getValue().clone()); + } + return map; + } + + private void checkScoping() { + if (values == null) { + enter(); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/wave/client/scheduler/TaskInfo.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/wave/client/scheduler/TaskInfo.java b/src/org/waveprotocol/wave/client/scheduler/TaskInfo.java index 420807e..171f26a 100644 --- a/src/org/waveprotocol/wave/client/scheduler/TaskInfo.java +++ b/src/org/waveprotocol/wave/client/scheduler/TaskInfo.java @@ -54,7 +54,7 @@ final class TaskInfo { this.interval = interval; this.nextExecuteTime = startTime; this.job = job; - this.scopeValues = Timing.getScope().cloneValues(); + this.scopeValues = Timing.cloneScopeValues(); } @Override http://git-wip-us.apache.org/repos/asf/incubator-wave/blob/5abfce6c/src/org/waveprotocol/wave/client/wavepanel/event/FocusManager.java ---------------------------------------------------------------------- diff --git a/src/org/waveprotocol/wave/client/wavepanel/event/FocusManager.java b/src/org/waveprotocol/wave/client/wavepanel/event/FocusManager.java index 6704ae1..4641250 100644 --- a/src/org/waveprotocol/wave/client/wavepanel/event/FocusManager.java +++ b/src/org/waveprotocol/wave/client/wavepanel/event/FocusManager.java @@ -284,7 +284,7 @@ public final class FocusManager implements Focusable, KeySignalHandler { Timer timer = null; if (Timing.isEnabled()) { Timing.enterScope(); - Timing.getScope().set(ExecutionTree.class, new ExecutionTree()); + Timing.setScopeValue(ExecutionTree.class, new ExecutionTree()); timer = Timing.start("Key event dispatch"); } try {
