본문 바로가기
서버/Kotlin-Spring_Boot

Suspend function 'await' should be called only from a coroutine or another suspend function

by HDobby 2023. 5. 26.

await을 사용 하기 위해선 함수에 suspend가 붙어 있거나 코루틴 내부에서 호출을 진행해야 한다.

하지만 Scheduled로 지정된 함수에 suspend를 붙이게 된다면 아래와 같은 에러 메시지를 보게 된다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'showTimeScheduler' defined in file [Y:\ThreeMovie\threemovieapi\build\classes\kotlin\main\com\threemovie\threemovieapi\domain\showtime\scheduler\ShowTimeScheduler.class]: Encountered invalid @Scheduled method 'chkMovieShowingTime': Only no-arg methods may be annotated with @Scheduled
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:606) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:915) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302) ~[spring-boot-3.0.1.jar:3.0.1]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291) ~[spring-boot-3.0.1.jar:3.0.1]
	at com.threemovie.threemovieapi.ThreemovieapiApplicationKt.main(ThreemovieapiApplication.kt:17) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-3.0.1.jar:3.0.1]
Caused by: java.lang.IllegalStateException: Encountered invalid @Scheduled method 'chkMovieShowingTime': Only no-arg methods may be annotated with @Scheduled
	at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:517) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$postProcessAfterInitialization$1(ScheduledAnnotationBeanPostProcessor.java:379) ~[spring-context-6.0.3.jar:6.0.3]
	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
	at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.lambda$postProcessAfterInitialization$2(ScheduledAnnotationBeanPostProcessor.java:379) ~[spring-context-6.0.3.jar:6.0.3]
	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na]
	at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:378) ~[spring-context-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:435) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1754) ~[spring-beans-6.0.3.jar:6.0.3]
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.0.3.jar:6.0.3]
	... 20 common frames omitted

runBlocking을 코루틴과 await을 묶어 주면 해결된다.

runBlocking {
    for (mbTheater in mbTheaters) {
        CoroutineScope(Dispatchers.IO).async { updateMBShowtimes(mbTheater) }
            .also { showTimeAsync.add(it) }
    }
    for (lcTheater in lcTheaters) {
        CoroutineScope(Dispatchers.IO).async { updateLCShowtimes(lcTheater) }
            .also { showTimeAsync.add(it) }
    }
    for (cgvTheater in cgvTheaters) {
        CoroutineScope(Dispatchers.IO).async { updateCGVShowtimes(cgvTheater) }
            .also { showTimeAsync.add(it) }
    }
    for (showTimeDeferred in showTimeAsync) {
        showTimeList.addAll(showTimeDeferred.await())
    }
}
728x90

댓글