HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavaMinor

Filter request code handler

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
codehandlerrequestfilter

Problem

I use the following code which works OK, the code is filtering requests and in case there are too many requests it sends some logs/errors
since I'm very new to Java my question if there is a better way to write it especially the while statement ...

public final class filterBu implements Filter {

        private static AtomicInteger reqcnt;
        private static final String MAX_CUNCCURENT = "maxConcurrent";
        private static final Logger logger = LoggerFactory.getLogger(ContentValidationFilter.class);
        private static final String EXCEED_MAX_REQUESTS_MSG = "maximum reaced";
        private static int maxCunnccurent;
        private static final int TOO_MANY_REQUESTS = 429;

        @Override
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            while (true) {
                int value = reqcnt.get();
                if (value >= maxCunnccurent) {
                    ((HttpServletResponse) resp).sendError(TOO_MANY_REQUESTS, EXCEED_MAX_REQUESTS_MSG);
                    return;
                }
                if (reqcnt.compareAndSet(value, value + 1)) {
                    break;
                }
            }
            try {
                chain.doFilter(req, resp);
            } finally {
                reqcnt.decrementAndGet();
            }

        }

        @Override
        public void init(FilterConfig config) throws ServletException, NumberFormatException {
            maxCunnccurent = Integer.parseInt(config.getInitParameter(MAX_CUNCCURENT));
            if (maxCunnccurent < 1) {
                logger.error("excced limit"); 
            }
            reqcnt = new AtomicInteger(0);
        }

    }

Solution

Replace the AtomicInteger with a Semaphore holding maxCunnccurent (maxConcurrent, right?) permits. So :

reqcnt = new Semaphore(maxCunnccurent);


Now, each time you get a filter request, you try to get a permit. If you do get a permit, you go ahead and filter, making sure that afterwards you release the permit again. If you don't get a permit, you send your error response :

boolean acquired = reqcnt.tryAcquire();
if (!acquired) {
    ((HttpServletResponse) resp).sendError(TOO_MANY_REQUESTS, EXCEED_MAX_REQUESTS_MSG);
    return;
}
try {
    chain.doFilter(req, resp);
} finally {
    reqcnt.release();
}

Code Snippets

reqcnt = new Semaphore(maxCunnccurent);
boolean acquired = reqcnt.tryAcquire();
if (!acquired) {
    ((HttpServletResponse) resp).sendError(TOO_MANY_REQUESTS, EXCEED_MAX_REQUESTS_MSG);
    return;
}
try {
    chain.doFilter(req, resp);
} finally {
    reqcnt.release();
}

Context

StackExchange Code Review Q#146995, answer score: 4

Revisions (0)

No revisions yet.