Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unix: make timeout and buffer size configurable #64

Merged
merged 1 commit into from
Jan 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 80 additions & 5 deletions src/main/java/com/timgroup/statsd/NonBlockingStatsDClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
public final class NonBlockingStatsDClient implements StatsDClient {

private static final int PACKET_SIZE_BYTES = 1400;
private static final int SOCKET_TIMEOUT_MS = 100;
private static final int SOCKET_BUFFER_BYTES = -1;
Copy link
Contributor

@nmuesch nmuesch Jan 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you confirm where this default comes from? Would this be the same as not providing a default and falling back on whatever the system has set, or would this not set a limit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would keep the exact settings what we use today:

  • 100ms timeout
  • default socket write buffer size (because any size <= 0 is ignored)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok great, the timeout made sense, but wasn't aware of the socket size being ignored if less than zero. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not in the library but in our own code :)

                if (bufferSize > 0) {
                    clientChannel.setOption(UnixSocketOptions.SO_SNDBUF, bufferSize);
                }


private static final StatsDClientErrorHandler NO_OP_HANDLER = new StatsDClientErrorHandler() {
@Override public void handle(final Exception e) { /* No-op */ }
Expand Down Expand Up @@ -249,7 +251,7 @@ public NonBlockingStatsDClient(final String prefix, final String hostname, final
*/
public NonBlockingStatsDClient(final String prefix, final String hostname, final int port,
final String[] constantTags, final StatsDClientErrorHandler errorHandler) throws StatsDClientException {
this(prefix, Integer.MAX_VALUE, constantTags, errorHandler, staticStatsDAddressResolution(hostname, port));
this(prefix, Integer.MAX_VALUE, constantTags, errorHandler, staticStatsDAddressResolution(hostname, port), SOCKET_TIMEOUT_MS, SOCKET_BUFFER_BYTES);
}

/**
Expand Down Expand Up @@ -280,7 +282,42 @@ public NonBlockingStatsDClient(final String prefix, final String hostname, final
*/
public NonBlockingStatsDClient(final String prefix, final String hostname, final int port, final int queueSize,
final String[] constantTags, final StatsDClientErrorHandler errorHandler) throws StatsDClientException {
this(prefix, queueSize, constantTags, errorHandler, staticStatsDAddressResolution(hostname, port));
this(prefix, queueSize, constantTags, errorHandler, staticStatsDAddressResolution(hostname, port), SOCKET_TIMEOUT_MS, SOCKET_BUFFER_BYTES);
}

/**
* Create a new StatsD client communicating with a StatsD instance on the
* specified host and port. All messages send via this client will have
* their keys prefixed with the specified string. The new client will
* attempt to open a connection to the StatsD server immediately upon
* instantiation, and may throw an exception if that a connection cannot
* be established. Once a client has been instantiated in this way, all
* exceptions thrown during subsequent usage are passed to the specified
* handler and then consumed, guaranteeing that failures in metrics will
* not affect normal code execution.
*
* @param prefix
* the prefix to apply to keys sent via this client
* @param hostname
* the host name of the targeted StatsD server
* @param port
* the port of the targeted StatsD server
* @param constantTags
* tags to be added to all content sent
* @param errorHandler
* handler to use when an exception occurs during usage, may be null to indicate noop
* @param queueSize
* the maximum amount of unprocessed messages in the BlockingQueue.
* @param timeout
* the timeout in milliseconds for blocking operations. Applies to unix sockets only.
* @param bufferSize
* the socket buffer size in bytes. Applies to unix sockets only.
* @throws StatsDClientException
* if the client could not be started
*/
public NonBlockingStatsDClient(final String prefix, final String hostname, final int port, final int queueSize, int timeout, int bufferSize,
final String[] constantTags, final StatsDClientErrorHandler errorHandler) throws StatsDClientException {
this(prefix, queueSize, constantTags, errorHandler, staticStatsDAddressResolution(hostname, port), timeout, bufferSize);
}

/**
Expand Down Expand Up @@ -308,7 +345,40 @@ public NonBlockingStatsDClient(final String prefix, final String hostname, final
* if the client could not be started
*/
public NonBlockingStatsDClient(final String prefix, final int queueSize, String[] constantTags, final StatsDClientErrorHandler errorHandler,
final Callable<SocketAddress> addressLookup) throws StatsDClientException {
final Callable<SocketAddress> addressLookup) throws StatsDClientException {
this(prefix, queueSize, constantTags, errorHandler, addressLookup, SOCKET_TIMEOUT_MS, SOCKET_BUFFER_BYTES);
}

/**
* Create a new StatsD client communicating with a StatsD instance on the
* specified host and port. All messages send via this client will have
* their keys prefixed with the specified string. The new client will
* attempt to open a connection to the StatsD server immediately upon
* instantiation, and may throw an exception if that a connection cannot
* be established. Once a client has been instantiated in this way, all
* exceptions thrown during subsequent usage are passed to the specified
* handler and then consumed, guaranteeing that failures in metrics will
* not affect normal code execution.
*
* @param prefix
* the prefix to apply to keys sent via this client
* @param constantTags
* tags to be added to all content sent
* @param errorHandler
* handler to use when an exception occurs during usage, may be null to indicate noop
* @param addressLookup
* yields the IP address and socket of the StatsD server
* @param queueSize
* the maximum amount of unprocessed messages in the BlockingQueue.
* @param timeout
* the timeout in milliseconds for blocking operations. Applies to unix sockets only.
* @param bufferSize
* the socket buffer size in bytes. Applies to unix sockets only.
* @throws StatsDClientException
* if the client could not be started
*/
public NonBlockingStatsDClient(final String prefix, final int queueSize, String[] constantTags, final StatsDClientErrorHandler errorHandler,
final Callable<SocketAddress> addressLookup, final int timeout, final int bufferSize) throws StatsDClientException {
if((prefix != null) && (!prefix.isEmpty())) {
this.prefix = new StringBuilder(prefix).append(".").toString();
} else {
Expand Down Expand Up @@ -336,9 +406,14 @@ public NonBlockingStatsDClient(final String prefix, final int queueSize, String
final SocketAddress address = addressLookup.call();
if (address instanceof UnixSocketAddress) {
clientChannel = UnixDatagramChannel.open();
// Set send timeout to 100ms, to handle the case where the transmission buffer is full
// Set send timeout, to handle the case where the transmission buffer is full
// If no timeout is set, the send becomes blocking
clientChannel.setOption(UnixSocketOptions.SO_SNDTIMEO, Integer.valueOf(100));
if (timeout > 0) {
clientChannel.setOption(UnixSocketOptions.SO_SNDTIMEO, timeout);
}
if (bufferSize > 0) {
clientChannel.setOption(UnixSocketOptions.SO_SNDBUF, bufferSize);
}
} else{
clientChannel = DatagramChannel.open();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.junit.Test;

import java.io.IOException;
import java.net.SocketException;
import java.util.Locale;

import static org.hamcrest.MatcherAssert.assertThat;
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/com/timgroup/statsd/UnixSocketTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void start() throws IOException {
socketFile.deleteOnExit();

server = new DummyStatsDServer(socketFile.toString());
client = new NonBlockingStatsDClient("my.prefix", socketFile.toString(), 0, 1, null, this);
client = new NonBlockingStatsDClient("my.prefix", socketFile.toString(), 0, 1, 100, 1024 * 1024, null, this);
}

@After
Expand Down