View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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.MemSession;
28  import org.eclipse.jetty.util.log.Log;
29  import org.eclipse.jetty.util.log.Logger;
30  
31  
32  /* ------------------------------------------------------------ */
33  public class NoSqlSession extends MemSession
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          _active.incrementAndGet();
49      }
50      
51      /* ------------------------------------------------------------ */
52      public NoSqlSession(NoSqlSessionManager manager, long created, long accessed, String clusterId, Object version)
53      {
54          super(manager, created,accessed,clusterId);
55          _manager=manager;
56          _version=version;
57      }
58      
59      /* ------------------------------------------------------------ */
60      @Override
61      public Object doPutOrRemove(String name, Object value)
62      {
63          synchronized (this)
64          {
65              Object old = super.doPutOrRemove(name,value);
66              
67              if (_manager.getSavePeriod()==-2)
68              {
69                  save(true);
70              }
71              return old;
72          }
73      }
74      
75      
76  
77      @Override
78      public void setAttribute(String name, Object value)
79      {
80          Object old = changeAttribute(name,value);
81          if (value == null && old == null)
82              return; //not dirty, no change
83          
84          if (value==null || !value.equals(old))
85          {
86              if (_dirty==null)
87              {
88                  _dirty=new HashSet<String>();
89              }
90              
91              _dirty.add(name);
92          }
93      }
94      
95      
96  
97      @Override
98      protected void timeout() throws IllegalStateException
99      {
100         super.timeout();
101     }
102 
103 
104     
105     /* ------------------------------------------------------------ */
106     @Override
107     protected void checkValid() throws IllegalStateException
108     {
109         super.checkValid();
110     }
111 
112     /* ------------------------------------------------------------ */
113     @Override
114     protected boolean access(long time)
115     {
116         __log.debug("NoSqlSession:access:active {} time {}", _active, time);
117         if (_active.incrementAndGet()==1)
118         {
119             long period=_manager.getStalePeriod()*1000L;
120             if (period==0)
121                 refresh();
122             else if (period>0)
123             {
124                 long stale=time-_lastSync;
125                 __log.debug("NoSqlSession:access:stale "+stale);
126                 if (stale>period)
127                     refresh();
128             }
129         }
130 
131         return super.access(time);
132     }
133 
134     /* ------------------------------------------------------------ */
135     @Override
136     protected void complete()
137     {
138         super.complete();
139         if(_active.decrementAndGet()==0)
140         {
141             switch(_manager.getSavePeriod())
142             {
143                 case 0: 
144                     save(isValid());
145                     break;
146                 case 1:
147                     if (isDirty())
148                         save(isValid());
149                     break;
150 
151             }
152         }
153     }
154 
155     /* ------------------------------------------------------------ */
156     @Override
157     protected void doInvalidate() throws IllegalStateException
158     {
159         super.doInvalidate();
160         //jb why save here? if the session is invalidated it should be removed
161         save(false);
162     }
163     
164     /* ------------------------------------------------------------ */
165     protected void save(boolean activateAfterSave)
166     {
167         synchronized (this)
168         {
169             _version=_manager.save(this,_version,activateAfterSave);
170             _lastSync=getAccessed();
171         }
172     }
173 
174 
175     /* ------------------------------------------------------------ */
176     protected void refresh()
177     {
178         synchronized (this)
179         {
180             _version=_manager.refresh(this,_version);
181         }
182     }
183 
184     /* ------------------------------------------------------------ */
185     public boolean isDirty()
186     {
187         synchronized (this)
188         {
189             return _dirty!=null && !_dirty.isEmpty();
190         }
191     }
192     
193     /* ------------------------------------------------------------ */
194     public Set<String> takeDirty()
195     {
196         synchronized (this)
197         {
198             Set<String> dirty=_dirty;
199             if (dirty==null)
200                 dirty= new HashSet<String>();
201             else
202                 _dirty=null;
203             return dirty;
204         }
205     }
206 
207     /* ------------------------------------------------------------ */
208     public Object getVersion()
209     {
210         return _version;
211     }
212 
213     @Override
214     public void setClusterId(String clusterId)
215     {
216         super.setClusterId(clusterId);
217     }
218 
219     @Override
220     public void setNodeId(String nodeId)
221     {
222         super.setNodeId(nodeId);
223     }
224 }