View Javadoc

1   // ========================================================================
2   // Copyright 2006 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  
15  package org.mortbay.cometd.continuation;
16  
17  import org.mortbay.cometd.ClientImpl;
18  import org.mortbay.thread.Timeout;
19  import org.mortbay.util.ajax.Continuation;
20  
21  /* ------------------------------------------------------------ */
22  /**
23   * Extension of {@link ClientImpl} that uses {@link Continuation}s to
24   * resume clients waiting for messages. Continuation clients are used for
25   * remote clients and have removed if they are not accessed within
26   * an idle timeout (@link {@link ContinuationBayeux#_clientTimer}).
27   * 
28   * @author gregw
29   *
30   */
31  public class ContinuationClient extends ClientImpl
32  {
33      private long _accessed;
34      public transient Timeout.Task _timeout; 
35      private ContinuationBayeux _bayeux;
36      private transient Continuation _continuation;
37  
38      /* ------------------------------------------------------------ */
39      protected ContinuationClient(ContinuationBayeux bayeux)
40      {
41          super(bayeux);
42          _bayeux=bayeux;
43  
44          if (!isLocal())
45          {
46              _timeout=new Timeout.Task()
47              {
48                  @Override
49                                  public void expired()
50                  {
51                      remove(true);
52                  }
53                  @Override
54                                  public String toString()
55                  {
56                      return "T-"+ContinuationClient.this.toString();
57                  }
58              };
59              _bayeux.startTimeout(_timeout,getTimeout());
60          }
61      }
62  
63  
64      /* ------------------------------------------------------------ */
65      public void setContinuation(Continuation continuation)
66      {
67          if (continuation==null)
68          {
69              synchronized (this)
70              {
71                  if (_continuation!=null)
72                  {
73                      if(_continuation.isPending())
74                          _continuation.resume(); 
75                  }
76                  _continuation=null;
77                  if(_timeout!=null)
78                      _bayeux.startTimeout(_timeout,getTimeout());
79              }
80          }
81          else
82          {
83              synchronized (this)
84              {
85                  if (_continuation!=null)
86                  {
87                      if(_continuation.isPending())
88                          _continuation.resume(); 
89                  }
90                  _continuation=continuation;
91                  _bayeux.cancelTimeout(_timeout);
92              }
93          }
94      }
95      
96      /* ------------------------------------------------------------ */
97      public Continuation getContinuation()
98      {
99          return _continuation;
100     }
101 
102     /* ------------------------------------------------------------ */
103     @Override
104         public void resume()
105     {
106         synchronized (this)
107         {
108             if (_continuation!=null)
109             {
110                 _continuation.resume();
111             }
112             _continuation=null;
113         }        
114     }
115 
116     /* ------------------------------------------------------------ */
117     @Override
118     public boolean isLocal()
119     {
120         return false;
121     }
122 
123     /* ------------------------------------------------------------ */
124     public void access()
125     {
126         synchronized(this)
127         {
128             // distribute access time in cluster
129             _accessed=_bayeux.getNow();
130             if (_timeout!=null && _timeout.isScheduled())
131             {
132                 _timeout.reschedule();
133             }
134         }
135     }
136 
137 
138     /* ------------------------------------------------------------ */
139     public synchronized long lastAccessed()
140     {
141         return _accessed;
142     }
143     
144     /* ------------------------------------------------------------ */
145     /* (non-Javadoc)
146      * @see org.mortbay.cometd.ClientImpl#remove(boolean)
147      */
148     @Override
149     public void remove(boolean wasTimeout) 
150     {
151         synchronized(this)
152         {
153             if (!wasTimeout && _timeout!=null)
154                 _bayeux.cancelTimeout(_timeout);
155             _timeout=null;
156             super.remove(wasTimeout);
157         }        
158     }
159 
160 }