Skip to content

Commit

Permalink
Plugin for controlling whether or not to fill in stacktraces (#124)
Browse files Browse the repository at this point in the history
* Implement fillInOutsideLifecycleExceptionStacktraces plugin

This implements support for controlling whether or not `OutsideLifecycleException`s fill in their stacktraces. This is a potentially expensive operation that is often used just for signaling, so we can save a little perf here.

* Add tests
  • Loading branch information
ZacSweers authored Oct 30, 2017
1 parent b8aa665 commit 5b35ba8
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ private AutoDisposePlugins() { }

@Nullable
private static volatile Consumer<? super OutsideLifecycleException> outsideLifecycleHandler;
private static volatile boolean fillInOutsideLifecycleExceptionStacktraces;

/**
* Prevents changing the plugins.
Expand All @@ -53,7 +54,15 @@ public static boolean isLockdown() {
}

/**
* @return the consumer for handling {@link OutsideLifecycleException}.
* @return the value indicating whether or not to fill in stacktraces in
* {@link OutsideLifecycleException}.
*/
public static boolean getFillInOutsideLifecycleExceptionStacktraces() {
return fillInOutsideLifecycleExceptionStacktraces;
}

/**
* @return the value for handling {@link OutsideLifecycleException}.
*/
@Nullable
public static Consumer<? super OutsideLifecycleException> getOutsideLifecycleHandler() {
Expand All @@ -71,6 +80,19 @@ public static void setOutsideLifecycleHandler(
outsideLifecycleHandler = handler;
}

/**
* @param fillInStacktrace {@code true} to fill in stacktraces in
* {@link OutsideLifecycleException}s. {@code false} to disable them (and use them as signals
* only). Disabling them, if you don't care about the stacktraces, can result in some minor
* performance improvements.
*/
public static void setFillInOutsideLifecycleExceptionStacktraces(boolean fillInStacktrace) {
if (lockdown) {
throw new IllegalStateException("Plugins can't be changed anymore");
}
fillInOutsideLifecycleExceptionStacktraces = fillInStacktrace;
}

/**
* Removes all handlers and resets to default behavior.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,12 @@ public class OutsideLifecycleException extends RuntimeException {
public OutsideLifecycleException(String s) {
super(s);
}

@Override public final synchronized Throwable fillInStackTrace() {
if (AutoDisposePlugins.getFillInOutsideLifecycleExceptionStacktraces()) {
return super.fillInStackTrace();
} else {
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2017. Uber Technologies
*
* Licensed 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 com.uber.autodispose;

import org.junit.After;
import org.junit.Test;

import static com.google.common.truth.Truth.assertThat;

public final class AutoDisposePluginsTest {

@After public void tearDown() {
AutoDisposePlugins.reset();
}

@Test public void noStacktraceFill_shouldHaveNoStacktrace() {
AutoDisposePlugins.setFillInOutsideLifecycleExceptionStacktraces(false);

LifecycleNotStartedException started =
new LifecycleNotStartedException("Lifecycle not started");
assertThat(started.getStackTrace()).isEmpty();

LifecycleEndedException ended = new LifecycleEndedException("Lifecycle ended");
assertThat(ended.getStackTrace()).isEmpty();
}

@Test public void defaultStacktraceFill_shouldHaveStacktrace() {
LifecycleNotStartedException started =
new LifecycleNotStartedException("Lifecycle not started");
assertThat(started.getStackTrace()).isNotEmpty();

LifecycleEndedException ended = new LifecycleEndedException("Lifecycle ended");
assertThat(ended.getStackTrace()).isNotEmpty();
}

@Test public void trueStacktraceFill_shouldHaveStacktrace() {
AutoDisposePlugins.setFillInOutsideLifecycleExceptionStacktraces(true);

LifecycleNotStartedException started =
new LifecycleNotStartedException("Lifecycle not started");
assertThat(started.getStackTrace()).isNotEmpty();

LifecycleEndedException ended = new LifecycleEndedException("Lifecycle ended");
assertThat(ended.getStackTrace()).isNotEmpty();
}
}

0 comments on commit 5b35ba8

Please sign in to comment.