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 try
121 {
122 super.checkValid();
123 }
124 catch (IllegalStateException e)
125 {
126 throw new IllegalStateException (e.getMessage()+" idle="+_idle+" deidleFailed="+_deIdleFailed+" version="+_version, e);
127 }
128 }
129
130
131
132
133 @Override
134 protected boolean access(long time)
135 {
136 if (LOG.isDebugEnabled())
137 LOG.debug("NoSqlSession:access:active {} time {}", _active, time);
138 if (_active.incrementAndGet()==1)
139 {
140 long period=_manager.getStalePeriod()*1000L;
141 if (period==0)
142 refresh();
143 else if (period>0)
144 {
145 long stale=time-_lastSync;
146 if (LOG.isDebugEnabled())
147 LOG.debug("NoSqlSession:access:stale "+stale);
148 if (stale>period)
149 refresh();
150 }
151 }
152
153 return super.access(time);
154 }
155
156
157 @Override
158 protected void complete()
159 {
160 super.complete();
161 if(_active.decrementAndGet()==0)
162 {
163 switch(_manager.getSavePeriod())
164 {
165 case 0:
166 save(isValid());
167 break;
168 case 1:
169 if (isDirty())
170 save(isValid());
171 break;
172
173 }
174 }
175 }
176
177
178 @Override
179 protected void doInvalidate() throws IllegalStateException
180 {
181 super.doInvalidate();
182
183 save(false);
184 }
185
186
187 protected void save(boolean activateAfterSave)
188 {
189 synchronized (this)
190 {
191 _version=_manager.save(this,_version,activateAfterSave);
192 _lastSync=getAccessed();
193 }
194 }
195
196
197
198 public void idle ()
199 {
200 synchronized (this)
201 {
202 if (!isIdle() && !isIdling())
203 {
204 if (LOG.isDebugEnabled())
205 LOG.debug("Idling {}", super.getId());
206 setIdling();
207 save(false);
208 willPassivate();
209 clearAttributes();
210 setIdle(true);
211 }
212 }
213 }
214
215
216
217 public synchronized void deIdle()
218 {
219 if (LOG.isDebugEnabled())
220 LOG.debug("Checking before de-idling {}, isidle:{}, isDeidleFailed:", super.getId(), isIdle(), isDeIdleFailed());
221
222 if (isIdle() && !isDeIdleFailed())
223 {
224
225 setDeIdling();
226 if (LOG.isDebugEnabled())
227 LOG.debug("De-idling " + super.getId());
228
229
230 super.access(System.currentTimeMillis());
231
232
233 if (isValid())
234 {
235 try
236 {
237 setIdle(false);
238 _version=_manager.refresh(this, new Long(0));
239 if (_version == null)
240 setDeIdleFailed(true);
241 }
242 catch (Exception e)
243 {
244 setDeIdleFailed(true);
245 LOG.warn("Problem de-idling session " + super.getId(), e);
246 invalidate();
247 }
248 }
249 }
250 }
251
252
253 public synchronized boolean isIdle ()
254 {
255 return _idle == IdleState.IDLE;
256 }
257
258
259
260 public synchronized boolean isIdling ()
261 {
262 return _idle == IdleState.IDLING;
263 }
264
265
266 public synchronized boolean isDeIdling()
267 {
268 return _idle == IdleState.DEIDLING;
269 }
270
271
272 public synchronized void setIdling ()
273 {
274 _idle = IdleState.IDLING;
275 }
276
277 public synchronized void setDeIdling ()
278 {
279 _idle = IdleState.DEIDLING;
280 }
281
282
283 public synchronized void setIdle (boolean idle)
284 {
285 if (idle)
286 _idle = IdleState.IDLE;
287 else
288 _idle = IdleState.NOT_IDLE;
289 }
290
291
292 public boolean isDeIdleFailed()
293 {
294 return _deIdleFailed;
295 }
296
297 public void setDeIdleFailed(boolean _deIdleFailed)
298 {
299 this._deIdleFailed = _deIdleFailed;
300 }
301
302
303 protected void refresh()
304 {
305 synchronized (this)
306 {
307 _version=_manager.refresh(this,_version);
308 }
309 }
310
311
312 public boolean isDirty()
313 {
314 synchronized (this)
315 {
316 return _dirty!=null && !_dirty.isEmpty();
317 }
318 }
319
320
321 public Set<String> takeDirty()
322 {
323 synchronized (this)
324 {
325 Set<String> dirty=_dirty;
326 if (dirty==null)
327 dirty= new HashSet<String>();
328 else
329 _dirty=null;
330 return dirty;
331 }
332 }
333
334
335 public Object getVersion()
336 {
337 return _version;
338 }
339
340
341
342 @Override
343 public void setClusterId(String clusterId)
344 {
345 super.setClusterId(clusterId);
346 }
347
348
349
350 @Override
351 public void setNodeId(String nodeId)
352 {
353 super.setNodeId(nodeId);
354 }
355 }