Ограничить доступ к контроллеру Spring MVC - N сессий одновременно - PullRequest
6 голосов
/ 22 декабря 2008

Мы лицензировали коммерческий продукт (продукт не важен в этом контексте), который ограничен числом одновременно работающих пользователей. Пользователи получают доступ к этому продукту через Spring Controller.

У нас есть N лицензий на этот продукт, и если N + 1 пользователи получают к нему доступ, они получают неприятное сообщение об ошибке о необходимости купить больше лицензий. Я хочу убедиться, что пользователи не видят это сообщение, и предпочел бы, чтобы запросы к продукту просто «помещались в очередь», а не имели фактически доступ к нему пользователей N + 1. Конечно, они предпочли бы, чтобы я приобрел лицензии, поэтому их инструмент не позволит нам сделать это изначально.

Вместо того, чтобы иметь возможность управлять инструментом, я бы хотел ограничить количество одновременных сеансов контроллером, чтобы он никогда не превышал N. Все остальные могут ждать.

Мы используем Spring MVC.

Есть идеи?

Ответы [ 3 ]

7 голосов
/ 22 декабря 2008

Что вам нужно, так это ObjectPool. Проверьте Apache Commons Pool http://commons.apache.org/pool

При запуске приложения вы должны создать пул объектов с лицензиями или объектами коммерческой библиотеки (не уверен, какой у них публичный интерфейс).

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) 

А когда вам нужен коммерческий объект в вашем коде.

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

Если это не то, что вам нужно, вам нужно будет предоставить более подробную информацию о вашей коммерческой библиотеке.

3 голосов
/ 16 января 2009

Spring имеет org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor, который может использоваться через AOP (или базовый код может использоваться автономно). Это может быть более легкий подход, чем использование пула объектов.

0 голосов
/ 27 декабря 2008

Я имею в виду SessionListener для увеличения счетчика при создании сеанса и уменьшения его, когда сеанс признан недействительным или по истечении времени ожидания, а также для защиты вызовов URL. Но дизайн, который явно объединяет две идеи, ускользает от меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...