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 }