2008-12-21 11 views
6

Hemos licenciado un producto comercial (producto no importante en este contexto), que está limitado por el número de usuarios simultáneos. Los usuarios acceden a este producto pasando por un controlador de primavera.Limite el acceso a un controlador Spring MVC - N sesiones a la vez

Tenemos N licencias para este producto, y si N + 1 usuarios acceden a él, reciben un desagradable mensaje de error sobre la necesidad de comprar más licencias. Quiero asegurarme de que los usuarios no vean este mensaje y preferiría que las solicitudes al producto simplemente "hagan cola", en lugar de que los usuarios de N + 1 realmente accedan a él. Por supuesto, preferirían que compre las licencias, por lo que su herramienta no nos permitirá hacerlo de forma nativa.

En lugar de poder controlar la herramienta, me gustaría limitar el número de sesiones simultáneas al controlador para que nunca sean más que N. Todos los demás pueden esperar.

Estamos usando Spring MVC.

¿Alguna idea?

Respuesta

7

Lo que necesita es una ObjectPool. Consulte Apache Commons Pool http://commons.apache.org/pool

Al iniciarse la aplicación, debe crear un grupo de objetos con licencias u objetos de la biblioteca comercial (no estoy seguro de qué tipo de interfaz pública tienen).

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) 

Y cuando necesite el objeto comercial en su código.

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 
    } 
} 

Si esto no es lo que desea, entonces deberá proporcionar más detalles acerca de su biblioteca comercial.

0

Estoy pensando en un SessionListener para incrementar el conteo cuando se crea una sesión y disminuirla cuando la sesión se invalida o se agota y un aspecto para proteger las llamadas a la URL. Pero un diseño que claramente combina ambas ideas me está eludiendo.

3

Spring tiene un org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor que se puede utilizar a través de AOP (o el código subyacente se puede usar de forma independiente). Eso podría ser un enfoque más ligero que usar un grupo de objetos.

Cuestiones relacionadas