How to keep the queue consumer flow open?

Hi everyone,

I have actually a bunch of questions, hopefully it's okay to ask here :)

  1. How to keep the queue consumer flow open?
    Example Consumer provided here (https://tutorials.solace.dev/dotnet/persistence-with-queues/) gets messages only currently on the queue and closes immediately after that. How to keep the flow open so that consumer gets new messages appearing in the queue?
  2. How much memory a simple, basic, empty queue consumes? More or less
  3. Is it possible to configure UI tool PubSub+ Broker Manager so that some users can have read-only access and to queues only?
    Imagine a Support person who would monitor the queues and their performance, without access to e.g. create new queues or create messages.

Thank you,

Andrzej

Tagged:

Answers

  • nicholasdgoodman
    nicholasdgoodman Member, Employee Posts: 43 Solace Employee

    That's a number of questions, but I can provide some tips on the first one.

    So the tutorial samples are based on the source code found in GitHub here. Note that any .NET application will terminate as soon as it has no foreground threads active. So in order to keep the process running requires us to suspend the main thread (or some other foreground thread) with a WaitHandle.WaitOne() (or similar thread-blocking operation).

    That being said, there are two simple ways to keep an application like this open - depending on when you want the application to actually close down.

    Option 1: replace the statement WaitEventWaitHandle.WaitOne() with Thread.Sleep(Timeout.Infinite) and remove all other references to WaitEventWaitHandle field. This application will run until it receives a sig-term signal or is force killed.

    Option 2: move WaitEventWaitHandle.Set() to the HandleFlowEvent callback, and invoke it when args.Event == FlowEvent.FlowInactive. This application will terminate whenever the application disconnects from the broker (either due to network issues or the broker force disconnects the client).

  • andrzejk
    andrzejk Member Posts: 6

    Hi @nicholasdgoodman

    Thanks!

    Both options you have provided does exactly that. But, is this the right approach to consume messages?

    I only ask because both options block the current thread. I think I was expecting the Consumer flow would be event-based. That is, it would receive a message i.e. pick it up from the queue immediately after the moment it was sent there by the Producer. Is something like that possible? Option 2 looks like it might be almost that.

  • nicholasdgoodman
    nicholasdgoodman Member, Employee Posts: 43 Solace Employee

    Yes, so the exact nature of "how to keep the process alive" is very flexible - blocking the caller thread is one primitive example if you are writing a console style application. Other .NET Application types, such as ASP.NET Core / MVC apps will likely have other processes and tasks keeping the process alive (though typically at the end of initialization there is some kind of implicit main thread blocking that occurs).

    However, if you wanted a less heavy handed and slightly more modern approach you could swap out the WaitEventWaitHandle field with a TaskCompletionSource:

    class QueueConsumer : IDisposeable
    {
      // all the other properties and fields…
      private TaskCompletionSource<object> runCompletion = new TaskCompletionSource<object>();
         
      Task Run(IContext context, string host)
      {
        // all the existing implementation…
        return runCompletion.Task;  
      }
         
      public void HandleFlowEvent(object sender, FlowEventArgs args)
      {
         if(args.Event == FlowEvent.FlowInactive)
         {
           runCompletion.SetResult(null);
        }
      }
    }

    So elsewhere in code you would now have the ability to:

    await queueConsumer.Run(context, host);