public static void Main() { Console.WriteLine("Subscribing to " + Channel + " on stream Id " + StreamID); var ctx = new Aeron.Context() .AvailableImageHandler(SamplesUtil.PrintUnavailableImage) .UnavailableImageHandler(SamplesUtil.PrintUnavailableImage); var reporter = new RateReporter(1000, SamplesUtil.PrintRate); var fragmentAssembler = new FragmentAssembler(SamplesUtil.RateReporterHandler(reporter)); var running = new AtomicBoolean(true); var t = new Thread(subscription => SamplesUtil.SubscriberLoop(fragmentAssembler.OnFragment, FragmentCountLimit, running)((Subscription) subscription)); var report = new Thread(reporter.Run); using (var aeron = Aeron.Connect(ctx)) using (var subscription = aeron.AddSubscription(Channel, StreamID)) { t.Start(subscription); report.Start(); Console.ReadLine(); Console.WriteLine("Shutting down..."); running.Set(false); reporter.Halt(); t.Join(); report.Join(); } }
public static void Main() { if (MessageLength < BitUtil.SIZE_OF_LONG) { throw new ArgumentException($"Message length must be at least {BitUtil.SIZE_OF_LONG:D} bytes"); } ComputerSpecifications.Dump(); var context = new Aeron.Context(); var reporter = new RateReporter(1000, PrintRate); _reporterThread = new Thread(_ => reporter.Run()); _reporterThread.Start(); // Connect to media driver and add publication to send messages on the configured channel and stream ID. // The Aeron and Publication classes implement AutoCloseable, and will automatically // clean up resources when this try block is finished. using (var aeron = Aeron.Connect(context)) using (var publication = aeron.AddPublication(Channel, StreamID)) using (var byteBuffer = BufferUtil.AllocateDirectAligned(MessageLength, BitUtil.CACHE_LINE_LENGTH)) using (var buffer = new UnsafeBuffer(byteBuffer)) { do { _printingActive = true; Console.WriteLine($"Streaming {NumberOfMessages} messages of {(RandomMessageLength ? " random" : "")} size {MessageLength} bytes to {Channel} on stream Id {StreamID}"); long backPressureCount = 0; for (long i = 0; i < NumberOfMessages; i++) { var length = LengthGenerator.AsInt; buffer.PutLong(0, i); OfferIdleStrategy.Reset(); while (publication.Offer(buffer, 0, length) < 0L) { // The offer failed, which is usually due to the publication // being temporarily blocked. Retry the offer after a short // spin/yield/sleep, depending on the chosen IdleStrategy. backPressureCount++; OfferIdleStrategy.Idle(); } reporter.OnMessage(1, length); } Console.WriteLine("Done streaming. Back pressure ratio " + (double) backPressureCount/NumberOfMessages); if (0 < LingerTimeoutMs) { Console.WriteLine("Lingering for " + LingerTimeoutMs + " milliseconds..."); Thread.Sleep((int) LingerTimeoutMs); } _printingActive = false; Console.WriteLine("Execute again?"); } while (Console.ReadLine() == "y"); } reporter.Halt(); _reporterThread.Join(); }
/// <summary> /// Return a reusable, parameteried <seealso cref="IFragmentHandler"/> that calls into a /// <seealso cref="RateReporter"/>. /// </summary> /// <param name="reporter"> for the rate </param> /// <returns> <seealso cref="IFragmentHandler"/> that records the rate information </returns> public static IFragmentHandler RateReporterHandler(RateReporter reporter) { return(HandlerHelper.ToFragmentHandler((buffer, offset, length, header) => reporter.OnMessage(1, length))); }
/// <summary> /// Return a reusable, parameteried <seealso cref="FragmentHandler"/> that calls into a /// <seealso cref="RateReporter"/>. /// </summary> /// <param name="reporter"> for the rate </param> /// <returns> <seealso cref="FragmentHandler"/> that records the rate information </returns> public static FragmentHandler RateReporterHandler(RateReporter reporter) { return (buffer, offset, length, header) => reporter.OnMessage(1, length); }