Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как "убить" или остановить сервлет вручную? 
:(
    Опции темы
olegrolik
Дата 30.11.2007, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Есть веб приложение, есть два сервлета, которые работают. Первый  что-то выполняет (отправляет, принимает и т.д.). Второй нужен для того, чтобы при его запуске убить первый (или хотя бы остановить - если остановка возможна конечно). 
Как это можно реализовать?

Есть кое-какие мысли и соображения:
Например второй сервлет ищет инстанс первого и убивает его.

Забегая вперёд, хочу спросить, можно ли таким же образом осуществить запуск первого сервлета? Т.е. в зависимости от параметра запускать/останавливать первый ?

Спасибо.
PM MAIL   Вверх
Maksym
Дата 30.11.2007, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



Цитата(olegrolik @  30.11.2007,  15:25 Найти цитируемый пост)
Т.е. в зависимости от параметра запускать/останавливать первый ?

Что ты понимаешь под запускать/останавливать? enable/disable.. что то другое?
И зачем "убивать сервлет"?
PM MAIL   Вверх
olegrolik
Дата 30.11.2007, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Maksym, понимаю создать инстанс/убить инстанс. Для начала так.
Убивать сервлет, для того, чтобы он ничего не делал  smile такая задача  smile  Конечно можно не убивать, а(повторяюсь) хотя бы остановить - не знаю возможно ли это.


-----------------------------------------------------------

Хм.... а вообще я тут ступил конкретно.... 
Можно ведь сделать что-то вроде такого:
 
Код

public void doGet(HttpServletRequest req, HttpServletResponse res) {
       String actionStr = request.getParameter("action");
       if(actionStr.equals("shutdown") this.destroy();

}

PM MAIL   Вверх
Souljah
Дата 30.11.2007, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 148
Регистрация: 24.12.2004

Репутация: 3
Всего: 7



Опиши задачу поточнее.
Что значит "ничего не делал"? Чтобы перестал отзываться на url-mapping к нему?

Менеджментом инстансов сервлетов заведует контейнер, убить сервлет без правки контейнерного кода не получится никак
PM MAIL   Вверх
Maksym
Дата 30.11.2007, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



Цитата(olegrolik @  30.11.2007,  16:24 Найти цитируемый пост)
Хм.... а вообще я тут ступил конкретно.... 
Можно ведь сделать что-то вроде такого:

Ты пробовал после этого отправить запрос на сервлет..?
Я не тестил, но вроде как этот метод должн дергаться контейнером и открыт в API, чтобы в нем ресурсы освобождать, контейнер может протупить твой вызов и не заблокировать следующее обращение к service... 

Это сообщение отредактировал(а) Maksym - 30.11.2007, 17:59
PM MAIL   Вверх
COVD
Дата 30.11.2007, 19:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 4
Всего: 43



Речь очевидно о том, что надо остановить поток, обслуживающий запрос клиента. Клиентов в общем случае много и потоков столько же (а сервлет один, про него вообще можно забыть, это всего лишь описание последовательности действий, "виртуальная функция" smile ).  

Клиент послал запрос. На сервере создался новый поток (или свободный из пула взят) и стал его выполнять. Клиент устал ждать и нажимает кнопку "Отменить". Сервер получает новый запрос "отменить" (очевидно, обрабатывается другим сервлетом). Опять создается новый поток, чтобы выполнить эту команду, т.е. остановить первый поток. Чтобы остановить выполнение первого потока надо предусмотреть в его шагах условия остановки, т.е. контрольную точку, флаг, которую он периодически проверяет, не слишком ли долго он копается с обработкой. Если да, то поток прекращает выполнение и закрывает соединение или шлет код ошибки. А второй поток, отменяющий, должен иметь доступ к этому флагу. Если бы клиент предполагался всегда один, то этот флаг можно было бы сделать статическим. Но если клиентов одновременно может быть много, то этот флаг должен быть в сессии клиента, чтобы клиент не отменил чужой запрос. 

Это сообщение отредактировал(а) COVD - 30.11.2007, 19:58
PM MAIL   Вверх
olegrolik
Дата 2.12.2007, 23:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Цитата(COVD @ 30.11.2007,  19:42)
Речь очевидно о том, что надо остановить поток, обслуживающий запрос клиента. Клиентов в общем случае много и потоков столько же (а сервлет один, про него вообще можно забыть, это всего лишь описание последовательности действий, "виртуальная функция" smile ).  

Клиент послал запрос. На сервере создался новый поток (или свободный из пула взят) и стал его выполнять. Клиент устал ждать и нажимает кнопку "Отменить". Сервер получает новый запрос "отменить" (очевидно, обрабатывается другим сервлетом). Опять создается новый поток, чтобы выполнить эту команду, т.е. остановить первый поток. Чтобы остановить выполнение первого потока надо предусмотреть в его шагах условия остановки, т.е. контрольную точку, флаг, которую он периодически проверяет, не слишком ли долго он копается с обработкой. Если да, то поток прекращает выполнение и закрывает соединение или шлет код ошибки. А второй поток, отменяющий, должен иметь доступ к этому флагу. Если бы клиент предполагался всегда один, то этот флаг можно было бы сделать статическим. Но если клиентов одновременно может быть много, то этот флаг должен быть в сессии клиента, чтобы клиент не отменил чужой запрос.

Да, речь о том, чтобы остановить поток. И поток будет один, т.к. мой сервлет-класс реализует SingleThreadModel интерфейс (правда он deprecated, но речь не об этом).

Souljah, если ты имеешь ввиду: не получится убрать <servlet> из web.xml, то я с этим согласен. Требуется просто остановить. Я точно не могу сформулировать свою задачу.

Просто скажу то, что к сервлету постоянно кто-то обращается и передаёт какую-то информацию. Я хочу с помощью запроса типа http://server:8080/MyServlet?action=shutdown остановить его. Что в данном случае остановить - не знаю. Возможно запустить его метод destroy, возможно ещё есть какие-то варианты?

Опять повторюсь : Забегая вперёд, хочу спросить, можно ли таким же образом осуществить запуск первого сервлета?

Спасибо за помощь.

Это сообщение отредактировал(а) olegrolik - 2.12.2007, 23:44
PM MAIL   Вверх
olegrolik
Дата 3.12.2007, 11:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Maksym, попробовал вариант с this.destroy(). Метод вроде бы выполняется, но сервлет не убивается, т.е. потом запросы к нему приходят. Ты был прав.
Вопрос остаётся открытым.
PM MAIL   Вверх
Maksym
Дата 3.12.2007, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



1. Обрамить весь код в service() сервлета if'ом по какому-нибудь флагу из статики. Сделать синхронизированный метод по переключению этого флага (action=shutdown будет дергать это метод). При вызове сервлета клиентом -- service(), конечно, отработает но if его не пустит, а на else можно повесить, например, редирект на какую-нибудь страницу "сервис отключен, обратитесь к администрации".

2. Написать фильтр, который будет перехватывать обращения к сервлетам и проверять включена ли эта функциональность (вызванный сервлет) в данный момент. Если нет -- делать редирект на всю ту же "сервис отключен, обратитесь к администрации".

Оба подхода позволяют включить функциональность обратно (а вдруг понадобится..) без перезапуска контейнера.
Второй подход намного гибче и идеологически вернее -- рекомендую его.
Сама же идея принудительной выгрузки сервлета "изнутри" не кажется мне правильной в рамках лайф цикла веб-приложения; разработчики контейнера и спецификации тоже, думаю, не случайно не оставили такой возможности.


PM MAIL   Вверх
olegrolik
Дата 3.12.2007, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Maksym, совсем не понял что ты хотел сказать. Синхронизация мне не нужна, т.к. инстанс будет всегда один.
Код



public boolean WORKING = true;


public void service(HttpServletRequest req, HttpServletResponse res) {
        String actionStr = req.getParameter("act");
                if(actionStr.equals("shutdown")) WORKING = false;
    }



Цитата
При вызове сервлета клиентом -- service(), конечно, отработает но if его не пустит, а на else можно повесить, например, редирект

Это о чём вообще?
Цитата

2. Написать фильтр, который будет перехватывать обращения к сервлетам и проверять включена ли эта функциональность (вызванный сервлет) в данный момент.
 А фильтр этот тоже в методе service() ? Что он из себя представляет? Метод ?

Это сообщение отредактировал(а) olegrolik - 3.12.2007, 13:27
PM MAIL   Вверх
Maksym
Дата 3.12.2007, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



Цитата(olegrolik @  3.12.2007,  12:23 Найти цитируемый пост)
Это о чём вообще?

Может быть я очень сложно  написал очень простую мысль о том, что запретить выполнение кода в метода можно с помощью конструкции if.. сори  smile 

Фильтры

Тот пример, который ты привел -- не очень верный. Сейчас убегаю, напишу про него позже.



PM MAIL   Вверх
olegrolik
Дата 3.12.2007, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Maksym, спасибо. С нетерпением жду твою версию.
Я тут сделал небольшой "трюк". Смысл моего приложения в приёме файла от клиента.
Я создал public class Global, который содержит в себе перменную boolean manage.

Код


public class Global {
    public static boolean manage = true;
}



В сервлете рассмотрел следующие условия (метод doGet, к примеру):
Код

if(Global.manage==true && req.getParameter("act").equals("shutdown")) { 
                Global.manage=false;
                System.out.println("Система остановлена.");
                
            }
if(Global.manage==false && req.getParameter("act").equals("on")) { 
            Global.manage=true;
            System.out.println("Система запущена.");
            // здесь мы обрабатываем файл, короче тут бизнес-логика.
        }
// Здесь код для оповещения клиента. Случай, когда мы не разрешаем ему работу
if(Global.manage==false && !req.getParameter("act").equals("on")) 
            try {
                res.sendRedirect("http://страница с ошибкой");
                System.out.println("ошибка, редирект на мэйл.ру.");
                System.out.println(Global.manage);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


Как вам такой вариант? Конечно не "стильно", зато полностью отвечает тому, что я хотел сделать. Получается, что тему неправильно назвал. Хотя, посмотрим что предложит Maksym.
PM MAIL   Вверх
Maksym
Дата 3.12.2007, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


.
***


Профиль
Группа: Участник Клуба
Сообщений: 1456
Регистрация: 19.8.2005
Где: Odessa, Black Sea

Репутация: 24
Всего: 62



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

Посмотрел ли ты про фильтры? Это инструмент специально предназначенный для осуществления проверок такого типа, как в последнем сервлете.
PM MAIL   Вверх
olegrolik
Дата 3.12.2007, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Maksym, у меня поток будет один, т.к. сервлет реализует SingleThreadModel интерфейс.
Фильтры посмотрел, но видимо здесь можно обойтись и без них. 
P.S. Я собираюсь реализовывать это дело в Spring MVC. Эти условия (if'ы) будут прописаны в контроллере. 


хмм.... если Spring, то прийдётся сделать синхронизацию доступа. Не хочется использовать просто устаревший интерфейс SingleThreadModel. К тому же под вопросом возможность его использования. 
Как бы то ни было, Maksym, спасибо. Лови плюсик!  smile 


Также хочу добавить, что клиент может сам остановить сервлет. А это недопустимо. В принципе можно в качестве параметра взять что-то вроде: "45345fdsfisdof3i-3ffsdf"  smile 
Но это некрасиво. 

Кто ещё что предложит?

Это сообщение отредактировал(а) olegrolik - 3.12.2007, 18:39
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0887 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.