use of rx.Subscription in project Hystrix by Netflix.
the class HystrixSampleSseServlet method handleRequest.
/**
* - maintain an open connection with the client
* - on initial connection send latest data of each requested event type
* - subsequently send all changes for each requested event type
*
* @param request incoming HTTP Request
* @param response outgoing HTTP Response (as a streaming response)
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
private void handleRequest(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
final AtomicBoolean moreDataWillBeSent = new AtomicBoolean(true);
Subscription sampleSubscription = null;
/* ensure we aren't allowing more connections than we want */
int numberConnections = incrementAndGetCurrentConcurrentConnections();
try {
//may change at runtime, so look this up for each request
int maxNumberConnectionsAllowed = getMaxNumberConcurrentConnectionsAllowed();
if (numberConnections > maxNumberConnectionsAllowed) {
response.sendError(503, "MaxConcurrentConnections reached: " + maxNumberConnectionsAllowed);
} else {
/* initialize response */
response.setHeader("Content-Type", "text/event-stream;charset=UTF-8");
response.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
response.setHeader("Pragma", "no-cache");
final PrintWriter writer = response.getWriter();
//since the sample stream is based on Observable.interval, events will get published on an RxComputation thread
//since writing to the servlet response is blocking, use the Rx IO thread for the write that occurs in the onNext
sampleSubscription = sampleStream.observeOn(Schedulers.io()).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
logger.error("HystrixSampleSseServlet: ({}) received unexpected OnCompleted from sample stream", getClass().getSimpleName());
moreDataWillBeSent.set(false);
}
@Override
public void onError(Throwable e) {
moreDataWillBeSent.set(false);
}
@Override
public void onNext(String sampleDataAsString) {
if (sampleDataAsString != null) {
writer.print("data: " + sampleDataAsString + "\n\n");
// explicitly check for client disconnect - PrintWriter does not throw exceptions
if (writer.checkError()) {
moreDataWillBeSent.set(false);
}
writer.flush();
}
}
});
while (moreDataWillBeSent.get() && !isDestroyed) {
try {
Thread.sleep(pausePollerThreadDelayInMs);
//in case stream has not started emitting yet, catch any clients which connect/disconnect before emits start
writer.print("ping: \n\n");
// explicitly check for client disconnect - PrintWriter does not throw exceptions
if (writer.checkError()) {
moreDataWillBeSent.set(false);
}
writer.flush();
} catch (InterruptedException e) {
moreDataWillBeSent.set(false);
}
}
}
} finally {
decrementCurrentConcurrentConnections();
if (sampleSubscription != null && !sampleSubscription.isUnsubscribed()) {
sampleSubscription.unsubscribe();
}
}
}
use of rx.Subscription in project Hystrix by Netflix.
the class BucketedCounterStream method unsubscribe.
public void unsubscribe() {
Subscription s = subscription.get();
if (s != null) {
s.unsubscribe();
subscription.compareAndSet(s, null);
}
}
use of rx.Subscription in project Hystrix by Netflix.
the class RollingConcurrencyStream method unsubscribe.
public void unsubscribe() {
Subscription s = rollingMaxSubscription.get();
if (s != null) {
s.unsubscribe();
rollingMaxSubscription.compareAndSet(s, null);
}
}
use of rx.Subscription in project Hystrix by Netflix.
the class RollingDistributionStream method unsubscribe.
public void unsubscribe() {
Subscription s = rollingDistributionSubscription.get();
if (s != null) {
s.unsubscribe();
rollingDistributionSubscription.compareAndSet(s, null);
}
}
use of rx.Subscription in project Hystrix by Netflix.
the class HystrixStreamingOutputProvider method writeTo.
@Override
public void writeTo(HystrixStream o, Class<?> t, Type gt, Annotation[] as, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, final OutputStream entity) throws IOException {
Subscription sampleSubscription = null;
final AtomicBoolean moreDataWillBeSent = new AtomicBoolean(true);
try {
sampleSubscription = o.getSampleStream().observeOn(Schedulers.io()).subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
LOGGER.error("HystrixSampleSseServlet: ({}) received unexpected OnCompleted from sample stream", getClass().getSimpleName());
moreDataWillBeSent.set(false);
}
@Override
public void onError(Throwable e) {
moreDataWillBeSent.set(false);
}
@Override
public void onNext(String sampleDataAsString) {
if (sampleDataAsString != null) {
try {
entity.write(("data: " + sampleDataAsString + "\n\n").getBytes());
entity.flush();
} catch (IOException ioe) {
moreDataWillBeSent.set(false);
}
}
}
});
while (moreDataWillBeSent.get()) {
try {
Thread.sleep(o.getPausePollerThreadDelayInMs());
} catch (InterruptedException e) {
moreDataWillBeSent.set(false);
}
}
} finally {
o.getConcurrentConnections().decrementAndGet();
if (sampleSubscription != null && !sampleSubscription.isUnsubscribed()) {
sampleSubscription.unsubscribe();
}
}
}
Aggregations