Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use getExecutionException to handle timeout, short-circuit, etc... exceptions #1168

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
6f162a7
Javanica HystrixRequestCacheManager should use the concurrency strategy
jhinch-at-atlassian-com Feb 26, 2016
c7f9cfb
Merge pull request #1108 from jhinch/javanica-plugins-concurrency-str…
mattrjacobs Feb 29, 2016
6869ec3
Upgrade to RxJava 1.1.1
Feb 29, 2016
e5978f9
Upgrade netflixoss Nebula plugin to 3.2.3
Feb 8, 2016
a0d97f8
Special casing the 2 WAR artifacts to not have POMs rewritten
Feb 11, 2016
9ef5b6e
Merge pull request #1110 from mattrjacobs/upgrade-14x-to-rx-1-1-1
mattrjacobs Feb 29, 2016
0d38591
Removing println in build.gradle
Feb 29, 2016
ced9f74
Merge pull request #1112 from mattrjacobs/upgrade-14x-nebula-oss
mattrjacobs Feb 29, 2016
b6fa398
Made HystrixRequestContext Closeable so we can leverage try-with-reso…
velo Feb 29, 2016
b3d74a5
Merge pull request #1113 from mattrjacobs/backport-closeable-to-14x
mattrjacobs Feb 29, 2016
b525240
Making the HystrixTimeoutException instance per-command, not static
Mar 7, 2016
5629563
Merge pull request #1121 from mattrjacobs/1.4.x-nonstatic-timeout-exc…
mattrjacobs Mar 7, 2016
a88b30b
#1109 MetricJsonListener queue size can be configured by passing addi…
Feb 29, 2016
1410bee
#1109 Make default metric listener queue size configurable by propert…
Mar 2, 2016
ee6c90a
#1109 Rolling back request parameter support for setting queueSize
Mar 11, 2016
6f55c0a
Merge pull request #1114 from anuragw/1.4.x
mattrjacobs Mar 11, 2016
60f417a
Use getExecutionException to handle timeout, short-circuit, etc... ex…
spencergibb Apr 1, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 19 additions & 17 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

