2008-12-21 6 views
6

Nous avons concédé sous licence un produit commercial (produit non important dans ce contexte), limité par le nombre d'utilisateurs simultanés. Les utilisateurs accèdent à ce produit en passant par un contrôleur Spring.Limiter l'accès à un contrôleur Spring MVC - N sessions à la fois

Nous avons N licences pour ce produit, et si les utilisateurs N + 1 y accèdent, ils reçoivent un message d'erreur désagréable concernant l'achat de licences supplémentaires. Je veux m'assurer que les utilisateurs ne voient pas ce message, et préféreraient que les demandes au produit se contentent de «faire la queue», plutôt que d'avoir réellement accès à des utilisateurs N + 1. Bien sûr, ils préféreraient que j'achète les licences, donc leur outil ne nous laissera pas le faire nativement. Au lieu de pouvoir contrôler l'outil, je voudrais limiter le nombre de sessions simultanées au contrôleur pour ne jamais être supérieur à N. Tout le monde peut attendre.

Nous utilisons Spring MVC.

Des idées?

Répondre

7

Ce dont vous avez besoin est un ObjectPool. Au démarrage de l'application, vous devez créer un pool d'objets avec des licences ou des objets de la bibliothèque commerciale (Vous ne savez pas quel type d'interface publique ils ont).

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) 

Et quand vous avez besoin de l'objet commercial dans votre 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 
    } 
} 

Si ce n'est pas ce que vous voulez, vous devrez fournir plus de détails sur votre bibliothèque commerciale.

0

Je pense à un SessionListener pour incrémenter le compte lorsqu'une session est créée et le décrémenter lorsque la session est invalidée ou expire et un aspect pour garder les appels à l'URL. Mais un design qui marie clairement les deux idées ensemble me fuit.

3

Spring a un org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor qui peut être utilisé via AOP (ou le code sous-jacent peut être utilisé de manière autonome). Cela pourrait être une approche plus légère que d'utiliser un pool d'objets.

Questions connexes