Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Задача с таймерами / 25 сообщений из 33, страница 1 из 2
21.11.2014, 12:23
    #38812993
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
Всем привет. Есть заказ, есть исполнитель заказа. Когда заказ создается, запускается таймер, который в течении 5 минут ищет исполнителя. Если в течении этого времени исполнитель не найден, заказ отменяется. Заказов одновременно может быть много и получается, что под каждый из этих заказов должен запускаться отдельный таймер. Я так понимаю каждый такой таймер должен создаваться в отдельном потоке... В общем, как решаются подобные задачи? Может быть для этих целей есть хорошая библиотека, поделитесь опытом, пожалуйста. Спасибо
...
Рейтинг: 0 / 0
21.11.2014, 12:31
    #38813020
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
Нет смысла создавать каждый таймер в своём потоке. Так как "убить задачу" процесс, быстрый, то одного потока хватит с головой.
На худой конец, сконфигуряете на пул из 2х потоков
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

Запускается процесс, для ней сабмитится runnable в ScheduledExecutorService. При запуске runable проверяет, если его процесс ещё активет, то убивает его.
...
Рейтинг: 0 / 0
21.11.2014, 13:36
    #38813143
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
BlazkowiczНет смысла создавать каждый таймер в своём потоке. Так как "убить задачу" процесс, быстрый, то одного потока хватит с головой.
На худой конец, сконфигуряете на пул из 2х потоков
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

Запускается процесс, для ней сабмитится runnable в ScheduledExecutorService. При запуске runable проверяет, если его процесс ещё активет, то убивает его.
Спасибо, это именно то, что нужно. Но я не могу понять один момент. Заказ я должна убивать в двух случаях: 1) по таймауту (прошло 5 минут никто не откликнулся), 2) когда статус заказа в базе данных поменялся с waiting на in_progress. С пунктом 1 все вроде понятно, а вот со 2 нет. Грубо говоря:
Для первого пункта:
Код: java
1.
2.
3.
4.
5.
6.
 scheduler.schedule(new Runnable() {
            public void run() {
                beeperHandle.cancel(true);
                System.out.println("cancel");
            }
        }, 60 * 60, SECONDS);


А для второго как? Мне ведь нужно сопоставить как-то айдишник заказа с потоком, нужно это для того, чтобы пока крутится таймер лезть в базу, проверять статус и если он in_progress (т.е. его взяли на исполнение) - делать beeperHandle.cancel(true);
Не совсем понимаю как этот момент разрулить
...
Рейтинг: 0 / 0
21.11.2014, 13:47
    #38813167
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
JulT,

Жесть какая. В методе, который меняет статус, делаете проверку и вызываете отмену.
...
Рейтинг: 0 / 0
21.11.2014, 13:53
    #38813180
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
BlazkowiczJulT,

Жесть какая. В методе, который меняет статус, делаете проверку и вызываете отмену.

это понятно, я к тому, что не отвалятся ли при такой отмене другие таймеры связанные с другими заказами? ладно, нужно почитать детально про принцип работы ScheduledExecutorService, я впервые с ним сталкиваюсь
спасибо
...
Рейтинг: 0 / 0
21.11.2014, 14:03
    #38813200
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
Blazkowicz Жесть какая. В методе, который меняет статус, делаете проверку и вызываете отмену.
На сколько я понял девушку, метод который меняет сатус работает в БД.
Оттуда тяжело убить процесс.

Хотя возможно это сам процесс нашедший исполнителя, тогда какие, спрашивается, сложности самому закончится?
...
Рейтинг: 0 / 0
21.11.2014, 14:12
    #38813215
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
Сергей Арсеньев На сколько я понял девушку, метод который меняет сатус работает в БД.

Этого мы знать не можем.

Сергей Арсеньев Оттуда тяжело убить процесс.

Не так уж и тяжело. Вешаем триггер. Кидаем событие. Ловим событие, отменям процесс по id.

