|
2 | 2 | import logging |
3 | 3 | import time |
4 | 4 | import asyncio |
5 | | -from concurrent.futures import ThreadPoolExecutor, as_completed |
6 | 5 | from app.services.batch_service import BatchService |
7 | 6 | from app.utils.discord_notifier import notify_discord_async |
8 | 7 |
|
|
12 | 11 | def start_batch_scheduler(): |
13 | 12 | scheduler = BackgroundScheduler(timezone="Asia/Seoul") |
14 | 13 |
|
15 | | - @scheduler.scheduled_job('cron', hour=19, minute=15) |
| 14 | + @scheduler.scheduled_job( |
| 15 | + 'cron', |
| 16 | + hour=16, minute=5, day_of_week='mon-fri', |
| 17 | + coalesce=False, # 밀린 작업 버림 |
| 18 | + max_instances=1, # 중복 실행 방지 |
| 19 | + misfire_grace_time=600 # 지연 허용 10분 |
| 20 | + ) |
16 | 21 | def run_batch(): |
17 | | - logger.info("[Scheduler] 18:05 배치 예측 시작") |
18 | | - start = time.time() |
19 | | - |
20 | | - success_count = 0 |
21 | | - fail_count = 0 |
22 | | - failed_symbols = [] # 실패한 종목 |
23 | | - |
24 | | - start_id = 1 |
25 | | - end_id = 100 |
26 | | - max_workers = 3 |
27 | | - |
28 | | - with ThreadPoolExecutor(max_workers=max_workers) as executor: |
29 | | - futures = { |
30 | | - executor.submit(BatchService.process_single_stock, stock_id): stock_id |
31 | | - for stock_id in range(start_id, end_id + 1) |
32 | | - } |
33 | | - |
34 | | - for future in as_completed(futures): |
35 | | - stock_id = futures[future] |
36 | | - try: |
37 | | - stock_id, success, symbol_or_msg = future.result() |
38 | | - if success: |
39 | | - success_count += 1 |
40 | | - else: |
41 | | - fail_count += 1 |
42 | | - failed_symbols.append(symbol_or_msg) # symbol 저장 |
43 | | - except Exception as e: |
44 | | - logger.exception(f"[Batch] [{stock_id}] 처리 중 예외 발생: {str(e)}") |
45 | | - fail_count += 1 |
| 22 | + logger.info("[Scheduler] 16:05 배치 예측 시작") |
| 23 | + start_time = time.time() |
| 24 | + |
| 25 | + start_id, end_id = 1, 100 |
| 26 | + chunk_size = 20 |
| 27 | + max_workers = 6 |
| 28 | + cooldown_sec = 2 |
| 29 | + |
| 30 | + success_count, fail_count, failed_symbols = BatchService.run_batch_in_chunks( |
| 31 | + start_id=start_id, |
| 32 | + end_id=end_id, |
| 33 | + chunk_size=chunk_size, |
| 34 | + max_workers=max_workers, |
| 35 | + cooldown_sec=cooldown_sec |
| 36 | + ) |
46 | 37 |
|
47 | | - duration = time.time() - start |
| 38 | + duration = time.time() - start_time |
48 | 39 | logger.info( |
49 | | - f"[Scheduler] 배치 예측 완료 - 성공: {success_count}, 실패: {fail_count}, 소요 시간: {duration:.2f}s" |
| 40 | + f"[Scheduler] 배치 예측 완료 - 성공: {success_count}, 실패: {fail_count}, 소요: {duration:.2f}s" |
50 | 41 | ) |
51 | 42 |
|
| 43 | + # Discord 알림 |
52 | 44 | # 스레드에서 비동기 함수 실행 |
53 | 45 | try: |
54 | 46 | import threading |
55 | 47 | def run_notification(): |
56 | | - asyncio.run(notify_discord_async(success_count, fail_count, duration, failed_symbols)) |
| 48 | + asyncio.run( |
| 49 | + notify_discord_async(success_count, fail_count, duration, failed_symbols, 1404342496221462539)) |
57 | 50 |
|
58 | 51 | notification_thread = threading.Thread(target=run_notification) |
59 | 52 | notification_thread.start() |
|
0 commit comments