View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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       * a boolean version of the setAttribute method that lets us manage the _dirty set
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 }