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 import java.util.HashSet;
22 import java.util.Set;
23 import java.util.concurrent.atomic.AtomicInteger;
24
25 import javax.servlet.http.HttpServletRequest;
26
27 import org.eclipse.jetty.server.session.AbstractSession;
28 import org.eclipse.jetty.util.log.Log;
29 import org.eclipse.jetty.util.log.Logger;
30
31
32
33 public class NoSqlSession extends AbstractSession
34 {
35 private final static Logger __log = Log.getLogger("org.eclipse.jetty.server.session");
36
37 private final NoSqlSessionManager _manager;
38 private Set<String> _dirty;
39 private final AtomicInteger _active = new AtomicInteger();
40 private Object _version;
41 private long _lastSync;
42
43
44 public NoSqlSession(NoSqlSessionManager manager, HttpServletRequest request)
45 {
46 super(manager, request);
47 _manager=manager;
48 save(true);
49 _active.incrementAndGet();
50 }
51
52
53 public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId, Object version)
54 {
55 super(manager, created,accessed,clusterId);
56 _manager=manager;
57 _version=version;
58 }
59
60
61 @Override
62 public Object doPutOrRemove(String name, Object value)
63 {
64 synchronized (this)
65 {
66 Object old = super.doPutOrRemove(name,value);
67
68 if (_manager.getSavePeriod()==-2)
69 {
70 save(true);
71 }
72 return old;
73 }
74 }
75
76
77
78 @Override
79 public void setAttribute(String name, Object value)
80 {
81 if ( updateAttribute(name,value) )
82 {
83 if (_dirty==null)
84 {
85 _dirty=new HashSet<String>();
86 }
87
88 _dirty.add(name);
89 }
90 }
91
92
93
94
95 protected boolean updateAttribute (String name, Object value)
96 {
97 Object old=null;
98 synchronized (this)
99 {
100 checkValid();
101 old=doPutOrRemove(name,value);
102 }
103
104 if (value==null || !value.equals(old))
105 {
106 if (old!=null)
107 unbindValue(name,old);
108 if (value!=null)
109 bindValue(name,value);
110
111 _manager.doSessionAttributeListeners(this,name,old,value);
112 return true;
113 }
114 return false;
115 }
116
117
118 @Override
119 protected void checkValid() throws IllegalStateException
120 {
121 super.checkValid();
122 }
123
124
125 @Override
126 protected boolean access(long time)
127 {
128 __log.debug("NoSqlSession:access:active "+_active);
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 __log.debug("NoSqlSession:access:stale "+stale);
138 if (stale>period)
139 refresh();
140 }
141 }
142
143 return super.access(time);
144 }
145
146
147 @Override
148 protected void complete()
149 {
150 super.complete();
151 if(_active.decrementAndGet()==0)
152 {
153 switch(_manager.getSavePeriod())
154 {
155 case 0:
156 save(isValid());
157 break;
158 case 1:
159 if (isDirty())
160 save(isValid());
161 break;
162
163 }
164 }
165 }
166
167
168 @Override
169 protected void doInvalidate() throws IllegalStateException
170 {
171 super.doInvalidate();
172 save(false);
173 }
174
175
176 protected void save(boolean activateAfterSave)
177 {
178 synchronized (this)
179 {
180 _version=_manager.save(this,_version,activateAfterSave);
181 _lastSync=getAccessed();
182 }
183 }
184
185
186
187 protected void refresh()
188 {
189 synchronized (this)
190 {
191 _version=_manager.refresh(this,_version);
192 }
193 }
194
195
196 public boolean isDirty()
197 {
198 synchronized (this)
199 {
200 return _dirty!=null && !_dirty.isEmpty();
201 }
202 }
203
204
205 public Set<String> takeDirty()
206 {
207 synchronized (this)
208 {
209 Set<String> dirty=_dirty;
210 if (dirty==null)
211 dirty= new HashSet<String>();
212 else
213 _dirty=null;
214 return dirty;
215 }
216 }
217
218
219 public Object getVersion()
220 {
221 return _version;
222 }
223
224 @Override
225 public void setClusterId(String clusterId)
226 {
227 super.setClusterId(clusterId);
228 }
229
230 @Override
231 public void setNodeId(String nodeId)
232 {
233 super.setNodeId(nodeId);
234 }
235
236
237
238 }