Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package io.undertow.server.handlers;
  
  
  import java.util.Queue;
 
 import static org.xnio.Bits.longBitMask;

Represents a limit on a number of running requests.

This is basically a counter with a configured set of limits, that is used by RequestLimitingHandler.

When the number of active requests goes over the configured max requests then requests will be suspended and queued.

If the queue is full requests will be rejected with a 513.

The reason why this is abstracted out into a separate class is so that multiple handlers can share the same state. This allows for fine grained control of resources.

Author(s):
Stuart Douglas
See also:
RequestLimitingHandler
 
 public class RequestLimit {
     @SuppressWarnings("unused")
     private volatile long state;
 
     private static final AtomicLongFieldUpdater<RequestLimitstateUpdater = AtomicLongFieldUpdater.newUpdater(RequestLimit.class"state");
 
     private static final long MASK_MAX = longBitMask(32, 63);
     private static final long MASK_CURRENT = longBitMask(0, 30);

    
The handler that will be invoked if the queue is full.
 
     private volatile HttpHandler failureHandler = new ResponseCodeHandler(513);
 
     private final Queue<SuspendedRequestqueue;
 
 
         @Override
         public void exchangeEvent(final HttpServerExchange exchangefinal NextListener nextListener) {
             try {
                 final SuspendedRequest task = .poll();
                 if (task != null) {
                     task.exchange.dispatch(task.next);
                 } else {
                     decrementRequests();
                 }
             } finally {
                 nextListener.proceed();
             }
         }
     };
 
 
     public RequestLimit(int maximumConcurrentRequests) {
         this(maximumConcurrentRequests, -1);
     }

    
Construct a new instance. The maximum number of concurrent requests must be at least one.

Parameters:
maximumConcurrentRequests the maximum concurrent requests
queueSize The maximum number of requests to queue
 
     public RequestLimit(int maximumConcurrentRequestsint queueSize) {
         if (maximumConcurrentRequests < 1) {
             throw new IllegalArgumentException("Maximum concurrent requests must be at least 1");
         }
          = (maximumConcurrentRequests & 0xFFFFFFFFL) << 32;
 
         this. = new LinkedBlockingQueue<SuspendedRequest>(queueSize <= 0 ? . : queueSize);
     }
 
     public void handleRequest(final HttpServerExchange exchangefinal HttpHandler nextthrows Exception {
         long oldValnewVal;
         do {
             oldVal = ;
             final long current = oldVal & ;
             final long max = (oldVal & ) >> 32L;
             if (current >= max) {
                 exchange.dispatch(.new Runnable() {
                     @Override
                     public void run() {
                         if (!.offer(new SuspendedRequest(exchangenext))) {
                             Connectors.executeRootHandler(exchange);
                         }
                     }
                 });
                 return;
            }
            newVal = oldVal + 1;
        } while (!.compareAndSet(thisoldValnewVal));
        next.handleRequest(exchange);
    }

    
Get the maximum concurrent requests.

Returns:
the maximum concurrent requests
    public int getMaximumConcurrentRequests() {
        return (int) ( >> 32L);
    }

    
Set the maximum concurrent requests. The value must be greater than or equal to one.

Parameters:
newMax the maximum concurrent requests
    public int setMaximumConcurrentRequests(int newMax) {
        if (newMax < 1) {
            throw new IllegalArgumentException("Maximum concurrent requests must be at least 1");
        }
        long oldValnewVal;
        int currentoldMax;
        do {
            oldVal = ;
            current = (int) (oldVal & );
            oldMax = (int) ((oldVal & ) >> 32L);
            newVal = current | newMax & 0xFFFFFFFFL << 32L;
        } while (!.compareAndSet(thisoldValnewVal));
        while (current < newMax) {
            // more space opened up!  Process queue entries for a while
            final SuspendedRequest request = .poll();
            if (request != null) {
                // now bump up the counter by one; this *could* put us over the max if it changed in the meantime but that's OK
                newVal = .getAndIncrement(this);
                current = (int) (newVal & );
                request.exchange.dispatch(request.next);
            }
        }
        return oldMax;
    }
    private void decrementRequests() {
        .decrementAndGet(this);
    }
    public HttpHandler getFailureHandler() {
        return ;
    }
    public void setFailureHandler(HttpHandler failureHandler) {
        this. = failureHandler;
    }
    private static final class SuspendedRequest {
        final HttpServerExchange exchange;
        final HttpHandler next;
        private SuspendedRequest(HttpServerExchange exchangeHttpHandler next) {
            this. = exchange;
            this. = next;
        }
    }
New to GrepCode? Check out our FAQ X