com.buabook.kdb.publisher.KdbPublisher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-kdb-communication Show documentation
Show all versions of java-kdb-communication Show documentation
Java library to publish data into and query data out of kdb+ processes (c) 2017 Sport Trades Ltd
The newest version!
package com.buabook.kdb.publisher;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.buabook.kdb.Flips;
import com.buabook.kdb.connection.KdbConnection;
import com.buabook.kdb.connection.KdbProcess;
import com.buabook.kdb.data.KdbTable;
import com.buabook.kdb.exceptions.KdbTargetProcessUnavailableException;
import com.google.common.base.Strings;
import com.kx.c.Flip;
/**
* KDB Data Publisher
* Provides the ability to publish some data (in either {@link KdbTable} or
* {@link Flip} format) to a specific kdb process.
* Any instantiation of this class will cause the publisher to run in the current
* thread. Use {@link KdbPublisherThread} if you need a new thread.
* (c) 2014 - 2015 Sport Trades Ltd
*
* @author Jas Rajasansir
* @version 1.1.0
* @since 6 Apr 2014
*/
public class KdbPublisher extends KdbConnection {
private static final Logger log = LoggerFactory.getLogger(KdbPublisher.class);
/** @see #resetConnectionDuration */
private static final Duration DEFAULT_RESET_CONNECTION_DURATION = Duration.standardMinutes(30);
private static final String PUBLISH_FUNCTION = ".u.upd";
/**
* The maximum amount of time after the last publish / connect allowed before the connection to the kdb
* process is reset. This is due to socket timeout on the target machine that may not be noticed by the
* local Java process.
* On Linux boxes, /proc/sys/net/ipv4/tcp_keepalive_time
will tell you how long a socket
* can stay open.
*/
private final Duration resetConnectionDuration;
/** The time of the last successful publish to the kdb process */
private DateTime lastPublishTime;
/** @see #KdbPublisher(KdbProcess, Duration) */
public KdbPublisher(KdbProcess server) throws KdbTargetProcessUnavailableException {
this(server, null);
}
/**
* Generates a new KDB publisher. NOTE: The process must be online and
* available to connect to when this constructor is called; reconnection is not supported here.
* @param server The server to connect to
* @param resetConnectionDuration The maximum time allowed between publishes before the connection is reset. If this is
* null
, {@link #DEFAULT_RESET_CONNECTION_DURATION} will be used
* @throws KdbTargetProcessUnavailableException If the target KDB process is unavailable
* @see #connect()
* @see #resetConnectionDuration
*/
public KdbPublisher(KdbProcess server, Duration resetConnectionDuration) throws KdbTargetProcessUnavailableException {
super(server);
connect();
if(resetConnectionDuration == null)
this.resetConnectionDuration = DEFAULT_RESET_CONNECTION_DURATION;
else
this.resetConnectionDuration = resetConnectionDuration;
this.lastPublishTime = DateTime.now();
log.info("Successfully connected to kdb process for publishing [ Target: {} ] [ Connection Reset After: {} ]", server, resetConnectionDuration);
}
/**
* Allows a list of tables to be published (in sequence) to the target KDB process
* @param tables The list of tables to publish
* @return The publish status for each table in the list
* @see #publish(KdbTable)
*/
public List publish(List tables) {
if(tables == null || tables.size() == 0)
return new ArrayList<>();
List results = new ArrayList<>();
for(KdbTable t : tables)
results.add(publish(t));
return results;
}
/**
* Allows a table (as an internal {@link KdbTable} to be published to the target KDB process
* @param table The table to publish
* @return true
if the publish was successful, false
otherwise
* @see #publish(String, Flip)
*/
public Boolean publish(KdbTable table) {
if(table == null)
return false;
return publish(table.getTableName(), table.convertToFlip());
}
/**
* Performs the publish of a {@link Flip} table structure to the target KDB process
* @param tableName The name of the table to publish
* @param tableData The table contents
* @return true
if the publish was successful, false
otherwise. NOTE:
* The function will also return true
if either parameter is null
*/
public Boolean publish(String tableName, Flip tableData) {
if(Strings.isNullOrEmpty(tableName) || tableData == null)
return true;
if(lastPublishTime.plus(resetConnectionDuration).isBeforeNow()) {
log.info("Maximum connection duration has elapsed. Resetting connection before publishing");
reconnect();
}
if(! isConnected()) {
log.warn("Connection to kdb process lost! Attempting reconnect now...");
reconnect();
}
log.debug("Publishing table update [ Table Name: {} ] [ Table Size: {} ]", tableName, Flips.getRowCount(tableData));
try {
getConnection().ks(PUBLISH_FUNCTION, tableName, tableData);
} catch (RuntimeException e) {
log.error("Uncaught RuntimeException during publishing. Error - {}", e.getMessage(), e);
return false;
} catch (IOException e) {
log.error("Basic I/O exception occurred. Assuming connection has been corrupted. Attempting reconnect. Error - {}", e.getMessage());
reconnect();
return false;
}
lastPublishTime = DateTime.now();
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy