Henry,
A few problems with this code:

   - Postdecrement of a volatile is not atomic.
   - Calls to "foreign" code in a synchronized block risks deadlock.
   - As you suspected, there is no guarantee that afterHandle will be called
   once for every call to beforeHandle.

Here's an untested, uncompiled version that addresses these problems:

import org.restlet.*;
import java.util.concurrent.Semaphore;

public class ThrottlingFilter extends Filter {

    private final Semaphore permits;

    public ThrottlingFilter(int maxRunningRequests) {
        this.permits = new Semaphore(maxRunningRequests);
    }

    @Override protected int doHandle(Request request, Response response) {
        if (!permits.tryAcquire()) {
            response.setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
            return Filter.STOP;
        }
        try {
            return super.doHandle(request, response);
        } finally {
            permits.release();
        }
    }
}

--tim


On Thu, Feb 5, 2009 at 5:10 AM, <[email protected]> wrote:

> > Basically, you need to create an org.restlet.Filter subclass
> >that will contains some throttling configuration properties.
>
> Here's a first quick sketch (only limiting the amount of running requests):
> <http://pastebin.com/m12342784
>
> It throws 503 status codes when too many requests are running at the same
> time.
>
> This only works, when after each and every request the filter's afterHandle
> is called. Is there any situation, where beforeHandle of a request is
> issued, but the afterHandle is skipped (except for the case where
> beforeHandle does not return CONTINUE, obviously)?
>

------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=1108535

Reply via email to