com.miserablemind.api.consumer.tradeking.api.impl.StreamDispatcher.java Source code

Java tutorial

Introduction

Here is the source code for com.miserablemind.api.consumer.tradeking.api.impl.StreamDispatcher.java

Source

/*
 * Miserable Mind
 * http://www.miserablemind.com | Twitter: @lrimkus
 * The MIT License (MIT)
 */

package com.miserablemind.api.consumer.tradeking.api.impl;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.miserablemind.api.consumer.tradeking.api.StreamListener;
import com.miserablemind.api.consumer.tradeking.api.domain.TradeKingObject;
import com.miserablemind.api.consumer.tradeking.api.domain.market.StreamQuoteEvent;
import com.miserablemind.api.consumer.tradeking.api.domain.market.StreamTradeEvent;
import com.miserablemind.api.consumer.tradeking.api.impl.mixins.StreamQuoteMixIn;
import com.miserablemind.api.consumer.tradeking.api.impl.mixins.StreamTradeMixIn;
import com.miserablemind.api.consumer.tradeking.api.impl.mixins.TradeKingKObjectMixIn;

import java.io.IOException;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Dispatcher polls queue in a loop and dispatches it to listeners once a recognizable entry is found
 * It uses a pool of threads to run process paralleled
 */
class StreamDispatcher implements Runnable {

    private final List<StreamListener> listeners;

    private final ObjectMapper objectMapper;

    private final AtomicBoolean active;

    private final Queue<String> queue;

    private final ExecutorService pool;

    public StreamDispatcher(Queue<String> queue, List<StreamListener> listeners) {
        this.queue = queue;
        this.listeners = listeners;
        pool = Executors.newCachedThreadPool();
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JodaModule());

        objectMapper.addMixInAnnotations(TradeKingObject.class, TradeKingKObjectMixIn.class);
        objectMapper.addMixInAnnotations(StreamQuoteEvent.class, StreamQuoteMixIn.class);
        objectMapper.addMixInAnnotations(StreamTradeEvent.class, StreamTradeMixIn.class);
        objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);

        active = new AtomicBoolean(true);
    }

    /**
     * Keeps polling the queue. If it finds something,
     * it tries to figure out the type of the entry and dispatches it for processing
     */
    public void run() {
        while (active.get()) {

            String jsonEntry = queue.poll();
            if (jsonEntry == null || jsonEntry.length() == 0)
                return;

            try {
                if (jsonEntry.contains("{\"quote")) {
                    handleQuote(jsonEntry);
                } else if (jsonEntry.startsWith("{\"trade")) {
                    handleTrade(jsonEntry);
                }
            } catch (IOException e) {
                // could not map the line, will skip for now
            }
        }
    }

    /**
     * Stops the dispatcher.
     */
    public void stop() {
        active.set(false);
        pool.shutdown();
    }

    /**
     * Takes a String json entry, converts it to a stream quote object and passes it to listeners provided to execute in
     * thread pool
     *
     * @param jsonEntry json format quote
     * @throws IOException exception if could not map json to object
     */
    private void handleQuote(String jsonEntry) throws IOException {
        StreamQuoteEvent quoteEvent = objectMapper.readValue(jsonEntry, StreamQuoteEvent.class);
        for (final StreamListener listener : listeners)
            pool.submit((() -> listener.onQuote(quoteEvent)));
    }

    /**
     * Takes a String json entry, converts it to a stream trade object and passes it to listeners provided to execute in
     * thread pool
     *
     * @param jsonEntry json format trade entry
     * @throws IOException exception if could not map json to object
     */
    private void handleTrade(String jsonEntry) throws IOException {
        StreamTradeEvent tradeEvent = objectMapper.readValue(jsonEntry, StreamTradeEvent.class);
        for (StreamListener listener : listeners)
            pool.submit((() -> listener.onTrade(tradeEvent)));
    }

}