Problem
A session value is not being retrieved in a Razor view and is causing faulty logic.
Environment
Redis sentinel with sentinel on web servers but only a single redis master and single redis slave. The redis connection string is pointing to both master and slave.
Code
In a controller before the view:
var fooLocal = fooMapper.Map(fooDbCall.GetFromDb(fooValue));
if (fooLocal != null)
{
Session["FooSession"] = fooLocal.fooProperty;
}
else
{
Session["FooSession"] = false;
}
In the view
@if (fooRazorVal == 123)
{
// show some stuff
}
else if (!((bool?)Session["FooSession"] ?? false) && (fooRazorVal2 == 456))
{
// show error message
}
else
{
// show other stuff
}
Result
The error message is shown even when an account in question has been walked back through the code and database to verify it should not be false let alone null. Other session values are stored and retrieved fine or else you wouldn't even make it this far in my process.
Investigation
As I mentioned, all other code bits and the database have been verified. I added a logging class and there are lots of entries like so:
[Info]GetItemFromSessionStore => Session Id: ctps3urcqwm0tpezo5bbmqzj, Session provider object: 4686063 => Can not lock, Someone else has lock and lockId is 636901606595110722
[Info]GetItemFromSessionStore => Session Id: ctps3urcqwm0tpezo5bbmqzj, Session provider object: 26422156 => Lock taken with lockId: 636901606595110722
[Info]GetItemFromSessionStore => Session Id: ctps3urcqwm0tpezo5bbmqzj, Session provider object: 4686063 => Can not lock, Someone else has lock and lockId is 636901606595110722
However, given the sheer number of them, I'm wondering if this is actually an error or the RedisSessionStateProvider
working as intended. I did see that it uses SETNX
to acquire locks. Unfortunately, I'm not well versed enough in redis semantics to know if this is causing an issue.
I did see a note on the Redis docs about this being an old approach and to use RedLock instead. However, as I understand RedLock, a single master/single slave setup is not sufficient although it does support retries so maybe it would work anyway. I'm also curious if I should roll a simple custom provider that lets StackExhange's ConnectionMultiplexer
work without extra locks or custom scripts and if I do need locks to use one of the C# libraries for RedLock.