Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit Access To a Spring MVC Controller -- N sessions at a time

We've licensed a commercial product (product not important in this context), which is limited by the number of concurrent users. Users access this product by going through a Spring Controller.

We have N licenses for this product, and if N+1 users access it, they get a nasty error message about needing to buy more licenses. I want to make sure users don't see this message, and would prefer that requests to the product simply "queue up", rather than having N+1 users actually access it. Of course, they would prefer that I purchase the licenses, so their tool won't let us do this natively.

In lieu of being able to control the tool, I'd like to limit the number of concurrent sessions to the controller to never be more than N. Everyone else can wait.

We're using Spring MVC.

Any ideas?

like image 790
Anthony Avatar asked Dec 21 '08 23:12

Anthony


2 Answers

What you need is a ObjectPool. Check out Apache Commons Pool http://commons.apache.org/pool

At the application startup you should create a Object Pool with licences or objects of commercial library (Not sure what kind of public interface they have).

public class CommercialObjectFactory extends BasePoolableObjectFactory { 
    // for makeObject we'll simply return a new commercial object
    @Override
    public Object makeObject() { 
        return new CommercialObject(); 
    } 
}

GenericObjectPool pool = new GenericObjectPool(new CommercialObjectFactory());

// The size of pool in our case it is N
pool.setMaxActive(N) 
// We want to wait if the pool is exhausted
pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_BLOCK) 

And when you need the commercial object in your code.

CommercialObject obj = null;
try { 
    obj = (CommercialObject)pool.borrowObject();

    // use the commerical object the way you to use it.
    // ....

} finally { 
    // be nice return the borrwed object
    try {
        if(obj != null) {
            pool.returnObject(obj);
        }
    } catch(Exception e) {
        // ignored
    }
} 

If this is not what you want then you will need to provide more detail about your commercial library.

like image 195
TRF Avatar answered Sep 28 '22 02:09

TRF


Spring has a org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor that can be used via AOP (or the underlying code can be used standalone). That might be a lighter weight approach than using a object pool.

like image 26
Ed Thomas Avatar answered Sep 28 '22 02:09

Ed Thomas