plugins {
id 'nebula.netflixoss' version '3.1.2'
id 'nebula.netflixoss' version '3.2.3'
id 'me.champeau.gradle.jmh' version '0.2.0'
id 'net.saliman.cobertura' version '2.2.8'
}
Expand Down Expand Up @@ -58,22 +58,24 @@ subprojects {
publishing {
publications {
nebula(MavenPublication) {
pom.withXml {
configurations.compile.resolvedConfiguration.firstLevelModuleDependencies.each { dep ->
if (dep.moduleName == "servlet-api") {
asNode().dependencies[0].dependency.find {
it.artifactId[0].text() == dep.moduleName &&
it.groupId[0].text() == dep.moduleGroup
}.scope[0].value = 'provided'
} else {
asNode().dependencies[0].dependency.find {
it.artifactId[0].text() == dep.moduleName &&
it.groupId[0].text() == dep.moduleGroup
}.scope[0].value = 'compile'
}
}
}
}
if (!project.name.equals("hystrix-dashboard") && !project.name.equals("hystrix-examples-webapp")) {
pom.withXml {
configurations.compile.resolvedConfiguration.firstLevelModuleDependencies.each { dep ->
if (dep.moduleName == "servlet-api") {
asNode().dependencies[0].dependency.find {
it.artifactId[0].text() == dep.moduleName &&
it.groupId[0].text() == dep.moduleGroup
}.scope[0].value = 'provided'
} else {
asNode().dependencies[0].dependency.find {
it.artifactId[0].text() == dep.moduleName &&
it.groupId[0].text() == dep.moduleGroup
}.scope[0].value = 'compile'
}
}
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion hystrix-contrib/hystrix-javanica/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ If fallback method was marked with `@HystrixCommand` then this fallback method (
}
```

Javanica provides an ability to get execution exception (exception thrown that caused the failure of a command) within a fallback is being executed. A fallback method signature can be extended with an additional parameter in order to get an exception thrown by a command. Javanica exposes execution exception through additional parameter of fallback method. Execution exception is derived by calling method getFailedExecutionException() as in vanilla hystrix.
Javanica provides an ability to get execution exception (exception thrown that caused the failure of a command) within a fallback is being executed. A fallback method signature can be extended with an additional parameter in order to get an exception thrown by a command. Javanica exposes execution exception through additional parameter of fallback method. Execution exception is derived by calling method getExecutionException() as in vanilla hystrix.

Example:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixRequestCache;
import com.netflix.hystrix.contrib.javanica.cache.annotation.CacheRemove;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
import com.netflix.hystrix.strategy.HystrixPlugins;


/**
Expand Down Expand Up @@ -50,6 +50,6 @@ public void clearCache(CacheInvocationContext<CacheRemove> context) {
defaultCacheKeyGenerator.generateCacheKey(context);
String key = hystrixGeneratedCacheKey.getCacheKey();
HystrixRequestCache.getInstance(HystrixCommandKey.Factory.asKey(cacheName),
HystrixConcurrencyStrategyDefault.getInstance()).clear(key);
HystrixPlugins.getInstance().getConcurrencyStrategy()).clear(key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ Object process(Action action) throws Exception {
*/
@Override
protected T getFallback() {
throw new RuntimeException("No fallback available.", getFailedExecutionException());
throw new RuntimeException("No fallback available.", getExecutionException());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ protected List<Object> getFallback() {
Object execute() {
MetaHolder metaHolder = commandAction.getMetaHolder();
Object[] args = toArgs(getCollapsedRequests());
args = createArgsForFallback(args, metaHolder, getFailedExecutionException());
args = createArgsForFallback(args, metaHolder, getExecutionException());
return commandAction.executeWithArgs(commandAction.getMetaHolder().getFallbackExecutionType(), args);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected Object getFallback() {
@Override
Object execute() {
MetaHolder metaHolder = commandAction.getMetaHolder();
Object[] args = createArgsForFallback(metaHolder, getFailedExecutionException());
Object[] args = createArgsForFallback(metaHolder, getExecutionException());
return commandAction.executeWithArgs(commandAction.getMetaHolder().getFallbackExecutionType(), args);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ protected Observable construct() {
protected Observable resumeWithFallback() {
if (commandActions.hasFallbackAction()) {
MetaHolder metaHolder = commandActions.getFallbackAction().getMetaHolder();
Throwable cause = getFailedExecutionException();
Throwable cause = getExecutionException();
if (cause instanceof CommandActionExecutionException) {
cause = cause.getCause();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,20 @@
*/
package com.netflix.hystrix.contrib.metrics.eventstream;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.netflix.config.DynamicIntProperty;
import com.netflix.config.DynamicPropertyFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Streams Hystrix metrics in text/event-stream format.
Expand Down Expand Up @@ -62,6 +60,7 @@ public class HystrixMetricsStreamServlet extends HttpServlet {
/* used to track number of connections and throttle */
private static AtomicInteger concurrentConnections = new AtomicInteger(0);
private static DynamicIntProperty maxConcurrentConnections = DynamicPropertyFactory.getInstance().getIntProperty("hystrix.stream.maxConcurrentConnections", 5);
private static DynamicIntProperty defaultMetricListenerQueueSize = DynamicPropertyFactory.getInstance().getIntProperty("hystrix.stream.defaultMetricListenerQueueSize", 1000);

private static volatile boolean isDestroyed = false;

Expand Down Expand Up @@ -135,7 +134,9 @@ private void handleRequest(HttpServletRequest request, HttpServletResponse respo
response.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
response.setHeader("Pragma", "no-cache");

MetricJsonListener jsonListener = new MetricJsonListener();
int queueSize = defaultMetricListenerQueueSize.get();

MetricJsonListener jsonListener = new MetricJsonListener(queueSize);
poller = new HystrixMetricsPoller(jsonListener, delay);
// start polling and it will write directly to the output stream
poller.start();
Expand Down Expand Up @@ -207,7 +208,11 @@ private static class MetricJsonListener implements HystrixMetricsPoller.MetricsA
* <p>
* This is a safety check against a runaway poller causing memory leaks.
*/
private final LinkedBlockingQueue<String> jsonMetrics = new LinkedBlockingQueue<String>(1000);
private LinkedBlockingQueue<String> jsonMetrics;

public MetricJsonListener(int queueSize) {
jsonMetrics = new LinkedBlockingQueue<String>(queueSize);
}

/**
* Store JSON messages in a queue.
Expand Down
2 changes: 1 addition & 1 deletion hystrix-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apply plugin: 'me.champeau.gradle.jmh'

dependencies {
compile 'com.netflix.archaius:archaius-core:0.4.1'
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxjava:1.1.1'
compile 'org.slf4j:slf4j-api:1.7.0'
testCompile 'junit:junit-dep:4.10'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -931,8 +931,6 @@ protected boolean shouldOutputOnNextEvents() {
return false;
}

private static final HystrixTimeoutException TIMEOUT_EXCEPTION_INSTANCE = new HystrixTimeoutException();

private static class HystrixObservableTimeoutOperator<R> implements Operator<R, R> {

final AbstractCommand<R> originalCommand;
Expand All @@ -955,7 +953,7 @@ public Subscriber<? super R> call(final Subscriber<? super R> child) {

@Override
public void run() {
child.onError(TIMEOUT_EXCEPTION_INSTANCE);
child.onError(new HystrixTimeoutException());
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.netflix.hystrix.strategy.concurrency;

import java.io.Closeable;
import java.util.concurrent.ConcurrentHashMap;

import com.netflix.hystrix.HystrixCollapser;
Expand Down Expand Up @@ -60,7 +61,7 @@
* <p>
* <b>NOTE:</b> If <code>initializeContext()</code> is called then <code>shutdown()</code> must also be called or a memory leak will occur.
*/
public class HystrixRequestContext {
public class HystrixRequestContext implements Closeable {

/*
* ThreadLocal on each thread will hold the HystrixRequestVariableState.
Expand Down Expand Up @@ -142,4 +143,16 @@ public void shutdown() {
state = null;
}
}
}

/**
* Shutdown {@link HystrixRequestVariableDefault} objects in this context.
* <p>
* <b>NOTE: This must be called if <code>initializeContext()</code> was called or a memory leak will occur.</b>
*
* This method invokes <code>shutdown()</code>
*/
public void close() {
shutdown();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ public void testRequestVariableLifecycle1() throws Exception {
System.out.println("tasks in test: " + timer.tasks);

// simulate request lifecycle
requestContext.shutdown();
requestContext.close();

System.out.println("timer.tasks.size() B: " + timer.tasks.size());

Expand Down Expand Up @@ -454,7 +454,7 @@ public void run() {
}

// simulate request lifecycle
requestContext.shutdown();
requestContext.close();

HystrixRequestVariableHolder<RequestCollapser<?, ?, ?>> rv = RequestCollapserFactory.getRequestVariable(new TestRequestCollapser(timer, 1).getCollapserKey().name());

Expand Down