Azure Service Bus Sessions - MaxConcurrentSessions vs MaxConcurrentCalls
Asked Answered
O

2

6

This page describes how to use sessions in Azure Service Bus to group messages from the same source into same receivers.

In session-less queue processors I can control how many messages I may get in parallel:

new OnMessageOptions { MaxConcurrentCalls = 10 };

If I pass these options, no more than 10 messages will be handled at the same time.

Now, for session-ful processors the options are replaced by

new SessionHandlerOptions { MaxConcurrentSessions = 10 };

Which has a different meaning of no more than 10 sessions at the same time.

My sessions are relatively long-lived, and mostly idle, so I have to set this parameter to high value. However, I still want to limit the amount of parallel messages.

Is that possible out of the box?

What would the practical limit of parallelization be if I set MaxConcurrentSessions to int.MaxValue?

Outmarch answered 9/12, 2016 at 16:15 Comment(0)
T
10

I believe you might be misunderstanding the concept of sessions.

Consider a session to be like a sub-queue, so for example if you have a queue called Q1, where your publisher writes new 100 messages to each different session identifiers (e.g. - s1, s2, s3, s4, s5, s6, s7, s8, s9, 10 for simplicity), you will have in Q1 a total of 1000 messages, but each of the sessions only hold 100 messages.

Visual representation of the queue and its sessions

From the above scenario, your client will be running MaxConcurrentSessions = 10, meaning it will have a dedicated receiver for all your sessions s1->s10 which will process sequentially the messages out of each session until the session has no more messages to process, after which it will sit idle waiting for new messages to arrive or for SessionIdleTimeout to elapse at which point it will drop the session.

Visual representation of the client connection to queue

When configuring a session based client, it is important to determine your SessionIdleTimeout as that's what will determine the speed at which the client will drop a session that has no messages and will be available to pick up a new session. In the following example, I try to represent what would be the starting point of your system running with MaxConcurrentSessions=5 and a wildly more distributed message count

the starting point of your system running with MaxConcurrentSessions=5

When s3 is drained of its 14 messages, assuming we have a SessionIdleTimeout of 10s, your function's s3 Session Processor would sit idly waiting for 10s and if no new messages arrive in s4 it will drop the s3 Session Processor and obtain a new Session Processor for any of s6->s10.

Session emptied example

Rinse and repeat until all sessions are drained! ;-)

Tolman answered 14/11, 2022 at 7:36 Comment(0)
E
1

From the documentation:

A single receiver process can handle very many concurrent sessions easily, especially when they are written with strictly asynchronous code; juggling several dozen concurrent sessions effectively automatic with the callback model.

In case when you have multiple sessions that are long-lived:

The strategy for handling very many concurrent sessions, whereby each session only sporadically receives messages is for the handler to drop the session after some idle time and pick up processing again when the session is accepted as the next session arrives.

Evanish answered 12/12, 2016 at 7:27 Comment(3)
Still, I don't know how to choose MaxConcurrentSessions. Say, my idle timeout is 1 min, each message takes 1 sec to process and I want to handle 10 concurrent messages max. Then I kind of have to set MaxConcurrentSessions to 60*10. But that probably means SB will accept 600 new sessions at the same time?Outmarch
Setting MaxConcurrentSessions to 600 would indeed allow up to 600 sessions to be processed. All depends from what sessions those messages arrive. I think what you want to do is to keep your MaxConcurrentSessions at 10 and once you've process a message for a session, to drop that session (as documentation prescribes). There's a lot that I don't know about your system, so can't answer what I don't know. Why 10 concurrent messages and not more that that is one of those. Also, testing out to see if your assumption about work/idle time will work or cause some sessions to "starve".Evanish
The limit is needed to avoid overloading external systems that are called from the queue processor. I'm now trying to Close the session after each processed message. Seems to work ok-ish, but I guess that causes all prefetched messages of same session to be returned to the queue and marked as non-successful until the next retry. I guess I'll have to do the "timeout" thing, but then I'm back to question of limiting the session count vs message count.Outmarch

© 2022 - 2025 — McMap. All rights reserved.