/*
* Copyright 2014-2017 Real Logic Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.aeron.samples;
import io.aeron.Image;
import io.aeron.Subscription;
import io.aeron.logbuffer.FragmentHandler;
import io.aeron.protocol.HeaderFlyweight;
import org.agrona.LangUtil;
import org.agrona.concurrent.BusySpinIdleStrategy;
import org.agrona.concurrent.IdleStrategy;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
/**
* Utility functions for samples
*/
public class SamplesUtil
{
/**
* Return a reusable, parameterised event loop that calls a default idler when no messages are received
*
* @param fragmentHandler to be called back for each message.
* @param limit passed to {@link Subscription#poll(FragmentHandler, int)}
* @param running indication for loop
* @return loop function
*/
public static Consumer<Subscription> subscriberLoop(
final FragmentHandler fragmentHandler, final int limit, final AtomicBoolean running)
{
final IdleStrategy idleStrategy = new BusySpinIdleStrategy();
return subscriberLoop(fragmentHandler, limit, running, idleStrategy);
}
/**
* Return a reusable, parameterized event loop that calls and idler when no messages are received
*
* @param fragmentHandler to be called back for each message.
* @param limit passed to {@link Subscription#poll(FragmentHandler, int)}
* @param running indication for loop
* @param idleStrategy to use for loop
* @return loop function
*/
public static Consumer<Subscription> subscriberLoop(
final FragmentHandler fragmentHandler,
final int limit,
final AtomicBoolean running,
final IdleStrategy idleStrategy)
{
return
(subscription) ->
{
try
{
while (running.get())
{
idleStrategy.idle(subscription.poll(fragmentHandler, limit));
}
}
catch (final Exception ex)
{
LangUtil.rethrowUnchecked(ex);
}
};
}
/**
* Return a reusable, parameterized {@link FragmentHandler} that prints to stdout
*
* @param streamId to show when printing
* @return subscription data handler function that prints the message contents
*/
public static FragmentHandler printStringMessage(final int streamId)
{
return (buffer, offset, length, header) ->
{
final byte[] data = new byte[length];
buffer.getBytes(offset, data);
System.out.println(String.format(
"Message to stream %d from session %d (%d@%d) <<%s>>",
streamId, header.sessionId(), length, offset, new String(data)));
};
}
/**
* Return a reusable, parameteried {@link FragmentHandler} that calls into a
* {@link RateReporter}.
*
* @param reporter for the rate
* @return {@link FragmentHandler} that records the rate information
*/
public static FragmentHandler rateReporterHandler(final RateReporter reporter)
{
return (buffer, offset, length, header) -> reporter.onMessage(1, length);
}
/**
* Generic error handler that just prints message to stdout.
*
* @param channel for the error
* @param streamId for the error
* @param sessionId for the error, if source
* @param message indicating what the error was
* @param cause of the error
*/
public static void printError(
final String channel,
final int streamId,
final int sessionId,
final String message,
final HeaderFlyweight cause)
{
System.out.println(message);
}
/**
* Print the rates to stdout
*
* @param messagesPerSec being reported
* @param bytesPerSec being reported
* @param totalMessages being reported
* @param totalBytes being reported
*/
public static void printRate(
final double messagesPerSec,
final double bytesPerSec,
final long totalMessages,
final long totalBytes)
{
System.out.println(String.format(
"%.02g msgs/sec, %.02g bytes/sec, totals %d messages %d MB",
messagesPerSec, bytesPerSec, totalMessages, totalBytes / (1024 * 1024)));
}
/**
* Print the information for an available image to stdout.
*
* @param image that has been created
*/
public static void printAvailableImage(final Image image)
{
final Subscription subscription = image.subscription();
System.out.println(String.format(
"Available image on %s streamId=%d sessionId=%d from %s",
subscription.channel(), subscription.streamId(), image.sessionId(), image.sourceIdentity()));
}
/**
* Print the information for an unavailable image to stdout.
*
* @param image that has gone inactive
*/
public static void printUnavailableImage(final Image image)
{
final Subscription subscription = image.subscription();
System.out.println(String.format(
"Unavailable image on %s streamId=%d sessionId=%d",
subscription.channel(), subscription.streamId(), image.sessionId()));
}
}