Reputation: 4973
The Hystrix dashboard shows executions of HystrixCommands
, but not of the HystrixObservableCommand
. We need the HystrixObservableCommand
, as we're wrapping an async HTTP call. The code below shows an example which we tracked in the dashboard. Integration tests show that the call is properly executed, the stream mentions the AsyncHttpCommand
, but never tracks any hits.
void aMethod(A requestHeaders, B asyncContext, C message) {
// this is tracked
new DummyCommand().execute();
// this not
Observable<Response> observable = new AsyncHttpCommand(builder.setHeaders(requestHeaders), message).construct();
observable.subscribe(createObserver(asyncContext, message));
}
// we added and removed some properties without any change on the tracking
private final HystrixCommandProperties.Setter defaultProperties = HystrixCommandProperties.Setter()
.withExecutionIsolationSemaphoreMaxConcurrentRequests(400)
.withFallbackIsolationSemaphoreMaxConcurrentRequests(400)
.withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE)
.withExecutionTimeoutInMilliseconds(10000)
.withExecutionTimeoutEnabled(true)
.withFallbackEnabled(true)
.withCircuitBreakerEnabled(true)
.withCircuitBreakerErrorThresholdPercentage(50)
.withCircuitBreakerRequestVolumeThreshold(20)
.withCircuitBreakerSleepWindowInMilliseconds(5000)
.withCircuitBreakerForceOpen(false)
.withCircuitBreakerForceClosed(false);
private class DummyCommand extends HystrixCommand<String> {
protected DummyCommand() {
super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("default"))
.andCommandPropertiesDefaults(defaultProperties));
}
@Override
protected String run() throws Exception {
return "test";
}
}
private class AsyncHttpCommand extends HystrixObservableCommand<Response> {
private BoundRequestBuilder builder;
protected AsyncHttpCommand(final BoundRequestBuilder builder) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("default2"))
.andCommandPropertiesDefaults(defaultProperties));
this.builder = builder;
}
@Override
protected Observable<Response> construct() {
return Observable.from(builder.execute()).subscribeOn(Schedulers.io());
}
}
private Observer<? super Response> createObserver(final AsyncContext asyncContext, final SentRequestMessage message) {
return new Observer<Response>() {
@Override
public void onCompleted() {
// was never reached
}
@Override
public void onError(final Throwable throwable) {
// should not be reached, as fallback kicks in
}
@Override
public void onNext(final Response response) {
// omitted result handling ...
}
};
}
web.xml
<servlet>
<description></description>
<display-name>HystrixMetricsStreamServlet</display-name>
<servlet-name>HystrixMetricsStreamServlet</servlet-name>
<servlet-class>com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HystrixMetricsStreamServlet</servlet-name>
<url-pattern>/hystrix.stream</url-pattern>
</servlet-mapping>
pom.xml
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>1.4.10</version>
</dependency>
Am I doing anything wrong with the AsyncHttpCommand
? What needs to be changed/added, so that the hystrix stream will also show hits of that command.
Upvotes: 0
Views: 307
Reputation: 4973
The commands were correct, but we have to use observe()
instead of construct()
.
Observable<Response> observable = new AsyncHttpCommand(builder.setHeaders(requestHeaders), message)
.observe();
observable.subscribe(createObserver(asyncContext, message));
Upvotes: 1