List of usage examples for java.util Observable.OnSubscribe Observable.OnSubscribe
Observable.OnSubscribe
From source file:org.apache.usergrid.corepersistence.asyncevents.AsyncEventServiceImpl.java
private void startWorker(final String type) { Preconditions.checkNotNull(type, "Worker type required"); synchronized (mutex) { boolean isUtilityQueue = isNotEmpty(type) && type.toLowerCase().contains(QUEUE_NAME_UTILITY.toLowerCase()); Observable<List<QueueMessage>> consumer = Observable .create(new Observable.OnSubscribe<List<QueueMessage>>() { @Override//from w w w . j a va 2 s. c o m public void call(final Subscriber<? super List<QueueMessage>> subscriber) { //name our thread so it's easy to see long threadNum = isUtilityQueue ? counterUtility.incrementAndGet() : counter.incrementAndGet(); Thread.currentThread().setName("QueueConsumer_" + type + "_" + threadNum); List<QueueMessage> drainList = null; do { try { if (isUtilityQueue) { drainList = takeFromUtilityQueue(); } else { drainList = take(); } //emit our list in it's entity to hand off to a worker pool subscriber.onNext(drainList); //take since we're in flight inFlight.addAndGet(drainList.size()); } catch (Throwable t) { final long sleepTime = indexProcessorFig.getFailureRetryTime(); logger.error("Failed to dequeue. Sleeping for {} milliseconds", sleepTime, t); if (drainList != null) { inFlight.addAndGet(-1 * drainList.size()); } try { Thread.sleep(sleepTime); } catch (InterruptedException ie) { //swallow } indexErrorCounter.inc(); } } while (true); } }) //this won't block our read loop, just reads and proceeds .flatMap(sqsMessages -> { //do this on a different schedule, and introduce concurrency with flatmap for faster processing return Observable.just(sqsMessages) .map(messages -> { if (messages == null || messages.size() == 0) { // no messages came from the queue, move on return null; } try { // process the messages List<IndexEventResult> indexEventResults = callEventHandlers(messages); // submit the processed messages to index producer List<QueueMessage> messagesToAck = submitToIndex(indexEventResults, isUtilityQueue); if (messagesToAck.size() < messages.size()) { logger.warn("Missing {} message(s) from index processing", messages.size() - messagesToAck.size()); } // ack each message if making it to this point if (messagesToAck.size() > 0) { if (isUtilityQueue) { ackUtilityQueue(messagesToAck); } else { ack(messagesToAck); } } return messagesToAck; } catch (Exception e) { logger.error("Failed to ack messages", e); return null; //do not rethrow so we can process all of them } }).subscribeOn(rxTaskScheduler.getAsyncIOScheduler()); //end flatMap }, indexProcessorFig.getEventConcurrencyFactor()); //start in the background final Subscription subscription = consumer.subscribeOn(Schedulers.newThread()).subscribe(); subscriptions.add(subscription); } }