public void cancel() throws IOException {

    if (!isCancelled.getAndSet(true)) {
      logger.trace("Cancelling {}", uuid);

      if (config.getBroadcasterFactory().getDefault() != null) {
        config.getBroadcasterFactory().getDefault().removeAllAtmosphereResource(this);
        if (transport.equals(TRANSPORT.WEBSOCKET)) {
          String parentUUID = (String) req.getAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
          AtmosphereResource p = AtmosphereResourceFactory.getDefault().find(parentUUID);
          if (p != null) {
            config.getBroadcasterFactory().getDefault().removeAllAtmosphereResource(p);
          }
        }
      }

      asyncSupport.complete(this);

      SessionTimeoutSupport.restoreTimeout(req);
      action.type(Action.TYPE.CANCELLED);
      if (asyncSupport != null) asyncSupport.action(this);
      // We must close the underlying WebSocket as well.
      if (AtmosphereResponse.class.isAssignableFrom(response.getClass())) {
        AtmosphereResponse.class.cast(response).close();
        AtmosphereResponse.class.cast(response).destroy();
      }

      if (AtmosphereRequest.class.isAssignableFrom(req.getClass())) {
        AtmosphereRequest.class.cast(req).destroy();
      }
      req.removeAttribute(FrameworkConfig.ATMOSPHERE_RESOURCE);
      event.destroy();
    }
  }
  public synchronized void cancel() throws IOException {
    action.type(Action.TYPE.RESUME);
    if (isCancelled.getAndSet(true)) return;

    if (asyncSupport instanceof AsynchronousProcessor) {
      try {
        AsynchronousProcessor.class.cast(asyncSupport).resumed(req, response);
      } catch (ServletException e) {
        logger.trace("", e);
      }
    }
    asyncSupport.action(this);
    // We must close the underlying WebSocket as well.
    if (AtmosphereResponse.class.isAssignableFrom(response.getClass())) {
      AtmosphereResponse.class.cast(response).close();
      AtmosphereResponse.class.cast(response).destroy();
    }

    if (AtmosphereRequest.class.isAssignableFrom(req.getClass())) {
      AtmosphereRequest.class.cast(req).destroy();
    }

    // TODO: Grab some measurement.
    //        req = null;
    //        response = null;

    // Just in case
    if (broadcaster != null) {
      broadcaster.removeAtmosphereResource(this);
    }
    event.destroy();
  }
  public void cancel() throws IOException {

    if (!isCancelled.getAndSet(true)) {
      logger.trace("Cancelling {}", uuid);
      action.type(Action.TYPE.RESUME);
      asyncSupport.action(this);
      // We must close the underlying WebSocket as well.
      if (AtmosphereResponse.class.isAssignableFrom(response.getClass())) {
        AtmosphereResponse.class.cast(response).close();
        AtmosphereResponse.class.cast(response).destroy();
      }

      if (AtmosphereRequest.class.isAssignableFrom(req.getClass())) {
        AtmosphereRequest.class.cast(req).destroy();
      }

      if (broadcaster != null) {
        broadcaster.removeAtmosphereResource(this);
      }
      event.destroy();
    }
  }
 @Override
 public void close() throws IOException {
   cancel();
   event.setCloseByApplication(true);
   notifyListeners();
 }
  @Override
  public AtmosphereResource suspend(long timeout) {

    if (event.isSuspended() || disableSuspend) return this;

    if (config.isSupportSession()
        && req.getSession(false) != null
        && req.getSession().getMaxInactiveInterval() != -1
        && req.getSession().getMaxInactiveInterval() * 1000 < timeout) {
      throw new IllegalStateException(
          "Cannot suspend a "
              + "response longer than the session timeout. Increase the value of session-timeout in web.xml");
    }

    if (transport().equals(TRANSPORT.JSONP) || transport().equals(TRANSPORT.LONG_POLLING)) {
      resumeOnBroadcast.set(true);
    }

    onPreSuspend(event);

    // Recheck based on preSuspend
    if (event.isSuspended() || disableSuspend) return this;

    if (!event.isResumedOnTimeout()) {

      Enumeration<String> connection = req.getHeaders("Connection");
      if (connection == null) {
        connection = req.getHeaders("connection");
      }

      if (connection != null && connection.hasMoreElements()) {
        String[] e = connection.nextElement().toString().split(",");
        for (String upgrade : e) {
          if (upgrade.trim().equalsIgnoreCase(WEBSOCKET_UPGRADE)) {
            if (!asyncSupport.supportWebSocket()) {
              response.addHeader(X_ATMOSPHERE_ERROR, "Websocket protocol not supported");
            } else {
              req.setAttribute(FrameworkConfig.TRANSPORT_IN_USE, HeaderConfig.WEBSOCKET_TRANSPORT);
            }
          }
        }
      }

      if (req.getHeader(X_ATMOSPHERE_TRANSPORT) == null) {
        req.setAttribute(FrameworkConfig.TRANSPORT_IN_USE, HeaderConfig.LONG_POLLING_TRANSPORT);
      }

      req.setAttribute(PRE_SUSPEND, "true");
      action.type(Action.TYPE.SUSPEND);
      action.timeout(timeout);

      // TODO: We can possibly optimize that call by avoiding creating a Broadcaster if we are sure
      // the Broadcaster
      // is unique.
      boolean isJersey = req.getAttribute(FrameworkConfig.CONTAINER_RESPONSE) != null;

      boolean skipCreation = false;
      if (req.getAttribute(SKIP_BROADCASTER_CREATION) != null) {
        skipCreation = true;
      }

      // Null means SCOPE=REQUEST set by a Meteor
      if (!skipCreation
          && (broadcaster == null || broadcaster.getScope() == Broadcaster.SCOPE.REQUEST)
          && !isJersey) {
        String id = broadcaster != null ? broadcaster.getID() : getClass().getName();
        Class<? extends Broadcaster> clazz =
            broadcaster != null ? broadcaster.getClass() : DefaultBroadcaster.class;

        broadcaster = config.getBroadcasterFactory().lookup(clazz, id, false);
        if (broadcaster == null || broadcaster.getAtmosphereResources().size() > 0) {
          broadcaster =
              config.getBroadcasterFactory().lookup(clazz, id + "/" + UUID.randomUUID(), true);
        }
      }

      broadcaster.addAtmosphereResource(this);
      if (req.getAttribute(DefaultBroadcaster.CACHED) != null
          && transport() != null
          && (transport().equals(TRANSPORT.LONG_POLLING) || transport().equals(TRANSPORT.JSONP))) {
        action.type(Action.TYPE.CONTINUE);
        // Do nothing because we have found cached message which was written already, and the
        // handler resumed.
        logger.debug("Cached message found, not suspending {}", uuid());
        return this;
      }
      req.removeAttribute(PRE_SUSPEND);
      notifyListeners();
    }
    return this;
  }
 @Override
 public boolean isSuspended() {
   return event.isSuspended();
 }