thecloudlesssky / harbour.redissessionstatestore Goto Github PK
View Code? Open in Web Editor NEWA Redis based SessionStateStoreProvider written in C# using ServiceStack.Redis.
License: MIT License
A Redis based SessionStateStoreProvider written in C# using ServiceStack.Redis.
License: MIT License
I have just installed Session manager and I keep getting
"Could not load file or assembly "ServiceStack.Interfaces, Version 3.8.3..."
When I installed your package via NuGet, I got version 4.0.9 of ServiceStack assemblies. There seems to be an issue, why doesn't you package work with new libraries. I don't want to add those manually.
After I build the project successfully, I run the "Harbour.RedisSessionStateStore.SampleWeb" project, input something in the fields and submit, it will throw the Null exception. the break point go the " state.Timeout = context.Session.Timeout;", I will watch the "context.Sessiong" is null.
Hi Adrian,
I deployed Harbour Redis on my site but as soon as another user logs in, or more than one user uses the application, I get the following exception:
Exception type: InvalidOperationException
Exception message: A pipeline is already in use
at ServiceStack.Redis.RedisAllPurposePipeline.Init()
at ServiceStack.Redis.RedisClient.CreatePipeline()
at ServiceStack.Redis.Support.Locking.DistributedLock.Lock(String key, Int32 acquisitionTimeout, Int32 lockTimeout, Int64& lockExpire, IRedisClient client)
at ServiceStack.Redis.Support.Locking.DisposableDistributedLock..ctor(IRedisClient client, String globalLockKey, Int32 acquisitionTimeout, Int32 lockTimeout)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetDistributedLock(IRedisClient client, String key)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetItem(Boolean isExclusive, HttpContext context, String id, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actions)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetItemExclusive(HttpContext context, String id, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actions)
at System.Web.SessionState.SessionStateModule.GetSessionStateItem()
at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Here is the web.config entry:
And here is the global.asax:
this.clientManager = new PooledRedisClientManager("localhost:6379");
RedisSessionStateStoreProvider.SetClientManager(this.clientManager);
RedisSessionStateStoreProvider.SetOptions(new RedisSessionStateStoreOptions()
{
KeySeparator = ":",
OnDistributedLockNotAcquired = sessionId =>
{
Console.WriteLine("Session \"{0}\" could not establish distributed lock. " +
"This most likely means you have to increase the " +
"DistributedLockAcquireSeconds/DistributedLockTimeoutSeconds.", sessionId);
}
});
In the web.config, do I need the clientType and host entries? Is there something silly I am missing?
When using MVC5 asp net Identity, external logins stop working after i add reference to Harbour.RedisSessionStateStore using Nuget.
“System.NullReferenceException” in Harbour.RedisSessionStateStore.dll
i use the redis-server 2.8,and configure my web.config the same as readme.md
RedisSessionStateStoreProvider.cs
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{
using (var client = GetClient())
{
UpdateSessionStateIfLocked(client, id, (int)lockId, state =>
{
state.Locked = false;
state.Timeout = context.Session.Timeout;
});
}
}
i fount the context.Session.Timeout is null
Hi! We just updated our app with v1.3 of the Harbour.RedisSessionStateStore. I tested our app manually, and everything appears to be working fine. However in our test (from jmeter, 600 threads hitting couple pages of the app in a loop), we see many errors in the log:
Also want to point out our app makes concurrent requests within a page. We're using servicestack.redis, with pool size set to 100, timeout set to 2000. Redis client connection set to timeout in 600 secs, disk persistent is turned off.
I understand some of these are probably just caused by network latency. But "A transaction is already in use" is a bit concerning, any help is appreciated.
Hello,
I saw a couple of these on both servers in the cluster yesterday. I believe the exception is coming from the Service Stack client though.. I'm running the Ubuntu Precise packaged Redis v2.2.12; not sure if I should go with a newer version?
Description: The process was terminated due to an unhandled exception.
Exception Info: ServiceStack.Redis.RedisResponseException
Stack:
at ServiceStack.Redis.RedisNativeClient.CreateResponseError(System.String)
at ServiceStack.Redis.RedisNativeClient.ReadLong()
at ServiceStack.Redis.Support.Locking.DistributedLock.Lock(System.String, Int32, Int32, Int64 ByRef, ServiceStack.Redis.IRedisClient)
at ServiceStack.Redis.Support.Locking.DisposableDistributedLock..ctor(ServiceStack.Redis.IRedisClient, System.String, Int32, Int32)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetDistributedLock(ServiceStack.Redis.IRedisClient, System.String)
Exception: System.Runtime.Serialization.SerializationException
Message: Type 'ServiceStack.Redis.RedisResponseException' in Assembly 'ServiceStack.Redis, Version=3.9.71.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
StackTrace: at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter, SerializationBinder binder)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeObject(Object obj, MemoryStream stm)
at System.AppDomain.Serialize(Object o)
at System.AppDomain.MarshalObject(Object o)
Exception Info: ServiceStack.Redis.RedisResponseException
Stack:
at ServiceStack.Redis.RedisNativeClient.CreateResponseError(System.String)
at ServiceStack.Redis.RedisNativeClient.ReadLong()
at ServiceStack.Redis.Support.Locking.DistributedLock.Lock(System.String, Int32, Int32, Int64 ByRef, ServiceStack.Redis.IRedisClient)
at ServiceStack.Redis.Support.Locking.DisposableDistributedLock..ctor(ServiceStack.Redis.IRedisClient, System.String, Int32, Int32
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetDistributedLock(ServiceStack.Redis.IRedisClient, System.String)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetItem(Boolean, System.Web.HttpContext, System.String, Boolean ByRef, System.TimeSpan ByRef, System.Object ByRef, System.Web.SessionState.SessionStateActions ByRef)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetItemExclusive(System.Web.HttpContext, System.String, Boolean ByRef, System.TimeSpan ByRef, System.Object ByRef, System.Web.SessionState.SessionStateActions ByRef)
I would like to be able to specify the initial database when setting up the connection.
Here is the code to accomplish this. I was unable to create a pull request.
public override void Initialize(string name, NameValueCollection config)
{
if (String.IsNullOrWhiteSpace(name))
{
name = "AspNetSession";
}
this.name = name;
var sessionConfig = (SessionStateSection)WebConfigurationManager.GetSection("system.web/sessionState");
sessionTimeoutMinutes = (int)sessionConfig.Timeout.TotalMinutes;
lock (locker)
{
if (options == null)
{
SetOptions(new RedisSessionStateStoreOptions());
}
if (clientManagerStatic == null)
{
var host = config["host"];
var clientType = config["clientType"];
var initialDb = config["initialDb"];
clientManager = CreateClientManager(clientType, host, initialDb);
manageClientManagerLifetime = true;
}
else
{
clientManager = clientManagerStatic;
manageClientManagerLifetime = false;
}
}
base.Initialize(name, config);
}
private IRedisClientsManager CreateClientManager(string clientType, string host, string initialDb)
{
if (String.IsNullOrWhiteSpace(host))
{
host = "localhost:6379";
}
if (String.IsNullOrWhiteSpace(clientType))
{
clientType = "POOLED";
}
int database = 0;
if (!int.TryParse(initialDb, out database)) {
database = 0;
}
if (clientType.ToUpper() == "POOLED")
{
return new PooledRedisClientManager(database, host);
}
else
{
return new BasicRedisClientManager(database, host);
}
}
When creating a project from scratch, and adding Harbour.RedisSessionStateStore via Nuget, it's impossible to use this provider because of the version of ServiceStack.Redis (3.0.9).
Got this error :
System.MissingMethodException: Method not found 'Void ServiceStack.Redis.IRedisClient.UnWatch()'
The version 3.0.9 does not containes Watch/UnWatch method.
Updating to latest ServiceStack.Redis solve the issue.
Hi Support,
I have added your solution to my web app and evertyhing seemed to work fine, but now I am getting ocassional slow down of the site, some pages load for 1-2 minutes. As soon as I switch back to InProc session mode, everything is running very fast, then when I switch to Redis (in config), it is either fast as well or randomly slow. I wonder if there is anything I am missing. It is like it has issues writting to Redis database. I don't know. Any suggestions?
I am trying to use Session state store for Web api. How can I do this?
Cannot install latest version.
PM> Install-Package Harbour.RedisSessionStateStore
Attempting to resolve dependency 'ServiceStack.Common (= 3.9 && < 4.0)'.
Attempting to resolve dependency 'ServiceStack.Text'.
Attempting to resolve dependency 'ServiceStack.Redis (= 3.9 && < 4.0)'.
Attempting to resolve dependency 'ServiceStack.Text (= 3.9 && < 4.0)'.
Install-Package : Already referencing a newer version of 'ServiceStack.Text'.
At line:1 char:16
Also I have another project where I was able to install RedisSessionStateStore previously and cannot update the ServiceStack packages which I use separately for Redis access due to the version restrictions in your package. Any thought to merging the required ServiceStack dlls.instead of referencing?
I think ,now,Harbour.RedisSessionStateStore,Get/Set Session items use FCL Binary serialize method.That will let it bound with assembly,hard to share with not same assembly.
In my opinion,we will store json to Redis and store items type to Redis.like this:
private void Set<T>(string key, T o)
{
using (IRedisClient client = RedisPool.redisPool.GetClient())
{
client.SetEntryInHash(_sessionId, key+"Type", o.GetType().ToString());
client.SetEntryInHash(_sessionId, key + "Data", Newtonsoft.Json.JsonConvert.SerializeObject(o));
client.ExpireEntryIn(_sessionId, _expiresIn);
}
}
It can use to any assembly.and session can work to not same appDomain.can be provide SSO!
my English very bad~T.T
If i need to set my redis server URL somewhere other than the web.config, how is that done?
PM> Install-Package Harbour.RedisSessionStateStore
正在尝试解析依赖项“ServiceStack.Common (≥ 3.9 && < 4.0)”。
正在尝试解析依赖项“ServiceStack.Text”。
正在尝试解析依赖项“ServiceStack.Redis (≥ 3.9 && < 4.0)”。
正在尝试解析依赖项“ServiceStack.Text (≥ 3.9 && < 4.0)”。
已引用较新版本的“ServiceStack.Text”。
Is there a way to specify a key prefix?
Is it possible to connect to Azure Redis? Because you need not just the hostname but also provide a password.
Check out the ScottGu blogpost at the bottom for how to connect:
http://weblogs.asp.net/scottgu/archive/2014/05/12/azure-vm-security-extensions-expressroute-ga-reserved-ips-internal-load-balancing-multi-site-to-site-vpns-storage-import-export-ga-new-smb-file-service-api-management-hybrid-connection-service-redis-cache-remote-apps-and-more.aspx
i'm using VS2012 MVC 4 when i'm install Install-Package BetterCMS pakage i'm get this error
Install-Package : Already referencing a newer version of 'NHibernate'.
At line:1 char:16
Error:
Function can not be found "Void ServiceStack.Redis.IRedisClient.UnWatch()"
MissingMethodException: Método no encontrado: 'Void ServiceStack.Redis.IRedisClient.UnWatch()'.]
Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetItem(Boolean isExclusive, HttpContext context, String id, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actions) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:296
Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.GetItemExclusive(HttpContext context, String id, Boolean& locked, TimeSpan& lockAge, Object& lockId, SessionStateActions& actions) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:242
System.Web.SessionState.SessionStateModule.GetSessionStateItem() +115
System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData) +768
System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +96
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
Hi Adrian,
I'm not sure if this is a Harbour Redis specific issue. I've hooked up Harbour Redis and it is working. However, for some users, they randomly get logged out of the application. When I view the Redis CLI, the data for their redis session gets wiped out. We are storing the following in Session (I'm mostly using the HttpContext.Current.Session):
We did have an issue with Telerik reports wherein they were storing data in the session, but it was raw data and was not being converted into the byte array format Redis is expecting. I managed to create a workaround such that it would not be an issue.
In terms of Redis, are there any limitations or gotcha's that one needs to worry about when using Session? Is there something that I may not be aware of?
Note: I am using the MS OpenTech version of Redis
Thank you!
Is it possible to authorize on Redis server using Harbour.RedisSessionStateStore? It seems current implementation doesn't support it.
Like Title
I need it to last at least 2 hours. Thank you!
Hi, I'm having a strange problem after putting the RedisSessionStateStoreProvider in place, occasionally my site would hangs, and if i go on the server and issue a "monitor" command to my redis server, here's a portion of the output:
"watch" "bc/4i0sekkgl3nhis33ddooqyds"
"hgetall" "bc/4i0sekkgl3nhis33ddooqyds"
"unwatch"
"watch" "bc/4i0sekkgl3nhis33ddooqyds"
"hgetall" "bc/4i0sekkgl3nhis33ddooqyds"
"unwatch"
"watch" "bc/4i0sekkgl3nhis33ddooqyds"
"hgetall" "bc/4i0sekkgl3nhis33ddooqyds"
"unwatch"
"watch" "bc/4i0sekkgl3nhis33ddooqyds"
"hgetall" "bc/4i0sekkgl3nhis33ddooqyds"
"unwatch"
"watch" "bc/4i0sekkgl3nhis33ddooqyds"
"hgetall" "bc/4i0sekkgl3nhis33ddooqyds"
"unwatch"
...
...
and it would just keeps going on and on..
doing a hget bc/4i0sekkgl3nhis33ddooqyds locked shows that this key is locked, which I assume is what is causing it to hang?
I run into the same problem when doing load testing with JMeter.
I used the code as is without much modification. I have a master-slave setup (redis v2.8.3). servicestack.redis v3.9.60.
anyone seen this?
Thanks!
-wl
I recently switched from the default session store to RedisSessionStateStore
on a site that I maintain. Since doing so, I have seen periodic errors logged with the following form:
System.NullReferenceException: Object reference not set to an instance of an object.
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:line 367
at System.Web.SessionState.SessionStateModule.OnReleaseState(Object source, EventArgs eventArgs)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
If the line number indicated by the stack trace is accurate, the only thing I see that could cause a NullReferenceException
is the cast of lockId
to an int
, although I am not familiar enough with session state stores to know why this would be the case.
As far as I can tell, the RedisSessionStateStoreProvider can't connect to a master based on the get-master-addr-by-name API available from Redis sentinels.
Are there any plans to add sentinel-connection support?
Hi,
I was trying to set the Session.Timeout in runtime, however the timeout has always being reset to the default timeout. The default timeout is taken from the web.config. Based on your code, it seems like the culprit is that the timeout is set to default in ReleaseItemExclusive.
public override void ReleaseItemExclusive(HttpContext context, string id, object lockId)
{
using (var client = GetClient())
{
UpdateSessionStateIfLocked(client, id, (int)lockId, state =>
{
state.Locked = false;
state.Timeout = sessionTimeoutMinutes;
});
}
}
Is there any reason why the session timeout is set to default value? Or, I could miss something.
defaultDistributedLockAcquisitionTimeoutSeconds = 1;
defaultDistributedLockTimeoutSeconds = 1;
Hello,
Thanks for the project, it is working very well :-)
I am trying to figure out how to handle expiring items from the session. I can see that SetItemExpireCallback is not implemented, so I am wondering if I should go down that road, or maybe SS has a way to subscribe to expiring keys so I can snatch them and push to a database.
I am just starting working with Redis, so any thoughts are highly appreciated!
@TheCloudlessSky I am new to this Redis Session store. I have successfully add Redis to my MVC 5 project. but when add new session it gives RedisSessionStateStoreProvider.cs
not found error. Please help me to solve this.
StackTrace
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.<>c__DisplayClass7.<ResetItemTimeout>b__5(IRedisClient c) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:line 257
at ServiceStack.Redis.RedisCommandQueue.QueueCommand(Func`2 command, Action`1 onSuccessCallback, Action`1 onErrorCallback)
at ServiceStack.Redis.RedisCommandQueue.QueueCommand(Func`2 command)
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.<>c__DisplayClass7.<ResetItemTimeout>b__4(IRedisTransaction transaction) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:line 257
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.UseTransaction(IRedisClient client, Action`1 action) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:line 245
at Harbour.RedisSessionStateStore.RedisSessionStateStoreProvider.ResetItemTimeout(HttpContext context, String id) in d:\Repositories\Harbour.RedisSessionStateStore\src\Harbour.RedisSessionStateStore\RedisSessionStateStoreProvider.cs:line 255
at System.Web.SessionState.SessionStateModule.BeginAcquireState(Object source, EventArgs e, AsyncCallback cb, Object extraData)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
What kind of license is Harbour relased under?
Sorry for using an issue as a way of asking you the question, didn't really find any other way of contacting you.
Best regards,
Emanuel
I'm trying to use this project in asp.net mvc3, it always throw NullReferenceException when get context.Session.Timeout property, because of the context.Session is not initialized yet at RedisSessionStateStoreProvider.cs:257
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.