You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.markdown
+53-12Lines changed: 53 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,21 @@ The manager relies on the native expiration capability of Redis to expire keys f
12
12
13
13
Data stored in the session must be Serializable.
14
14
15
+
16
+
Support this project!
17
+
---------------------
18
+
19
+
This is an open-source project. Currently I'm not using this for anything personal or professional, so I'm not able to commit much time to the project, though I attempt to merge in reasonable pull requests. If you like to support further development of this project, you can donate via Pledgie:
20
+
21
+
<ahref='https://pledgie.com/campaigns/26802'><imgalt='Click here to lend your support to: Tomcat Redis Session Manager and make a donation at pledgie.com !'src='https://pledgie.com/campaigns/26802.png?skin_name=chrome'border='0' ></a>
22
+
23
+
24
+
Commercial Support
25
+
------------------
26
+
27
+
If your business depends on Tomcat and persistent sessions and you need a specific feature this project doesn't yet support, a quick bug fix you don't have time to author, or commercial support when things go wrong, I can provide support on a contractual support through my consultancy, Orange Function, LLC. If you have any questions or would like to begin discussing a deal, please contact me via email at james@orangefunction.com.
28
+
29
+
15
30
Tomcat Versions
16
31
---------------
17
32
@@ -38,19 +53,31 @@ Usage
38
53
39
54
Add the following into your Tomcat context.xml (or the context block of the server.xml if applicable.)
Copy the tomcat-redis-session-manager.jar and jedis-2.0.0.jar files into the `lib` directory of your Tomcat installation.
68
+
Copy the following files into the `TOMCAT_BASE/lib` directory:
69
+
70
+
* tomcat-redis-session-manager-VERSION.jar
71
+
* jedis-2.5.2.jar
72
+
* commons-pool2-2.2.jar
51
73
52
74
Reboot the server, and sessions should now be stored in Redis.
53
75
76
+
Connection Pool Configuration
77
+
-----------------------------
78
+
79
+
All of the configuration options from both `org.apache.commons.pool2.impl.GenericObjectPoolConfig` and `org.apache.commons.pool2.impl.BaseObjectPoolConfig` are also configurable for the Redis connection pool used by the session manager. To configure any of these attributes (e.g., `maxIdle` and `testOnBorrow`) just use the config attribute name prefixed with `connectionPool` (e.g., `connectionPoolMaxIdle` and `connectionPoolTestOnBorrow`) and set the desired value in the `<Manager>` declaration in your Tomcat context.xml.
80
+
54
81
Session Change Tracking
55
82
-----------------------
56
83
@@ -88,20 +115,34 @@ Then the example above would look like this:
88
115
myArray.add(additionalArrayValue);
89
116
session.setAttribute("customDirtyFlag");
90
117
118
+
Persistence Policies
119
+
--------------------
91
120
92
-
Possible Issues
93
-
---------------
121
+
With an persistent session storage there is going to be the distinct possibility of race conditions when requests for the same session overlap/occur concurrently. Additionally, because the session manager works by serializing the entire session object into Redis, concurrent updating of the session will exhibit last-write-wins behavior for the entire session (not just specific session attributes).
122
+
123
+
Since each situation is different, the manager gives you several options which control the details of when/how sessions are persisted. Each of the following options may be selected by setting the `sessionPersistPolicies="PERSIST_POLICY_1,PERSIST_POLICY_2,.."` attributes in your manager declaration in Tomcat's context.xml. Unless noted otherwise, the various options are all combinable.
124
+
125
+
-`SAVE_ON_CHANGE`: every time `session.setAttribute()` or `session.removeAttribute()` is called the session will be saved. __Note:__ This feature cannot detect changes made to objects already stored in a specific session attribute. __Tradeoffs__: This option will degrade performance slightly as any change to the session will save the session synchronously to Redis.
126
+
-`ALWAYS_SAVE_AFTER_REQUEST`: force saving after every request, regardless of whether or not the manager has detected changes to the session. This option is particularly useful if you make changes to objects already stored in a specific session attribute. __Tradeoff:__ This option make actually increase the liklihood of race conditions if not all of your requests change the session.
94
127
95
-
There is the possibility of a race condition that would cause seeming invisibility of the session immediately after your web application logs in a user: if the response has finished streaming and the client requests a new page before the valve has been able to complete saving the session into Redis, then the new request will not see the session.
96
128
97
-
This condition will be detected by the session manager and a java.lang.IllegalStateException with the message `Race condition encountered: attempted to load session[SESSION_ID] which has been created but not yet serialized.` will be thrown.
129
+
Testing/Example App
130
+
-------------------
98
131
99
-
Normally this should be incredibly unlikely (insert joke about programmers and "this should never happen" statements here) since the connection to save the session into Redis is almost guaranteed to be faster than the latency between a client receiving the response, processing it, and starting a new request.
132
+
For full integration testing as well as a demonstration of how to use the session manager, this project contains an example app and a virtual server setup via Vagrant and Chef.
100
133
101
-
Possible solutions:
134
+
To get the example server up and running, you'll need to do the following:
135
+
1. Download and install Virtual Box (4.3.12 at the time of this writing) from https://www.virtualbox.org/wiki/Downloads
136
+
1. Download and install the latest version (1.6.3 at the time of this writing) of Vagrant from http://www.vagrantup.com/downloads.html
137
+
1. Install Ruby, if necessary.
138
+
1. Install Berkshelf with `gem install berkshelf`
139
+
1. Install the Vagrant Berkshelf plugin with `vagrant plugin install vagrant-berkshelf --plugin-version '>= 2.0.1'`
140
+
1. Install the Vagrant Cachier plugin for _speed_ with `vagrant plugin install vagrant-cachier`
141
+
1. Install the Vagrant Omnibus plugin with `vagrant plugin install vagrant-omnibus`
142
+
1. Install the required Ruby gems with `PROJECT_ROOT/bundle install`
143
+
1. Boot the virtual machine with `PROJECT_ROOT/vagrant up`
144
+
1. Run the tests with `PROJECT_ROOT/rspec`
102
145
103
-
- Enable the "save on change" feature by setting `saveOnChange` to `true` in your manager declaration in Tomcat's context.xml. Using this feature will degrade performance slightly as any change to the session will save the session synchronously to Redis, and technically this will still exhibit slight race condition behavior, but it eliminates as much possiblity of errors occurring as possible.
104
-
- If you encounter errors, then you can force save the session early (before sending a response to the client) then you can retrieve the current session, and call `currentSession.manager.save(currentSession)` to synchronously eliminate the race condition. Note: this will only work directly if your application has the actual session object directly exposed. Many frameworks (and often even Tomcat) will expose the session in their own wrapper HttpSession implementing class. You may be able to dig through these layers to expose the actual underlying RedisSession instance--if so, then using that instance will allow you to implement the workaround.
0 commit comments