복붙노트

[SPRING] 봄에 EnableScheduling 주석을 사용하여 런타임에 예약 된 작업을 다시 시작하는 방법은 무엇입니까?

SPRING

봄에 EnableScheduling 주석을 사용하여 런타임에 예약 된 작업을 다시 시작하는 방법은 무엇입니까?

Java 8 및 Spring을 사용하여 런타임에서 작업 빈도를 변경하는 방법을 조사했습니다. 이 질문은 매우 유용했지만 내 문제를 완전히 해결하지 못했습니다.

다음에 작업을 수행 할 날짜를 구성 할 수 있습니다. 그러나 지연을 1 년으로 설정하면 새 구성을 고려하기 전에 1 년을 기다려야합니다.

구성 값이 다른 클래스에서 변경되면 예약 된 작업을 중지하는 것이 좋습니다. 다음에 작업을 실행할 때 다시 계산하십시오. 아마도이 작업을 수행하는 더 쉬운 방법이있을 것입니다.

여기까지 내가 가진 코드가 있습니다.

@Configuration
@EnableScheduling
public class RequestSchedulerConfig implements SchedulingConfigurer {

    @Autowired
    SchedulerConfigService schedulerConfigService;

    @Bean
    public RequestScheduler myBean() {
        return new RequestScheduler();
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(100);
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
        taskRegistrar.addTriggerTask(
                new Runnable() {
                    @Override public void run() {
                        myBean().startReplenishmentComputation();
                    }
                },
                new Trigger() {
                    @Override public Date nextExecutionTime(TriggerContext triggerContext) {
                        Duration d = schedulerConfigService.getIntervalFromDB();
                        return DateTime.now().plus(d).toDate();
                    }
                }
        );
    }
}

이것이 내가하고 싶은 일입니다.

@RestController
@RequestMapping("/api/config/scheduler")
public class RequestSchedulerController {

    @Autowired
    ApplicationConfigWrapper applicationConfigWrapper;

    @RequestMapping("/set/")
    @ResponseBody
    public String setRequestSchedulerConfig(@RequestParam(value = "frequency", defaultValue = "") final String frequencyInSeconds){
        changeValueInDb(frequencyInSeconds);
        myJob.restart();
        return "Yeah";
    }

}

해결법

  1. ==============================

    1.여기서 핵심 아이디어는 선물이 생성 될 때 선물을 제어하여 일부 상태 변수에 저장하여 데이터를 예약 할 때 변경 될 때이를 취소 할 수 있도록하는 것입니다.

    여기서 핵심 아이디어는 선물이 생성 될 때 선물을 제어하여 일부 상태 변수에 저장하여 데이터를 예약 할 때 변경 될 때이를 취소 할 수 있도록하는 것입니다.

    작동 코드는 다음과 같습니다.

    applicationContext.xml

    <task:annotation-driven />
    <task:scheduler id="infScheduler" pool-size="10"/>
    

    선물을 담는 싱글 톤 콩

    @Component
    public class SchedulerServiceImpl implements SchedulerService {
    
            private static final Logger logger = LoggerFactory.getLogger(SchedulerServiceImpl.class);
    
            @Autowired
            @Qualifier(value="infScheduler")
            private TaskScheduler taskScheduler;
    
            @Autowired
            private MyService myService;
    
            private ScheduledFuture job1;//for other jobs you can add new private state variables
    
            //Call this on deployment from the ScheduleDataRepository and everytime when schedule data changes.
            @Override
            public synchronized void scheduleJob(int jobNr, long newRate) {//you are free to change/add new scheduling data, but suppose for now you only want to change the rate
                    if (jobNr == 1) {//instead of if/else you could use a map with all job data
                            if (job1 != null) {//job was already scheduled, we have to cancel it
                                    job1.cancel(true);
                            }
                            //reschedule the same method with a new rate
                            job1 = taskScheduler.scheduleAtFixedRate(new ScheduledMethodRunnable(myService, "methodInMyServiceToReschedule"), newRate);
                    }
            }
    }
    
  2. ==============================

    2.간단한 접근 방법 중 하나는 스케줄러를 시도하거나 취소하거나 다시 시작하지 않고 새 작업 만 추가하는 것입니다.

    간단한 접근 방법 중 하나는 스케줄러를 시도하거나 취소하거나 다시 시작하지 않고 새 작업 만 추가하는 것입니다.

    구성이 변경 될 때마다 새 구성으로 새 작업을 추가하십시오.

    그런 다음 작업이 실행될 때마다 먼저 데이터베이스를 쿼리하거나 동시 맵에서 조회 등을 통해 일부 상태를 확인하여 최신 버전인지 확인해야합니다. 그렇다면 계속 진행해야합니다. 그렇지 않으면 즉시 종료해야합니다.

    유일한 단점은 작업 구성을 자주 실행하는 것과 비교하여 작업 구성을 자주 변경하는 경우 예약 된 작업 목록이 메모리에서 계속 증가한다는 것입니다.

  3. ==============================

    3.Set ScheduledTaskRegistrar.getScheduledTasks ()를 사용하여 모든 일정 작업을 가져오고 ScheduledTask :: cancel ()을 호출하는 것은 어떻습니까? 또는 ThreadPoolTaskScheduler :: shutdown () 실행 ThreadPoolTaskScheduler를 다시 작성하고 ScheduledTaskRegistrar에서 다시 설정합니까?

    Set ScheduledTaskRegistrar.getScheduledTasks ()를 사용하여 모든 일정 작업을 가져오고 ScheduledTask :: cancel ()을 호출하는 것은 어떻습니까? 또는 ThreadPoolTaskScheduler :: shutdown () 실행 ThreadPoolTaskScheduler를 다시 작성하고 ScheduledTaskRegistrar에서 다시 설정합니까?

  4. from https://stackoverflow.com/questions/31969251/how-to-restart-scheduled-task-on-runtime-with-enablescheduling-annotation-in-spr by cc-by-sa and MIT license