액터모델에는 타이머를 탑재해 반복 스케쥴 이벤트를 실행할수 있습니다.
함수를 즉각 실행 시키는것이 아닌, 자기자신에게 메시지를 추가해 액터가 가진 동일한 메일함을 이용하기때문에 동시 중복실행이 일어나지 않는 특징을 가지고 있습니다.
코드생성 프롬프트
10초에 한번씩 HelloCount를 0으로 초기화하는 이벤트를 생성하고 싶습니다. 타이머 컨셉을 적용해 모델을 개선
변경되는 코드 범위
object ResetHelloCount : HelloStateActorCommand() /** HelloStateActor 클래스 */ class HelloStateActor private constructor( private val context: ActorContext<HelloStateActorCommand>, private val timers: TimerScheduler<HelloStateActorCommand>, private var state: State ) : AbstractBehavior<HelloStateActorCommand>(context) { companion object { fun create(initialState: State): Behavior<HelloStateActorCommand> { return Behaviors.withTimers { timers -> Behaviors.setup { context -> HelloStateActor(context, timers, initialState) } } } } init { timers.startTimerAtFixedRate(ResetHelloCount, Duration.ofSeconds(10)) } private fun onResetHelloCount(command: ResetHelloCount): Behavior<HelloStateActorCommand> { helloCount = 0 return this }
TimerScheduler<HelloStateActorCommand>는 Akka Typed에서 제공하는 타이머 기능을 사용하기 위한 인터페이스입니다. 이 인터페이스를 사용하면 주기적으로 또는 일정 시간 후에 특정 메시지를 액터에게 전송할 수 있습니다. 이를 통해 시간 기반 이벤트를 처리할 수 있습니다.
주요 메서드:
- startTimerAtFixedRate: 주기적으로 메시지를 전송합니다.
- startSingleTimer: 한 번만 메시지를 전송합니다.
- cancel: 특정 타이머를 취소합니다.
추가되는 테스트 코드
@Test fun testResetHelloCount() { val probe = testKit.createTestProbe<Any>() val helloStateActor = testKit.spawn(HelloStateActor.create(State.HAPPY)) // Send Hello messages helloStateActor.tell(Hello("Hello", probe.ref())) helloStateActor.tell(Hello("Hello", probe.ref())) probe.expectMessage(HelloResponse("Kotlin")) probe.expectMessage(HelloResponse("Kotlin")) // Verify the hello count helloStateActor.tell(GetHelloCount(probe.ref())) probe.expectMessage(HelloCountResponse(2)) // Wait for the timer to reset the count Thread.sleep(Duration.ofSeconds(11).toMillis()) // Verify the hello count is reset helloStateActor.tell(GetHelloCount(probe.ref())) probe.expectMessage(HelloCountResponse(0)) }
- 10초 뒤에 HelloCount 가 초기화되는지 검증합니다.
개선되는 컨셉
10초 뒤에 작동하는 기능을 검증하기위해 10초를 기달리는 것이아닌~ 액터 테스트 시스템에 발생하는 시간을 가상으로 진행시킬수 있습니다.
이 테스트 기능을 도입함에 따라~ 시간이 흘러 발생하는 다양한 시나리오 테스트 수행이 가능해지며 유닛테스트 검증 시간을 단축화할수 있습니다.
TestKit에 ManualTime 주입
import akka.actor.testkit.typed.javadsl.ActorTestKit import akka.actor.testkit.typed.javadsl.ManualTime import com.typesafe.config.ConfigFactory import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test import java.time.Duration class HelloStateActorTest { companion object { private lateinit var testKit: ActorTestKit private lateinit var manualTime: ManualTime @BeforeAll @JvmStatic fun setup() { val config = ManualTime.config().withFallback(ConfigFactory.defaultApplication()) testKit = ActorTestKit.create(config) manualTime = ManualTime.get(testKit.system()) } ....
timePasses를 통해 시간을 흘러가게하기
// Advance the time by 5 seconds manualTime.timePasses(Duration.ofSeconds(5)) helloStateActor.tell(GetHelloCount(probe.ref())) probe.expectMessage(HelloCountResponse(2)) // Advance the time by 6 seconds manualTime.timePasses(Duration.ofSeconds(6)) // Verify the hello count is reset helloStateActor.tell(GetHelloCount(probe.ref())) probe.expectMessage(HelloCountResponse(0))
- TimerScheduler 와 호환되어~ 시간이 흘러가면 해당 이벤트가 임의 발생합니다.
- 10초에 Reset을 하기때문에 6초~ 5초 를 각각 흘러가게해 수신카운트를 검증할수 있습니다.
테스트결과
액터내에 메시지함에서 시간이 흘러간것을 검증 할때 유용하게 이용할수 있습니다.
20:14:22.717 [HelloStateActorTest-akka.actor.default-dispatcher-5] INFO actor.hellostate.HelloStateActor - onHello-Kotlin 20:14:22.717 [HelloStateActorTest-akka.actor.default-dispatcher-5] INFO actor.hellostate.HelloStateActor - onHello-Kotlin 20:14:22.719 [HelloStateActorTest-akka.actor.default-dispatcher-2] INFO actor.hellostate.HelloStateActor - onGetHelloCount-helloCount: 2 20:14:22.832 [HelloStateActorTest-akka.actor.default-dispatcher-7] INFO actor.hellostate.HelloStateActor - onGetHelloCount-helloCount: 2 20:14:22.934 [HelloStateActorTest-akka.actor.default-dispatcher-7] INFO actor.hellostate.HelloStateActor - Resetting hello count 20:14:22.936 [HelloStateActorTest-akka.actor.default-dispatcher-7] INFO actor.hellostate.HelloStateActor - onGetHelloCount-helloCount: 0 20:14:22.958 [HelloStateActorTest-akka.actor.default-dispatcher-7] INFO akka.actor.CoordinatedShutdown - Running CoordinatedShutdown with reason [ActorSystemTerminateReason] > Task :test BUILD SUCCESSFUL in 3s
next : 불규칙적으로 발생하는 이벤트를 배치처리가 아닌 준실시간(Near RealTime) 으로 고성능으로 Bulk처리하는방법