Сергей АрсеньевХотя возможно это сам процесс нашедший исполнителя, тогда какие, спрашивается, сложности самому закончится?
Сложностей никаких нет. Странно, конечно, что вопрос начинается про таймеры, а продолжается в стиле "ну и как же мне тогда сделать что-то совершенно другое".
...
Рейтинг: 0 / 0
03.12.2014, 14:54
    #38823732
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
Есть одна непонятная проблема:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
TestTask testTask = new TestTask();
final ScheduledFuture<?> testHandle = scheduler.scheduleAtFixedRate(testTask, 0, 1, SECONDS);

@Component
public class TestTask implements Runnable{
    private static final Logger LOGGER = LoggerFactory.getLogger(TestTask.class);

    @Autowired
    HumanRepository humanRepository;

    @Override
    public void run() {
       System.out.println("run task");
    }


Запускаю, каждую секунду в консоли выводится run task, все отлично. Но! Как только добавляю в метод run строчку:

Код: java
1.
Human hman = humanRepository.findOne(humanId);

(humanId=4)
Код: java
1.
2.
3.
4.
5.
6.
@Override
    public void run() {
       System.out.println("run task");
       Human hman = humanRepository.findOne(humanId);
       System.out.println("after");
    }


after никогда при этом не выводится, т.е. зависает на findOne. Делаю в другом классе вызов findOne, все работает. С чем это может быть связано? Спасибо
...
Рейтинг: 0 / 0
03.12.2014, 14:58
    #38823736
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
JulT, при некотором стечении обстоятельств твой сервер задач может рухнуть. Нужны какие-то
limitations. Лучше всего - очередь задачь ожидающих своей диспетчеризации.
...
Рейтинг: 0 / 0
03.12.2014, 16:22
    #38823858
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
off
очень интересно, как _ищется_ исполнитель 5 минут на гигагерцевом ядре процессора? )
...
Рейтинг: 0 / 0
03.12.2014, 16:26
    #38823863
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
если изменить термин на "заказ висит 5 минут в .....", то можно проходя обычным JOB раз минуту снимать статус протухшего заказа.
...
Рейтинг: 0 / 0
03.12.2014, 16:31
    #38823871
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
JulTafter никогда при этом не выводится, т.е. зависает на findOne.
Та, нет же не зависает. Сколько можно рассказывать, что это кривизна в Excecutor, которые тихо кушают все исключения и даже на консоль их не выводят.
А исключение вылетает, скорее всего, из-за того что в этом потоке репозиторий не работает, так как потом не связан с контейнером. Соответсвенно чего-то в своих ThreadLocal найти не может.
...
Рейтинг: 0 / 0
03.12.2014, 16:32
    #38823872
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
Petro123off
очень интересно, как _ищется_ исполнитель 5 минут на гигагерцевом ядре процессора? )
Да при чём тут гигагерцы. Если там в БД хранимка чего-то долго ищет.
...
Рейтинг: 0 / 0
03.12.2014, 16:42
    #38823892
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
maytonPetro123off
очень интересно, как _ищется_ исполнитель 5 минут на гигагерцевом ядре процессора? )
Да при чём тут гигагерцы. Если там в БД хранимка чего-то долго ищет.
off
расскажи алгоритм поиска
...
Рейтинг: 0 / 0
03.12.2014, 18:00
    #38824002
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
BlazkowiczJulTafter никогда при этом не выводится, т.е. зависает на findOne.
Та, нет же не зависает. Сколько можно рассказывать, что это кривизна в Excecutor, которые тихо кушают все исключения и даже на консоль их не выводят.
А исключение вылетает, скорее всего, из-за того что в этом потоке репозиторий не работает, так как потом не связан с контейнером. Соответсвенно чего-то в своих ThreadLocal найти не может.
Вы абсолютно правы, вылетает exception, еле отловила его. Вся проблема в том, что не инжектится бин. Создала новую тему, а нужно было здесь продолжить. Повторюсь:
Почему testRepository в классе:
Код: java
1.
2.
3.
4.
5.
@Service("autoSearch")
public class AutoSearch implements Runnable{

    @Autowired
    TestRepository testRepository;

всегда = null
В этом же пакете рядом лежит другой класс:
Код: java
1.
2.
3.
4.
5.
@Service("test")
public class B {

