1
2
3
4
5
6
7
8
9
10
11
12
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
24
25
26
27
28
29
30
31 public class ContinuationClient extends ClientImpl
32 {
33 private long _accessed;
34 public final Timeout.Task _intervalTimeoutTask;
35 public final Timeout.Task _lazyTimeoutTask;
36 private ContinuationBayeux _bayeux;
37 private volatile Continuation _continuation;
38 private volatile boolean _lazyResuming;
39
40
41 protected ContinuationClient(ContinuationBayeux bayeux)
42 {
43 super(bayeux);
44 _bayeux=bayeux;
45
46 if (isLocal())
47 {
48 _intervalTimeoutTask=null;
49 _lazyTimeoutTask=null;
50 }
51 else
52 {
53 _intervalTimeoutTask=new Timeout.Task()
54 {
55 @Override
56 public void expired()
57 {
58 remove(true);
59 }
60
61 @Override
62 public String toString()
63 {
64 return "T-" + ContinuationClient.this.toString();
65 }
66 };
67
68 _lazyTimeoutTask=new Timeout.Task()
69 {
70 @Override
71 public void expired()
72 {
73 _lazyResuming=false;
74 if (hasMessages())
75 resume();
76 }
77
78 @Override
79 public String toString()
80 {
81 return "L-" + ContinuationClient.this.toString();
82 }
83 };
84
85 _bayeux.startIntervalTimeout(_intervalTimeoutTask,getInterval());
86 }
87 }
88
89
90 public void setContinuation(Continuation continuation)
91 {
92 if (continuation == null)
93 {
94 synchronized(this)
95 {
96 if (_continuation != null)
97 {
98 if (_continuation.isPending())
99 _continuation.resume();
100 }
101 _continuation=null;
102 if (_intervalTimeoutTask != null)
103 _bayeux.startIntervalTimeout(_intervalTimeoutTask,getInterval());
104 }
105 }
106 else
107 {
108 synchronized(this)
109 {
110 if (_continuation != null)
111 {
112 if (_continuation.isPending())
113 _continuation.resume();
114 }
115 _continuation=continuation;
116 _bayeux.cancelIntervalTimeout(_intervalTimeoutTask);
117 _accessed=_bayeux.getNow();
118 }
119 }
120 }
121
122
123 public Continuation getContinuation()
124 {
125 return _continuation;
126 }
127
128
129 @Override
130 public void lazyResume()
131 {
132 int max=_bayeux.getMaxLazyLatency();
133 if (max>0 && _lazyTimeoutTask!=null && !_lazyResuming)
134 {
135 _lazyResuming=true;
136
137 _bayeux.startIntervalTimeout(_lazyTimeoutTask,_accessed%max);
138 }
139 }
140
141
142 @Override
143 public void resume()
144 {
145 synchronized(this)
146 {
147 if (_continuation != null)
148 {
149 _continuation.resume();
150 }
151 _continuation=null;
152 }
153 }
154
155
156 @Override
157 public boolean isLocal()
158 {
159 return false;
160 }
161
162
163 public void access()
164 {
165 synchronized(this)
166 {
167 _accessed=_bayeux.getNow();
168 if (_intervalTimeoutTask != null && _intervalTimeoutTask.isScheduled())
169 {
170
171
172 _intervalTimeoutTask.reschedule();
173 }
174 }
175 }
176
177
178 public synchronized long lastAccessed()
179 {
180 return _accessed;
181 }
182
183
184
185
186
187
188
189 @Override
190 public void remove(boolean wasTimeout)
191 {
192 synchronized(this)
193 {
194 if (!wasTimeout && _intervalTimeoutTask!=null)
195 _bayeux.cancelIntervalTimeout(_intervalTimeoutTask);
196 }
197 super.remove(wasTimeout);
198 }
199 }