Получение ключа задания из имени класса задания в Quartz

Я хочу удалить задание, для которого мне нужен ключ задания. Я знаю только название рабочего класса. Пожалуйста, предложите, как получить то же самое, используя имя класса работы.


person Bhavya Sharma    schedule 03.09.2018    source источник


Ответы (2)


Вы можете найти эту информацию, если выполните итерацию по всем группам заданий ваших экземпляров планировщика. Оттуда вы получаете jobKey. С помощью jobKey вы можете запросить jobDetail, который содержит информацию о классе. Если он совпадает, просто верните ключ.

public JobKey getJobKeyByJobClass (Scheduler scheduler, String className){  
    for (final String group : scheduler.getJobGroupNames()) {
        for (final JobKey jobKey : scheduler.getJobKeys(org.quartz.impl.matchers.GroupMatcher.groupEquals(group))) {
            if(className.equals(scheduler.getJobDetail(jobKey).getJobClass().getName())){
                return jobKey;
            }                               
        }
    }
    return null;
}
person Andreas Hauschild    schedule 03.09.2018
comment
Я знаю название рабочей группы. Но проблема в том, что я хочу избежать накладных расходов на повторение заданий, поскольку количество заданий очень велико. - person Bhavya Sharma; 03.09.2018
comment
Почему вы хотите избежать повторения? У вас есть миллионы заданий или вам нужно выполнять этот поиск 1000 раз в секунду? Думаю, в вашем случае это вообще не проблема. Если вы не уверены, просто измените время выполнения;) - person Andreas Hauschild; 03.09.2018
comment
В моем приложении может быть любое количество заданий. Итак, я не могу повторить. Однако моя работа уже выполняется в моем приложении. Мне просто нужно остановить его вручную в какой-то момент, и все, что у меня есть, это имя класса задания. - person Bhavya Sharma; 03.09.2018
comment
Насколько я знаю, вы не можете просто убить запущенное задание, потому что задание выполняется в потоке из пула потоков планировщика. Если ваше задание не реализует какую-либо собственную логику уничтожения, оно будет выполняться до тех пор, пока выполнение не определит. - person Andreas Hauschild; 03.09.2018

Вы можете получить JobKey несколькими способами. Давайте представим, что ваша Job реализация относится к MyJob классу.

  1. От JobExecutionContext. Если ваша работа выполняется, вы можете

    Scheduler scheduler = schedulerFactory.getScheduler(); 
    JobKey jobKey = null;
    for (JobExecutionContext jobCtx : scheduler.getCurrentlyExecutingJobs()) {
        JobDetail jobDetail = jobCtx.getJobDetail();
        if (MyJob.class.equals(jobDetail.getJobClass())) {
            jobKey = jobDetail.getKey();
            break;
        }
    } 
    

    то же самое с потоками

    Scheduler scheduler = schedulerFactory.getScheduler(); 
    Optional<JobDetail> job = scheduler.getCurrentlyExecutingJobs()
                  .stream()
                  .map(JobExecutionContext::getJobDetail)
                  .filter(jobDetail -> MyJob.class.equals(jobDetail.getJobClass()))
                  .findFirst();
    JobKey jobKey = job.isPresent() ? job.get().getKey() : null;
    
  2. По названию группы. Обычно, когда вы отправляете новое задание на выполнение, вы указываете имена групп и заданий. Если вы этого не делаете, начните, это облегчит задачу :)

    Scheduler scheduler = schedulerFactory.getScheduler();
    JobKey jobKey = null;
    for (JobKey jk : scheduler.getJobKeys(GroupMatcher.jobGroupEquals("myGroup"))) {
        if (MyJob.class.equals(scheduler.getJobDetail(jk).getJobClass())) {
            jobKey = jk;
            break; 
        }
    }
    

    то же самое с потоками

    Scheduler scheduler = schedulerFactory.getScheduler(); 
    Optional<JobDetail> job = scheduler.getJobKeys(GroupMatcher.jobGroupEquals("myGroup"))
                  .stream()
                  .map(jk -> scheduler.getJobDetail(jk))
                  .filter(jobDetail -> MyJob.class.equals(jobDetail.getJobClass()))
                  .findFirst();
    JobKey jobKey = job.isPresent() ? job.get().getKey() : null;
    

Надеюсь, поможет!

person Sergey Prokofiev    schedule 03.09.2018
comment
Спасибо за ответ. Но есть ли способ избежать итерации. Моя работа уже выполняется в моем приложении, и я пытаюсь найти способ остановить ее вручную в какой-то момент времени. - person Bhavya Sharma; 03.09.2018
comment
@BhavyaSharma, это просто, просто создайте группу с одним заданием, которое вы хотите завершить. Все остальное то же самое, вы запрашиваете scheduler для JobKeys своей группой, и будет только целевая работа. :) Вы хотите исключить Job из его класса реализации? - person Sergey Prokofiev; 03.09.2018
comment
Да, я тоже думал сделать это, создав единую группу. Да, я хочу исключить Job из его класса реализации. - person Bhavya Sharma; 03.09.2018
comment
@BhavyaSharma, тогда у вас, вероятно, есть доступ к JobExecutionContext. Получение ключа в данном случае очевидно jobExecutionContext.getJobDetail().getKey(). - person Sergey Prokofiev; 03.09.2018
comment
Незначительное изменение. Я хочу создать API, который будет обращаться к моему классу реализации с помощью GUICE. Я думал сохранить значение ключа в некоторой переменной в классе реализации, а затем использовать его в остальной конечной точке, чтобы поиграть с заданием. - person Bhavya Sharma; 04.09.2018