1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.nosql;
20
21
22 import java.util.HashSet;
23 import java.util.Set;
24 import java.util.concurrent.atomic.AtomicInteger;
25
26 import javax.servlet.http.HttpServletRequest;
27
28 import org.eclipse.jetty.server.session.MemSession;
29 import org.eclipse.jetty.util.log.Log;
30 import org.eclipse.jetty.util.log.Logger;
31
32
33
34 public class NoSqlSession extends MemSession
35 {
36 private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
37
38 private enum IdleState {NOT_IDLE, IDLE, IDLING, DEIDLING};
39
40 private final NoSqlSessionManager _manager;
41 private Set<String> _dirty;
42 private final AtomicInteger _active = new AtomicInteger();
43 private Object _version;
44 private long _lastSync;
45
46 private IdleState _idle = IdleState.NOT_IDLE;
47
48 private boolean _deIdleFailed;
49
50
51 public NoSqlSession(NoSqlSessionManager manager, HttpServletRequest request)
52 {
53 super(manager, request);
54 _manager=manager;
55 _active.incrementAndGet();
56 }
57
58
59 public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId, Object version)
60 {
61 super(manager, created,accessed,clusterId);
62 _manager=manager;
63 _version=version;
64 }
65
66
67 @Override
68 public Object doPutOrRemove(String name, Object value)
69 {
70 synchronized (this)
71 {
72 Object old = super.doPutOrRemove(name,value);
73
74 if (_manager.getSavePeriod()==-2)
75 {
76 save(true);
77 }
78 return old;
79 }
80 }
81
82
83
84 @Override
85 public void setAttribute(String name, Object value)
86 {
87 Object old = changeAttribute(name,value);
88 if (value == null && old == null)
89 return;
90
91 if (value==null || !value.equals(old))
92 {
93 if (_dirty==null)
94 {
95 _dirty=new HashSet<String>();
96 }
97
98 _dirty.add(name);
99 }
100 }
101
102
103
104 @Override
105 protected void timeout() throws IllegalStateException
106 {
107 super.timeout();
108 }
109
110
111
112
113 @Override
114 protected void checkValid() throws IllegalStateException
115 {
116
117
118 if (!isDeIdleFailed() && _manager.getIdlePeriod() > 0 && isIdle())
119 deIdle();
120 super.checkValid();
121 }
122
123
124 @Override
125 protected boolean access(long time)
126 {
127 if (LOG.isDebugEnabled())
128 LOG.debug("NoSqlSession:access:active {} time {}", _active, time);
129 if (_active.incrementAndGet()==1)
130 {
131 long period=_manager.getStalePeriod()*1000L;
132 if (period==0)
133 refresh();
134 else if (period>0)
135 {
136 long stale=time-_lastSync;
137 if (LOG.isDebugEnabled())
138 LOG.debug("NoSqlSession:access:stale "+stale);
139 if (stale>period)
140 refresh();
141 }
142 }
143
144 return super.access(time);
145 }
146
147
148 @Override
149 protected void complete()
150 {
151 super.complete();
152 if(_active.decrementAndGet()==0)
153 {
154 switch(_manager.getSavePeriod())
155 {
156 case 0:
157 save(isValid());
158 break;
159 case 1:
160 if (isDirty())
161 save(isValid());
162 break;
163
164 }
165 }
166 }
167
168
169 @Override
170 protected void doInvalidate() throws IllegalStateException
171 {
172 super.doInvalidate();
173
174 save(false);
175 }
176
177
178 protected void save(boolean activateAfterSave)
179 {
180 synchronized (this)
181 {
182 _version=_manager.save(this,_version,activateAfterSave);
183 _lastSync=getAccessed();
184 }
185 }
186
187
188
189 public void idle ()
190 {
191 synchronized (this)
192 {
193 if (!isIdle() && !isIdling())
194 {
195 if (LOG.isDebugEnabled())
196 LOG.debug("Idling {}", super.getId());
197 setIdling();
198 save(false);
199 willPassivate();
200 clearAttributes();
201 setIdle(true);
202 }
203 }
204 }
205
206
207
208 public synchronized void deIdle()
209 {
210 if (LOG.isDebugEnabled())
211 LOG.debug("Checking before de-idling {}, isidle:{}, isDeidleFailed:", super.getId(), isIdle(), isDeIdleFailed());
212
213 if (isIdle() && !isDeIdleFailed())
214 {
215
216 setDeIdling();
217 if (LOG.isDebugEnabled())
218 LOG.debug("De-idling " + super.getId());
219
220
221 super.access(System.currentTimeMillis());
222
223
224 if (isValid())
225 {
226 try
227 {
228 setIdle(false);
229 _version=_manager.refresh(this, new Long(0));
230 if (_version == null)
231 setDeIdleFailed(true);
232 }
233 catch (Exception e)
234 {
235 setDeIdleFailed(true);
236 LOG.warn("Problem de-idling session " + super.getId(), e);
237 invalidate();
238 }
239 }
240 }
241 }
242
243
244 public synchronized boolean isIdle ()
245 {
246 return _idle == IdleState.IDLE;
247 }
248
249
250
251 public synchronized boolean isIdling ()
252 {
253 return _idle == IdleState.IDLING;
254 }
255
256
257 public synchronized boolean isDeIdling()
258 {
259 return _idle == IdleState.DEIDLING;
260 }
261
262
263 public synchronized void setIdling ()
264 {
265 _idle = IdleState.IDLING;
266 }
267
268 public synchronized void setDeIdling ()
269 {
270 _idle = IdleState.DEIDLING;
271 }
272
273
274 public synchronized void setIdle (boolean idle)
275 {
276 if (idle)
277 _idle = IdleState.IDLE;
278 else
279 _idle = IdleState.NOT_IDLE;
280 }
281
282
283 public boolean isDeIdleFailed()
284 {
285 return _deIdleFailed;
286 }
287
288 public void setDeIdleFailed(boolean _deIdleFailed)
289 {
290 this._deIdleFailed = _deIdleFailed;
291 }
292
293
294 protected void refresh()
295 {
296 synchronized (this)
297 {
298 _version=_manager.refresh(this,_version);
299 }
300 }
301
302
303 public boolean isDirty()
304 {
305 synchronized (this)
306 {
307 return _dirty!=null && !_dirty.isEmpty();
308 }
309 }
310
311
312 public Set<String> takeDirty()
313 {
314 synchronized (this)
315 {
316 Set<String> dirty=_dirty;
317 if (dirty==null)
318 dirty= new HashSet<String>();
319 else
320 _dirty=null;
321 return dirty;
322 }
323 }
324
325
326 public Object getVersion()
327 {
328 return _version;
329 }
330
331
332
333 @Override
334 public void setClusterId(String clusterId)
335 {
336 super.setClusterId(clusterId);
337 }
338
339
340
341 @Override
342 public void setNodeId(String nodeId)
343 {
344 super.setNodeId(nodeId);
345 }
346 }