void sendPingAndReceivePong( const fragment_handler_t& fragmentHandler, std::shared_ptr<Publication> publication, std::shared_ptr<Subscription> subscription, const Settings& settings) { AERON_DECL_ALIGNED(std::uint8_t buffer[settings.messageLength], 16); concurrent::AtomicBuffer srcBuffer(buffer, settings.messageLength); BusySpinIdleStrategy idleStrategy; for (int i = 0; i < settings.numberOfMessages; i++) { do { // timestamps in the message are relative to this app, so just send the timepoint directly. steady_clock::time_point start = steady_clock::now(); srcBuffer.putBytes(0, (std::uint8_t*)&start, sizeof(steady_clock::time_point)); } while (publication->offer(srcBuffer, 0, settings.messageLength) < 0L); while (subscription->poll(fragmentHandler, settings.fragmentCountLimit) <= 0) { idleStrategy.idle(0); } } }
int main(int argc, char **argv) { CommandOptionParser cp; cp.addOption(CommandOption (optHelp, 0, 0, " Displays help information.")); cp.addOption(CommandOption (optPrefix, 1, 1, "dir Prefix directory for aeron driver.")); cp.addOption(CommandOption (optPingChannel, 1, 1, "channel Ping Channel.")); cp.addOption(CommandOption (optPongChannel, 1, 1, "channel Pong Channel.")); cp.addOption(CommandOption (optPingStreamId, 1, 1, "streamId Ping Stream ID.")); cp.addOption(CommandOption (optPongStreamId, 1, 1, "streamId Pong Stream ID.")); cp.addOption(CommandOption (optFrags, 1, 1, "limit Fragment Count Limit.")); signal (SIGINT, sigIntHandler); try { Settings settings = parseCmdLine(cp, argc, argv); std::cout << "Subscribing Ping at " << settings.pingChannel << " on Stream ID " << settings.pingStreamId << std::endl; std::cout << "Publishing Pong at " << settings.pongChannel << " on Stream ID " << settings.pongStreamId << std::endl; aeron::Context context; if (settings.dirPrefix != "") { context.aeronDir(settings.dirPrefix); } context.newSubscriptionHandler( [](const std::string& channel, std::int32_t streamId, std::int64_t correlationId) { std::cout << "Subscription: " << channel << " " << correlationId << ":" << streamId << std::endl; }); context.newPublicationHandler( [](const std::string& channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t correlationId) { std::cout << "Publication: " << channel << " " << correlationId << ":" << streamId << ":" << sessionId << std::endl; }); context.availableImageHandler([]( Image &image, const std::string &channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t joiningPosition, const std::string &sourceIdentity) { std::cout << "Available image on " << channel << " streamId=" << streamId << " sessionId=" << sessionId; std::cout << " at position=" << joiningPosition << " from " << sourceIdentity << std::endl; }); context.unavailableImageHandler( [](Image &image, const std::string &channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t position) { std::cout << "Unavailable image on " << channel << "streamId=" << streamId << " sessionId=" << sessionId; std::cout << " at position=" << position << std::endl; }); Aeron aeron(context); std::int64_t subscriptionId = aeron.addSubscription(settings.pingChannel, settings.pingStreamId); std::int64_t publicationId = aeron.addPublication(settings.pongChannel, settings.pongStreamId); std::shared_ptr<Subscription> pingSubscription = aeron.findSubscription(subscriptionId); while (!pingSubscription) { std::this_thread::yield(); pingSubscription = aeron.findSubscription(subscriptionId); } std::shared_ptr<Publication> pongPublication = aeron.findPublication(publicationId); while (!pongPublication) { std::this_thread::yield(); pongPublication = aeron.findPublication(publicationId); } BusySpinIdleStrategy idleStrategy; BusySpinIdleStrategy pingHandlerIdleStrategy; FragmentAssembler fragmentAssembler( [&](AtomicBuffer& buffer, index_t offset, index_t length, Header& header) { while (pongPublication->offer(buffer, offset, length) < 0L) { pingHandlerIdleStrategy.idle(0); } }); fragment_handler_t handler = fragmentAssembler.handler(); while (running) { const int fragmentsRead = pingSubscription->poll(handler, settings.fragmentCountLimit); idleStrategy.idle(fragmentsRead); } std::cout << "Shutting down...\n"; } catch (CommandOptionException& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; cp.displayOptionsHelp(std::cerr); return -1; } catch (SourcedException& e) { std::cerr << "FAILED: " << e.what() << " : " << e.where() << std::endl; return -1; } catch (std::exception& e) { std::cerr << "FAILED: " << e.what() << " : " << std::endl; return -1; } return 0; }
int main(int argc, char **argv) { CommandOptionParser cp; cp.addOption(CommandOption (optHelp, 0, 0, " Displays help information.")); cp.addOption(CommandOption (optPrefix, 1, 1, "dir Prefix directory for aeron driver.")); cp.addOption(CommandOption (optChannel, 1, 1, "channel Channel.")); cp.addOption(CommandOption (optStreamId, 1, 1, "streamId Stream ID.")); cp.addOption(CommandOption (optFrags, 1, 1, "limit Fragment Count Limit.")); signal (SIGINT, sigIntHandler); try { Settings settings = parseCmdLine(cp, argc, argv); std::cout << "Subscribing to channel " << settings.channel << " on Stream ID " << settings.streamId << std::endl; aeron::Context context; if (settings.dirPrefix != "") { context.aeronDir(settings.dirPrefix); } context.newSubscriptionHandler( [](const std::string& channel, std::int32_t streamId, std::int64_t correlationId) { std::cout << "Subscription: " << channel << " " << correlationId << ":" << streamId << std::endl; }); context.newConnectionHandler([]( const std::string& channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t joiningPosition, const std::string& sourceIdentity) { std::cout << "New connection on " << channel << " streamId=" << streamId << " sessionId=" << sessionId; std::cout << " at position=" << joiningPosition << " from " << sourceIdentity << std::endl; }); context.inactiveConnectionHandler( [](const std::string& channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t position) { std::cout << "Inactive connection on " << channel << "streamId=" << streamId << " sessionId=" << sessionId; std::cout << " at position=" << position << std::endl; }); Aeron aeron(context); // add the subscription to start the process std::int64_t id = aeron.addSubscription(settings.channel, settings.streamId); std::shared_ptr<Subscription> subscription = aeron.findSubscription(id); // wait for the subscription to be valid while (!subscription) { std::this_thread::yield(); subscription = aeron.findSubscription(id); } BusySpinIdleStrategy idleStrategy; RateReporter rateReporter(std::chrono::seconds(1), printRate); FragmentAssemblyAdapter fragmentAssemblyAdapter(rateReporterHandler(rateReporter)); fragment_handler_t handler = fragmentAssemblyAdapter.handler(); std::thread rateReporterThread([&](){ rateReporter.run(); }); while (running) { const int fragmentsRead = subscription->poll(handler, settings.fragmentCountLimit); idleStrategy.idle(fragmentsRead); } std::cout << "Shutting down...\n"; rateReporter.halt(); rateReporterThread.join(); } catch (CommandOptionException& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; cp.displayOptionsHelp(std::cerr); return -1; } catch (SourcedException& e) { std::cerr << "FAILED: " << e.what() << " : " << e.where() << std::endl; return -1; } catch (std::exception& e) { std::cerr << "FAILED: " << e.what() << " : " << std::endl; return -1; } return 0; }
int main(int argc, char **argv) { CommandOptionParser cp; cp.addOption(CommandOption (optHelp, 0, 0, " Displays help information.")); cp.addOption(CommandOption (optRandLen, 0, 0, " Random Message Length.")); cp.addOption(CommandOption (optProgress, 0, 0, " Print rate progress while sending.")); cp.addOption(CommandOption (optPrefix, 1, 1, "dir Prefix directory for aeron driver.")); cp.addOption(CommandOption (optChannel, 1, 1, "channel Channel.")); cp.addOption(CommandOption (optStreamId, 1, 1, "streamId Stream ID.")); cp.addOption(CommandOption (optMessages, 1, 1, "number Number of Messages.")); cp.addOption(CommandOption (optLength, 1, 1, "length Length of Messages.")); cp.addOption(CommandOption (optLinger, 1, 1, "milliseconds Linger timeout in milliseconds.")); cp.addOption(CommandOption (optFrags, 1, 1, "limit Fragment Count Limit.")); signal (SIGINT, sigIntHandler); try { Settings settings = parseCmdLine(cp, argc, argv); std::cout << "Subscribing to channel " << settings.channel << " on Stream ID " << settings.streamId << std::endl; ::setlocale(LC_NUMERIC, ""); std::printf( "Streaming %'ld messages of%s size %d bytes to %s on stream ID %d\n", settings.numberOfMessages, settings.randomMessageLength ? " random" : "", settings.messageLength, settings.channel.c_str(), settings.streamId); aeron::Context context; if (settings.dirPrefix != "") { context.aeronDir(settings.dirPrefix); } context.newPublicationHandler( [](const std::string& channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t correlationId) { std::cout << "Publication: " << channel << " " << correlationId << ":" << streamId << ":" << sessionId << std::endl; }); context.newSubscriptionHandler( [](const std::string& channel, std::int32_t streamId, std::int64_t correlationId) { std::cout << "Subscription: " << channel << " " << correlationId << ":" << streamId << std::endl; }); context.availableImageHandler([]( Image &image, const std::string &channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t joiningPosition, const std::string &sourceIdentity) { std::cout << "Available image on " << channel << " streamId=" << streamId << " sessionId=" << sessionId; std::cout << " at position=" << joiningPosition << " from " << sourceIdentity << std::endl; }); context.unavailableImageHandler( [](Image &image, const std::string &channel, std::int32_t streamId, std::int32_t sessionId, std::int64_t position) { std::cout << "Unavailable image on " << channel << "streamId=" << streamId << " sessionId=" << sessionId; std::cout << " at position=" << position << std::endl; }); Aeron aeron(context); std::int64_t subscriptionId = aeron.addSubscription(settings.channel, settings.streamId); std::int64_t publicationId = aeron.addPublication(settings.channel, settings.streamId); std::shared_ptr<Subscription> subscription = aeron.findSubscription(subscriptionId); while (!subscription) { std::this_thread::yield(); subscription = aeron.findSubscription(subscriptionId); } std::shared_ptr<Publication> publication = aeron.findPublication(publicationId); while (!publication) { std::this_thread::yield(); publication = aeron.findPublication(publicationId); } std::unique_ptr<std::uint8_t[]> buffer(new std::uint8_t[settings.messageLength]); concurrent::AtomicBuffer srcBuffer(buffer.get(), settings.messageLength); BusySpinIdleStrategy offerIdleStrategy; BusySpinIdleStrategy pollIdleStrategy; RateReporter rateReporter(std::chrono::seconds(1), printRate); FragmentAssembler fragmentAssembler(rateReporterHandler(rateReporter)); fragment_handler_t handler = fragmentAssembler.handler(); on_new_length_t lengthGenerator = composeLengthGenerator(settings.randomMessageLength, settings.messageLength); std::shared_ptr<std::thread> rateReporterThread; if (settings.progress) { rateReporterThread = std::make_shared<std::thread>([&](){ rateReporter.run(); }); } std::thread pollThread([&]() { while (running) { const int fragmentsRead = subscription->poll(handler, settings.fragmentCountLimit); pollIdleStrategy.idle(fragmentsRead); } }); do { printingActive = true; long backPressureCount = 0; if (nullptr == rateReporterThread) { rateReporter.reset(); } for (long i = 0; i < settings.numberOfMessages && running; i++) { const int length = lengthGenerator(); srcBuffer.putInt64(0, i); while (publication->offer(srcBuffer, 0, length) < 0L) { backPressureCount++; offerIdleStrategy.idle(0); } } if (nullptr == rateReporterThread) { rateReporter.report(); } std::cout << "Done streaming. Back pressure ratio "; std::cout << ((double)backPressureCount / settings.numberOfMessages) << std::endl; if (running && settings.lingerTimeoutMs > 0) { std::cout << "Lingering for " << settings.lingerTimeoutMs << " milliseconds." << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(settings.lingerTimeoutMs)); } printingActive = false; } while (running && continuationBarrier("Execute again?")); running = false; rateReporter.halt(); pollThread.join(); if (nullptr != rateReporterThread) { rateReporterThread->join(); } } catch (CommandOptionException& e) { std::cerr << "ERROR: " << e.what() << std::endl << std::endl; cp.displayOptionsHelp(std::cerr); return -1; } catch (SourcedException& e) { std::cerr << "FAILED: " << e.what() << " : " << e.where() << std::endl; return -1; } catch (std::exception& e) { std::cerr << "FAILED: " << e.what() << " : " << std::endl; return -1; } return 0; }