From c95749c2db368033a3f55496b44b3fa0c82a5c5d Mon Sep 17 00:00:00 2001 From: Ethan Date: Mon, 24 Jun 2024 18:17:22 +0900 Subject: [PATCH] =?UTF-8?q?6/24=20=EB=B0=B0=ED=8F=AC=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=20(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/prod-pull-request-merge.yml | 2 +- secrets | 2 +- .../backend/itracker/config/AuditConfig.kt | 4 +- .../itracker/crawl/result/CrawlResult.kt | 43 ++++++++++ .../repository/CrawlResultRepository.kt | 16 ++++ .../crawl/service/CrawlResultService.kt | 27 ++++++ .../itracker/schedule/config/AsyncConfig.kt | 9 +- .../schedule/config/SchedulingConfig.kt | 23 ++++++ .../schedule/config/ShedulingConfig.kt | 9 -- .../schedule/controller/ScheduleController.kt | 9 +- .../schedule/service/CrawlSchedulerService.kt | 82 +++---------------- .../service/schedulers/Schedulable.kt | 16 ++++ .../service/schedulers/SchedulerComposite.kt | 16 ++++ .../schedulers/airpods/AirpodsScheduler.kt | 34 ++++++++ .../service/schedulers/ipad/IpadScheduler.kt | 34 ++++++++ .../schedulers/iphone/IphoneScheduler.kt | 34 ++++++++ .../service/schedulers/mac/MacScheduler.kt | 34 ++++++++ .../schedulers/macbook/MacbookScheduler.kt | 34 ++++++++ .../schedulers/watch/AppleWatchScheduler.kt | 34 ++++++++ src/main/resources/application.yml | 3 + 20 files changed, 368 insertions(+), 97 deletions(-) create mode 100644 src/main/kotlin/backend/itracker/crawl/result/CrawlResult.kt create mode 100644 src/main/kotlin/backend/itracker/crawl/result/repository/CrawlResultRepository.kt create mode 100644 src/main/kotlin/backend/itracker/crawl/service/CrawlResultService.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/config/SchedulingConfig.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/Schedulable.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/SchedulerComposite.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/airpods/AirpodsScheduler.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/ipad/IpadScheduler.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/iphone/IphoneScheduler.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/mac/MacScheduler.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/macbook/MacbookScheduler.kt create mode 100644 src/main/kotlin/backend/itracker/schedule/service/schedulers/watch/AppleWatchScheduler.kt diff --git a/.github/workflows/prod-pull-request-merge.yml b/.github/workflows/prod-pull-request-merge.yml index a4c0e82..4f181b8 100644 --- a/.github/workflows/prod-pull-request-merge.yml +++ b/.github/workflows/prod-pull-request-merge.yml @@ -60,6 +60,6 @@ jobs: - name: Docker Compose run: | - ~/backend/deploy.sh + ~/backend/zero-downtime-deploy.sh docker container prune -f sudo docker image prune -af diff --git a/secrets b/secrets index 45b3451..21d867f 160000 --- a/secrets +++ b/secrets @@ -1 +1 @@ -Subproject commit 45b345125499e786a57bbafce3467a03915d48cc +Subproject commit 21d867f8bf9e2176e10cd3f893aa8d2a0328b49b diff --git a/src/main/kotlin/backend/itracker/config/AuditConfig.kt b/src/main/kotlin/backend/itracker/config/AuditConfig.kt index 1c14d47..53bf1f2 100644 --- a/src/main/kotlin/backend/itracker/config/AuditConfig.kt +++ b/src/main/kotlin/backend/itracker/config/AuditConfig.kt @@ -1,9 +1,9 @@ package backend.itracker.config +import org.springframework.context.annotation.Configuration import org.springframework.data.jpa.repository.config.EnableJpaAuditing -import org.springframework.stereotype.Component -@Component +@Configuration @EnableJpaAuditing class AuditConfig diff --git a/src/main/kotlin/backend/itracker/crawl/result/CrawlResult.kt b/src/main/kotlin/backend/itracker/crawl/result/CrawlResult.kt new file mode 100644 index 0000000..e29d604 --- /dev/null +++ b/src/main/kotlin/backend/itracker/crawl/result/CrawlResult.kt @@ -0,0 +1,43 @@ +package backend.itracker.crawl.result + +import backend.itracker.crawl.common.BaseEntity +import backend.itracker.crawl.service.CrawlTargetCategory +import jakarta.persistence.Entity + +@Entity +class CrawlResult( + + var airpods: Int = 0, + var ipad: Int = 0, + var iphone: Int = 0, + var mac: Int = 0, + var macbook: Int = 0, + var appleWatch: Int = 0, + id: Long = 0L, +) : BaseEntity(id) { + + override fun toString(): String { + return "CrawlResult(airpods=$airpods, ipad=$ipad, iphone=$iphone, mac=$mac, macbook=$macbook, appleWatch=$appleWatch)" + } + + fun update(result: CrawlResult) { + this.airpods += result.airpods + this.ipad += result.ipad + this.iphone += result.iphone + this.mac += result.mac + this.macbook += result.macbook + this.appleWatch += result.appleWatch + } + + companion object { + fun from(crawlCategory: CrawlTargetCategory): CrawlResult = + when (crawlCategory) { + CrawlTargetCategory.MACBOOK -> CrawlResult(macbook = 1) + CrawlTargetCategory.IPAD -> CrawlResult(ipad = 1) + CrawlTargetCategory.APPLE_WATCH -> CrawlResult(appleWatch = 1) + CrawlTargetCategory.MAC -> CrawlResult(mac = 1) + CrawlTargetCategory.AIRPODS -> CrawlResult(airpods = 1) + CrawlTargetCategory.IPHONE -> CrawlResult(iphone = 1) + } + } +} diff --git a/src/main/kotlin/backend/itracker/crawl/result/repository/CrawlResultRepository.kt b/src/main/kotlin/backend/itracker/crawl/result/repository/CrawlResultRepository.kt new file mode 100644 index 0000000..9cdde7b --- /dev/null +++ b/src/main/kotlin/backend/itracker/crawl/result/repository/CrawlResultRepository.kt @@ -0,0 +1,16 @@ +package backend.itracker.crawl.result.repository + +import backend.itracker.crawl.result.CrawlResult +import org.springframework.data.jpa.repository.JpaRepository +import org.springframework.data.jpa.repository.Query +import java.time.LocalDateTime + +interface CrawlResultRepository : JpaRepository { + + @Query(""" + select cr + from CrawlResult cr + where cr.createdAt between :today and :tomorrow + """) + fun findByCreatedAtBetween(today: LocalDateTime, tomorrow: LocalDateTime) : List +} diff --git a/src/main/kotlin/backend/itracker/crawl/service/CrawlResultService.kt b/src/main/kotlin/backend/itracker/crawl/service/CrawlResultService.kt new file mode 100644 index 0000000..085e1c6 --- /dev/null +++ b/src/main/kotlin/backend/itracker/crawl/service/CrawlResultService.kt @@ -0,0 +1,27 @@ +package backend.itracker.crawl.service + +import backend.itracker.crawl.result.CrawlResult +import backend.itracker.crawl.result.repository.CrawlResultRepository +import org.springframework.stereotype.Service +import org.springframework.transaction.annotation.Transactional +import java.time.LocalDateTime + +@Transactional +@Service +class CrawlResultService( + private val crawlResultRepository: CrawlResultRepository +) { + + fun updateCrawlResult(crawlCategory: CrawlTargetCategory) { + val today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0) + val results = crawlResultRepository.findByCreatedAtBetween(today, today.plusDays(1L)) + + if (results.isEmpty()) { + crawlResultRepository.save(CrawlResult.from(crawlCategory)) + return + } + + val latest = results.last() + latest.update(CrawlResult.from(crawlCategory)) + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/config/AsyncConfig.kt b/src/main/kotlin/backend/itracker/schedule/config/AsyncConfig.kt index f4e3a7c..61af920 100644 --- a/src/main/kotlin/backend/itracker/schedule/config/AsyncConfig.kt +++ b/src/main/kotlin/backend/itracker/schedule/config/AsyncConfig.kt @@ -2,9 +2,9 @@ package backend.itracker.schedule.config import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.core.task.TaskExecutor import org.springframework.scheduling.annotation.EnableAsync import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor -import java.util.concurrent.Executor private const val THREAD_POOL_SIZE = 2 private const val MAX_POOL_SIZE = 4 @@ -15,13 +15,14 @@ private const val QUEUE_CAPACITY = 4 class AsyncConfig { @Bean - fun taskExecutor(): Executor { + fun taskExecutor(): TaskExecutor { val taskExecutor = ThreadPoolTaskExecutor() - taskExecutor.setThreadNamePrefix("Async-Schedule-") + taskExecutor.setThreadNamePrefix("Async-itracker-") taskExecutor.corePoolSize = THREAD_POOL_SIZE taskExecutor.maxPoolSize = MAX_POOL_SIZE taskExecutor.queueCapacity = QUEUE_CAPACITY - taskExecutor.initialize() + taskExecutor.setWaitForTasksToCompleteOnShutdown(true) + taskExecutor.setAwaitTerminationSeconds(180) return taskExecutor } } diff --git a/src/main/kotlin/backend/itracker/schedule/config/SchedulingConfig.kt b/src/main/kotlin/backend/itracker/schedule/config/SchedulingConfig.kt new file mode 100644 index 0000000..4278928 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/config/SchedulingConfig.kt @@ -0,0 +1,23 @@ +package backend.itracker.schedule.config + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.scheduling.TaskScheduler +import org.springframework.scheduling.annotation.EnableScheduling +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler + +@Configuration +@EnableScheduling +class SchedulingConfig { + + @Bean + fun taskScheduler(): TaskScheduler { + val threadPoolTaskScheduler = ThreadPoolTaskScheduler() + threadPoolTaskScheduler.poolSize = 1 + threadPoolTaskScheduler.setThreadNamePrefix("Scheduling-itracker-") + threadPoolTaskScheduler.setWaitForTasksToCompleteOnShutdown(true) + threadPoolTaskScheduler.setAwaitTerminationSeconds(180) + return threadPoolTaskScheduler + } +} + diff --git a/src/main/kotlin/backend/itracker/schedule/config/ShedulingConfig.kt b/src/main/kotlin/backend/itracker/schedule/config/ShedulingConfig.kt index 5bf5b4a..e69de29 100644 --- a/src/main/kotlin/backend/itracker/schedule/config/ShedulingConfig.kt +++ b/src/main/kotlin/backend/itracker/schedule/config/ShedulingConfig.kt @@ -1,9 +0,0 @@ -package backend.itracker.schedule.config - -import org.springframework.scheduling.annotation.EnableScheduling -import org.springframework.stereotype.Component - -@Component -@EnableScheduling -class ShedulingConfig - diff --git a/src/main/kotlin/backend/itracker/schedule/controller/ScheduleController.kt b/src/main/kotlin/backend/itracker/schedule/controller/ScheduleController.kt index 2e583fe..88cc5df 100644 --- a/src/main/kotlin/backend/itracker/schedule/controller/ScheduleController.kt +++ b/src/main/kotlin/backend/itracker/schedule/controller/ScheduleController.kt @@ -15,13 +15,6 @@ class ScheduleController( @Async @PostMapping("/api/v1/schedule/update") fun manualCrawl(@RequestParam category: CrawlTargetCategory) { - when (category) { - CrawlTargetCategory.MACBOOK -> crawlSchedulerService.crawlMacbook() - CrawlTargetCategory.IPAD -> crawlSchedulerService.crawlIpad() - CrawlTargetCategory.APPLE_WATCH -> crawlSchedulerService.crawlAppleWatch() - CrawlTargetCategory.MAC -> crawlSchedulerService.crawlMac() - CrawlTargetCategory.AIRPODS -> crawlSchedulerService.crawlAirPods() - CrawlTargetCategory.IPHONE -> crawlSchedulerService.crawlIphone() - } + crawlSchedulerService.crawlManual(category) } } diff --git a/src/main/kotlin/backend/itracker/schedule/service/CrawlSchedulerService.kt b/src/main/kotlin/backend/itracker/schedule/service/CrawlSchedulerService.kt index 804c2b4..d53de15 100644 --- a/src/main/kotlin/backend/itracker/schedule/service/CrawlSchedulerService.kt +++ b/src/main/kotlin/backend/itracker/schedule/service/CrawlSchedulerService.kt @@ -1,90 +1,28 @@ package backend.itracker.schedule.service -import backend.itracker.crawl.airpods.service.AirPodsService -import backend.itracker.crawl.ipad.service.IpadService -import backend.itracker.crawl.iphone.service.IphoneService -import backend.itracker.crawl.mac.service.MacService -import backend.itracker.crawl.macbook.service.MacbookService -import backend.itracker.crawl.service.CrawlService -import backend.itracker.crawl.watch.service.AppleWatchService -import io.github.oshai.kotlinlogging.KotlinLogging +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.schedule.service.schedulers.SchedulerComposite import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component -import kotlin.time.measureTime -private const val CRAWLING_TIME = "0 0 3 * * *" +private const val CRAWLING_TIME = "30 31 17 * * *" private const val TIME_ZONE = "Asia/Seoul" -private val logger = KotlinLogging.logger {} +private val CRAWL_TARGETS = CrawlTargetCategory.entries @Component class CrawlSchedulerService( - private val crawlService: CrawlService, - private val macbookService: MacbookService, - private val ipadService: IpadService, - private val appleWatchService: AppleWatchService, - private val macService: MacService, - private val airPodsService: AirPodsService, - private val iphoneService: IphoneService + private val crawlers: SchedulerComposite, ) { - @Scheduled(cron = CRAWLING_TIME, zone = TIME_ZONE) - fun crawlMacbook() { - logger.info { "맥북 크롤링 시작. " } - val times = measureTime { - val macbooks = crawlService.crawlMacbook() - macbookService.saveAll(macbooks) - } - logger.info { "맥북 크롤링 끝. 시간: $times" } - } - - @Scheduled(cron = CRAWLING_TIME, zone = TIME_ZONE) - fun crawlIpad() { - logger.info { "아이패드 크롤링 시작. " } - val times = measureTime { - val ipads = crawlService.crawlIpad() - ipadService.saveAll(ipads) - } - logger.info { "아이패드 크롤링 끝. 시간: $times" } - } - - @Scheduled(cron = CRAWLING_TIME, zone = TIME_ZONE) - fun crawlAppleWatch() { - logger.info { "애플워치 크롤링 시작. " } - val times = measureTime { - val appleWatches = crawlService.crawlAppleWatch() - appleWatchService.saveAll(appleWatches) - } - logger.info { "애플워치 크롤링 끝. 시간: $times" } - } - - @Scheduled(cron = CRAWLING_TIME, zone = TIME_ZONE) - fun crawlMac() { - logger.info { "맥 크롤링 시작. " } - val times = measureTime { - val macs = crawlService.crawlMac() - macService.saveAll(macs) - } - logger.info { "맥 크롤링 끝. 시간: $times" } - } - - @Scheduled(cron = CRAWLING_TIME, zone = TIME_ZONE) - fun crawlAirPods() { - logger.info { "에어팟 크롤링 시작. " } - val times = measureTime { - val airPods = crawlService.crawlAirPods() - airPodsService.saveAll(airPods) - } - logger.info { "에어팟 크롤링 끝. 시간: $times" } + fun crawlManual(category: CrawlTargetCategory) { + crawlers.getScheduler(category).doSchedule() } @Scheduled(cron = CRAWLING_TIME, zone = TIME_ZONE) - fun crawlIphone() { - logger.info { "아이폰 크롤링 시작. " } - val times = measureTime { - val iphones = crawlService.crawlIphone() - iphoneService.saveAll(iphones) + fun scheduleCrawl() { + CRAWL_TARGETS.forEach { + crawlManual(it) } - logger.info { "아이폰 크롤링 끝. 시간: $times" } } } diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/Schedulable.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/Schedulable.kt new file mode 100644 index 0000000..53b58d0 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/Schedulable.kt @@ -0,0 +1,16 @@ +package backend.itracker.schedule.service.schedulers + +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory + +abstract class Schedulable( + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) { + + abstract fun supports(): CrawlTargetCategory + + abstract fun doSchedule() +} + diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/SchedulerComposite.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/SchedulerComposite.kt new file mode 100644 index 0000000..97cfd19 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/SchedulerComposite.kt @@ -0,0 +1,16 @@ +package backend.itracker.schedule.service.schedulers + +import backend.itracker.crawl.service.CrawlTargetCategory +import org.springframework.stereotype.Component + +@Component +class SchedulerComposite( + private val schedulables: Set +) { + + private val schedulers = schedulables.associateBy { it.supports() } + + fun getScheduler(crawlTargetCategory: CrawlTargetCategory): Schedulable { + return schedulers[crawlTargetCategory] ?: throw IllegalStateException("해당하는 스케쥴러가 없습니다. $crawlTargetCategory") + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/airpods/AirpodsScheduler.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/airpods/AirpodsScheduler.kt new file mode 100644 index 0000000..0280836 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/airpods/AirpodsScheduler.kt @@ -0,0 +1,34 @@ +package backend.itracker.schedule.service.schedulers.airpods + +import backend.itracker.crawl.airpods.service.AirPodsService +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.schedule.service.schedulers.Schedulable +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component +import kotlin.time.measureTime + +private val logger = KotlinLogging.logger {} + +@Component +class AirpodsScheduler( + private val airPodsService: AirPodsService, + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) : Schedulable(crawlResultService, crawlService) { + + override fun supports(): CrawlTargetCategory { + return CrawlTargetCategory.AIRPODS + } + + override fun doSchedule() { + logger.info { "에어팟 크롤링 시작. " } + val times = measureTime { + val airPods = crawlService.crawlAirPods() + airPodsService.saveAll(airPods) + } + crawlResultService.updateCrawlResult(CrawlTargetCategory.AIRPODS) + logger.info { "에어팟 크롤링 끝. 시간: $times" } + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/ipad/IpadScheduler.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/ipad/IpadScheduler.kt new file mode 100644 index 0000000..e68d706 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/ipad/IpadScheduler.kt @@ -0,0 +1,34 @@ +package backend.itracker.schedule.service.schedulers.ipad + +import backend.itracker.crawl.ipad.service.IpadService +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.schedule.service.schedulers.Schedulable +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component +import kotlin.time.measureTime + +private val logger = KotlinLogging.logger {} + +@Component +class IpadScheduler( + private val ipadService: IpadService, + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) : Schedulable(crawlResultService, crawlService) { + + override fun supports(): CrawlTargetCategory { + return CrawlTargetCategory.IPAD + } + + override fun doSchedule() { + logger.info { "아이패드 크롤링 시작. " } + val times = measureTime { + val ipads = crawlService.crawlIpad() + ipadService.saveAll(ipads) + } + crawlResultService.updateCrawlResult(CrawlTargetCategory.IPAD) + logger.info { "아이패드 크롤링 끝. 시간: $times" } + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/iphone/IphoneScheduler.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/iphone/IphoneScheduler.kt new file mode 100644 index 0000000..361040c --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/iphone/IphoneScheduler.kt @@ -0,0 +1,34 @@ +package backend.itracker.schedule.service.schedulers.iphone + +import backend.itracker.crawl.iphone.service.IphoneService +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.schedule.service.schedulers.Schedulable +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component +import kotlin.time.measureTime + +private val logger = KotlinLogging.logger {} + +@Component +class IphoneScheduler( + private val iphoneService: IphoneService, + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) : Schedulable(crawlResultService, crawlService) { + + override fun supports(): CrawlTargetCategory { + return CrawlTargetCategory.IPHONE + } + + override fun doSchedule() { + logger.info { "아이폰 크롤링 시작. " } + val times = measureTime { + val iphones = crawlService.crawlIphone() + iphoneService.saveAll(iphones) + } + crawlResultService.updateCrawlResult(CrawlTargetCategory.IPHONE) + logger.info { "아이폰 크롤링 끝. 시간: $times" } + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/mac/MacScheduler.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/mac/MacScheduler.kt new file mode 100644 index 0000000..83cec31 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/mac/MacScheduler.kt @@ -0,0 +1,34 @@ +package backend.itracker.schedule.service.schedulers.mac + +import backend.itracker.crawl.mac.service.MacService +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.schedule.service.schedulers.Schedulable +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component +import kotlin.time.measureTime + +private val logger = KotlinLogging.logger {} + +@Component +class MacScheduler( + private val macService: MacService, + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) : Schedulable(crawlResultService, crawlService) { + + override fun supports(): CrawlTargetCategory { + return CrawlTargetCategory.MAC + } + + override fun doSchedule() { + logger.info { "맥 크롤링 시작. " } + val times = measureTime { + val macs = crawlService.crawlMac() + macService.saveAll(macs) + } + crawlResultService.updateCrawlResult(CrawlTargetCategory.MAC) + logger.info { "맥 크롤링 끝. 시간: $times" } + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/macbook/MacbookScheduler.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/macbook/MacbookScheduler.kt new file mode 100644 index 0000000..c66ca11 --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/macbook/MacbookScheduler.kt @@ -0,0 +1,34 @@ +package backend.itracker.schedule.service.schedulers.macbook + +import backend.itracker.crawl.macbook.service.MacbookService +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.schedule.service.schedulers.Schedulable +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component +import kotlin.time.measureTime + +private val logger = KotlinLogging.logger {} + +@Component +class MacbookScheduler( + private val macbookService: MacbookService, + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) : Schedulable(crawlResultService, crawlService) { + + override fun supports(): CrawlTargetCategory { + return CrawlTargetCategory.MACBOOK + } + + override fun doSchedule() { + logger.info { "맥북 크롤링 시작. " } + val times = measureTime { + val macbooks = crawlService.crawlMacbook() + macbookService.saveAll(macbooks) + } + crawlResultService.updateCrawlResult(CrawlTargetCategory.MACBOOK) + logger.info { "맥북 크롤링 끝. 시간: $times" } + } +} diff --git a/src/main/kotlin/backend/itracker/schedule/service/schedulers/watch/AppleWatchScheduler.kt b/src/main/kotlin/backend/itracker/schedule/service/schedulers/watch/AppleWatchScheduler.kt new file mode 100644 index 0000000..3d2796c --- /dev/null +++ b/src/main/kotlin/backend/itracker/schedule/service/schedulers/watch/AppleWatchScheduler.kt @@ -0,0 +1,34 @@ +package backend.itracker.schedule.service.schedulers.watch + +import backend.itracker.crawl.service.CrawlResultService +import backend.itracker.crawl.service.CrawlService +import backend.itracker.crawl.service.CrawlTargetCategory +import backend.itracker.crawl.watch.service.AppleWatchService +import backend.itracker.schedule.service.schedulers.Schedulable +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component +import kotlin.time.measureTime + +private val logger = KotlinLogging.logger {} + +@Component +class AppleWatchScheduler( + private val appleWatchService: AppleWatchService, + private val crawlResultService: CrawlResultService, + private val crawlService: CrawlService, +) : Schedulable(crawlResultService, crawlService) { + + override fun supports(): CrawlTargetCategory { + return CrawlTargetCategory.APPLE_WATCH + } + + override fun doSchedule() { + logger.info { "애플워치 크롤링 시작. " } + val times = measureTime { + val appleWatches = crawlService.crawlAppleWatch() + appleWatchService.saveAll(appleWatches) + } + crawlResultService.updateCrawlResult(CrawlTargetCategory.APPLE_WATCH) + logger.info { "애플워치 크롤링 끝. 시간: $times" } + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 19bbc9c..d59d156 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,3 +19,6 @@ cors: selenium: driver-url: http://localhost:4444 + +server: + shutdown: graceful