📜 ⬆️ ⬇️

RequestQueueLimitPerSession and its distribution to older versions of .net

Good day! In this article, I would like to share a solution to an unexpected problem that has arisen in one of the projects I'm working on.

What could be dangerous about updating .net 4.6.1 to .net 4.6.2? I thought that for the upgrade process the minor version is enough to read the release notes to avoid serious problems. However, as it turned out, Microsoft can make very interesting and entertaining changes to bypass the release notes, which can take you on "boring summer evenings and weekends."

Under the cut there will be a description of one problem arising from the update and the way to solve it, as well as some .net source codes.

How did you start?


Regular update .net. What for? Yes, simply because. You can talk for a long time on the topic “work - don't touch”, but I think that on active projects it is always necessary to update the components of the stack at least regularly. Otherwise, at some point, updates in a few dozen versions will turn into such pain that it will be easier to freeze the old version forever, than to try to update and solve the problems that the community has been treating several years ago and no one remembers what they encountered there.
')
Generally speaking, the planned update should have been on .net 4.7, but since Microsoft has been very friendly for six months rebuilding the partnership system and still can’t provide a way to extend it normally in our conditions, VS 2017 hasn’t come to us yet. Therefore, it was temporarily decided to catch up with the version at least up to 4.6.2.

No sooner said than done. Updated, rolled out on the test circuit, tested, then on the battle. The flight is normal.

Problems


System.Web.HttpException (0x80004005): The request queue limit of the session is exceeded.

Um, wat? A daily analysis of the most frequent errors revealed on a lightly loaded server 600+ such errors. Well, start digging.

At the same time, http / 2 support on mobile devices was turned on and the old asmx mobile service appeared on the stack, so the traces were a bit confused. There was a suspicion that banal requests began to come too often and this overloaded the queue.

asmx
Yes, we do not have everything on webApi2, there are still a number of asmx services, which, due to the size of the project, migrate gradually.


Began to work out this case. Since all mobile services with the session worked readonly, we transfer the session to the appropriate mode.

Global.asax:
if (<   >) { Context.SetSessionStateBehavior(SessionStateBehavior.ReadOnly); } 

Update the contour. Mobile problems disappear. But arise with another asmx service, which is used from the web.
This leads to suspicions that the initial assumption most likely leads in the wrong direction.

Google - to the rescue!


www.google.com/search?q=The+request+queue+limit+of+the+session+is+exceeded

What do we see? Recommendations to increase the requestQueueLimit (the size of the queue to the server), try - no sense. And somehow it doesn’t look like a load, that we can break through this limit in some way.

The second link - if you have problems with the queue - "do not touch the queue, increase resources!" Clearly, passed.

No further information. Well, there remains another proven method. Sources

I'm actually very grateful to MS for opening the source. Otherwise, many problems would be solved ten times longer, in an empirical way, and maybe they would remain unresolved. (And also Resharper is very convenient for traveling through source codes).

Input data:
System.Web.HttpException (0x80004005): The request queue limit of the session is exceeded.
at System.Web.SessionState.SessionStateModule.QueueRef ()
at System.Web.SessionState.SessionStateModule.PollLockedSession ()
at System.Web.SessionState.SessionStateModule.GetSessionStateItem ()
at System.Web.SessionState.SessionStateModule.BeginAcquireState (Object source, EventArgs e, AsyncCallback cb, Object extraData)


We pass through the whole chain. In general, nothing much suspicious. We reach the final method :

 private void QueueRef() { if (!IsRequestQueueEnabled || _rqId == null) { return; } // // Check the limit int count = 0; s_queuedRequestsNumPerSession.TryGetValue(_rqId, out count); if (count >= AppSettings.RequestQueueLimitPerSession) { throw new HttpException(SR.GetString(SR.Request_Queue_Limit_Per_Session_Exceeded)); } // // Add ref s_queuedRequestsNumPerSession.AddOrUpdate(_rqId, 1, (key, value) => value + 1); } 

Hm And what is this RequestQueueLimitPerSession setting which is mentioned for some reason only in .net 4.7 , but is distributed with fixes up to .net 3.5 ?

Go to study settings in AppSettings.cs . Bingo!

 internal const int UnlimitedRequestsPerSession = Int32.MaxValue; internal const int DefaultRequestQueueLimitPerSession = 50; if (settings == null || !int.TryParse(settings["aspnet:RequestQueueLimitPerSession"], out _requestQueueLimitPerSession) || _requestQueueLimitPerSession < 0) _requestQueueLimitPerSession = BinaryCompatibility.Current.TargetsAtLeastFramework463 ? DefaultRequestQueueLimitPerSession : UnlimitedRequestsPerSession; 

If you have a .net 4.6.3 version (which apparently has a system name of 4.6.2) or older, then the queue length per user is chopped off by 50 requests, which is achieved quite easily in certain use cases. Increase the limit, fill, test - happy end.

I hope that this article on Habré will help someone who will face the same problem, because Searching for information on this problem on the Internet is hard to find.

PS: It is strange that such changes bypass release notes. Apparently, the point is that it was distributed with updates and fixes from 4.7. But from my point of view, this is an obvious breaking change, which for some time partially dumped the application and somehow more clearly would like to see such changes.

Source: https://habr.com/ru/post/335138/


All Articles