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