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 }