    @Autowired
    TestRepository testRepository;


и в нем инъекция проходит успешно.
Если я правильно понимаю, то причина в implements Runnable. Помогите разобраться. Спасибо
...
Рейтинг: 0 / 0
03.12.2014, 18:09
    #38824015
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
причина в том, что спринг контейнер понятия не имеет о вашем потоке
...
Рейтинг: 0 / 0
03.12.2014, 19:54
    #38824103
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
забыл ник,

Да, спасибо, уже разобралась. Я вызываю контекст и явно вызываю getBean. Единственное, мне не нравится, что у меня дваждый вызывается конфигурация, первый раз при запуске приложения, второй раз при явном вызове метода через ctx.getBean .... Этого можно как-то избежать?
...
Рейтинг: 0 / 0
03.12.2014, 21:38
    #38824189
DDiver
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
JulT,

что значит вызывается? два раза инициализируется контекст?
...
Рейтинг: 0 / 0
04.12.2014, 02:34
    #38824351
YamahaR1
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
BlazkowiczJulTafter никогда при этом не выводится, т.е. зависает на findOne.
Та, нет же не зависает. Сколько можно рассказывать, что это кривизна в Excecutor, которые тихо кушают все исключения и даже на консоль их не выводят.


И как тогда бороться с этой проблемой? Как отлавливать исключения?
...
Рейтинг: 0 / 0
04.12.2014, 04:36
    #38824389
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
try{

} catch() {

} finally
...
Рейтинг: 0 / 0
04.12.2014, 08:24
    #38824439
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
DDiverJulT,

что значит вызывается? два раза инициализируется контекст?
да
...
Рейтинг: 0 / 0
04.12.2014, 08:58
    #38824455
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
не могу понять что происходит
добавляю ctx в:
Код: java
1.
2.
3.
@Service("autoSearch")
public class AutoSearch implements Runnable{
private ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/application-context.xml");


запускаю проект, в консоль валятся логи инициализации контекста, причем постоянно, в итоге все заканчивается исключением: to many connection. Как быть?
...
Рейтинг: 0 / 0
04.12.2014, 09:15
    #38824476
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
JulT,
так не годится, контекст следует инициализировать только 1 раз. Например, при старте приложения. Или используя синглетон. Тут много разных способов, например такой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public class AppContextFactory {
	private static class SingletonHolder { 
		private static ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/application-context.xml");
	}
	public static ApplicationContext getInstance() {
		return SingletonHolder.ctx;
	}
}


Дальше обращаемся к нему только через статический метод AppContextFactory.getInstance()
...
Рейтинг: 0 / 0
04.12.2014, 10:23
    #38824552
JulT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
ivanraJulT,
так не годится, контекст следует инициализировать только 1 раз. Например, при старте приложения. Или используя синглетон. Тут много разных способов, например такой:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
public class AppContextFactory {
	private static class SingletonHolder { 
		private static ApplicationContext ctx = new ClassPathXmlApplicationContext("META-INF/application-context.xml");
	}
	public static ApplicationContext getInstance() {
		return SingletonHolder.ctx;
	}
}


Дальше обращаемся к нему только через статический метод AppContextFactory.getInstance()
Спасибо огромное. Сделала так: в application-context.xml добавила строчку:
Код: java
1.
<bean id="applicationContextFactory" class="ru.test.utils.context.AppContextFactory"></bean>


Далее:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
@Service("autoSearch")
public class AutoSearch implements Runnable{
@Autowired
	TestRepository testRepository;

	private TestRepository getTestRepository() {
		if (testRepository==null) {
			ApplicationContext ctx = AppContextFactory.getInstance();
			testRepository = ctx.getBean(TestRepository.class);
		}
		return testRepository;
	}


Все отлично работает, но все же мой контекст вызывается дважды. Первый раз при старте приложения, второй раз при вызове getTestRepository(). Этого можно как-то избежать?
...
Рейтинг: 0 / 0
04.12.2014, 10:40
    #38824574
ivanra
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Задача с таймерами
JulT,
при старте приложения тоже надо вызывать метод AppContextFactory.getInstance(), это надо делать везде в приложении, где требуется получить контекст. На то он и синглетон
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Задача с таймерами / 25 сообщений из 33, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]