Skip to content

Commit

Permalink
Add redis.Watch to ensure proper concurrency for #1.
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCloudlessSky committed Jul 15, 2012
1 parent 74968bc commit 054984e
Showing 1 changed file with 24 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ private string GetSessionIdKey(string id)
public override void CreateUninitializedItem(HttpContext context, string id, int timeout)
{
var key = this.GetSessionIdKey(id);
using (var client = this.GetClient())
using (var client = this.GetClientAndWatch(key))
{
var state = new RedisSessionState()
{
Expand Down Expand Up @@ -194,30 +194,40 @@ public override void EndRequest(HttpContext context)

}

private IRedisClient GetClient()
private IRedisClient GetClientAndWatch(string key)
{
return this.clientManager.GetClient();
var client = this.clientManager.GetClient();
client.Watch(key);
return client;
}

public override void ResetItemTimeout(HttpContext context, string id)
{
var key = this.GetSessionIdKey(id);
using (var client = this.GetClient())
using (var client = this.GetClientAndWatch(key))
using (var transaction = client.CreateTransaction())
{
client.ExpireEntryIn(key, TimeSpan.FromMinutes(this.sessionTimeoutMinutes));
transaction.QueueCommand(c => c.ExpireEntryIn(key, TimeSpan.FromMinutes(this.sessionTimeoutMinutes)));
transaction.Commit();
}
}

public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item)
{
var key = this.GetSessionIdKey(id);
using (var client = this.GetClient())
using (var client = this.GetClientAndWatch(key))
{
var stateRaw = client.GetAllEntriesFromHashRaw(key);
RedisSessionState state;
if (RedisSessionState.TryParse(stateRaw, out state) && state.Locked && state.LockId == (int)lockId)

using (var transaction = client.CreateTransaction())
{
client.Remove(key);
RedisSessionState state;
if (RedisSessionState.TryParse(stateRaw, out state) && state.Locked && state.LockId == (int)lockId)
{
transaction.QueueCommand(c => c.Remove(key));
}

transaction.Commit();
}
}
}
Expand All @@ -241,13 +251,14 @@ private SessionStateStoreData GetItem(bool isExclusive, HttpContext context, str
lockId = null;
actions = SessionStateActions.None;

using (var client = this.GetClient())
using (var client = this.GetClientAndWatch(key))
{
var stateRaw = client.GetAllEntriesFromHashRaw(key);

RedisSessionState state;
if (!RedisSessionState.TryParse(stateRaw, out state))
{
client.UnWatch();
return null;
}

Expand All @@ -256,6 +267,7 @@ private SessionStateStoreData GetItem(bool isExclusive, HttpContext context, str

if (state.Locked)
{
client.UnWatch();
locked = true;
lockId = state.LockId;
lockAge = DateTime.UtcNow - state.LockDate;
Expand Down Expand Up @@ -286,7 +298,7 @@ private SessionStateStoreData GetItem(bool isExclusive, HttpContext context, str
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{
var key = this.GetSessionIdKey(id);
using (var client = this.GetClient())
using (var client = this.GetClientAndWatch(key))
{
this.UpdateSessionStateIfLocked(client, key, (int)lockId, state =>
{
Expand All @@ -299,7 +311,7 @@ public override void ReleaseItemExclusive(HttpContext context, string id, object
public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem)
{
var key = this.GetSessionIdKey(id);
using (var client = this.GetClient())
using (var client = this.GetClientAndWatch(key))
{
if (newItem)
{
Expand Down

0 comments on commit 054984e

Please sign in to comment.