11import 'reflect-metadata' ;
2- import { injectable } from 'tsyringe' ;
2+ import { inject , injectable } from 'tsyringe' ;
33import Anthropic from '@anthropic-ai/sdk' ;
4- import { ClaudeResponse , FeedAIQueueItem } from './common/types' ;
5- import { TagMapRepository } from './repository/tag-map.repository' ;
6- import { FeedRepository } from './repository/feed.repository' ;
7- import logger from './common/logger' ;
8- import { PROMPT_CONTENT , redisConstant } from './common/constant' ;
9- import { RedisConnection } from './common/redis-access' ;
4+ import { ClaudeResponse , FeedAIQueueItem } from '../../common/types' ;
5+ import { TagMapRepository } from '../../repository/tag-map.repository' ;
6+ import { FeedRepository } from '../../repository/feed.repository' ;
7+ import logger from '../../common/logger' ;
8+ import { PROMPT_CONTENT , redisConstant } from '../../common/constant' ;
9+ import { RedisConnection } from '../../common/redis-access' ;
10+ import { AbstractQueueWorker } from '../abstract-queue-worker' ;
11+ import { DEPENDENCY_SYMBOLS } from '../../types/dependency-symbols' ;
1012
1113@injectable ( )
12- export class ClaudeService {
14+ export class ClaudeEventWorker extends AbstractQueueWorker < FeedAIQueueItem > {
1315 private readonly client : Anthropic ;
14- private readonly nameTag : string ;
1516
1617 constructor (
18+ @inject ( DEPENDENCY_SYMBOLS . TagMapRepository )
1719 private readonly tagMapRepository : TagMapRepository ,
20+ @inject ( DEPENDENCY_SYMBOLS . FeedRepository )
1821 private readonly feedRepository : FeedRepository ,
19- private readonly redisConnection : RedisConnection ,
22+ @inject ( DEPENDENCY_SYMBOLS . RedisConnection )
23+ redisConnection : RedisConnection ,
2024 ) {
25+ super ( '[AI Service]' , redisConnection ) ;
2126 this . client = new Anthropic ( {
2227 apiKey : process . env . AI_API_KEY ,
2328 } ) ;
24- this . nameTag = '[AI Service]' ;
2529 }
2630
27- async startRequestAI ( ) {
31+ protected async processQueue ( ) : Promise < void > {
2832 const feeds = await this . loadFeeds ( ) ;
29- await Promise . all ( feeds . map ( ( feed ) => this . processFeed ( feed ) ) ) ;
33+ await Promise . all ( feeds . map ( ( feed ) => this . processItem ( feed ) ) ) ;
34+ }
35+
36+ protected getQueueKey ( ) : string {
37+ return redisConstant . FEED_AI_QUEUE ;
38+ }
39+
40+ protected parseQueueMessage ( message : string ) : FeedAIQueueItem {
41+ return JSON . parse ( message ) ;
42+ }
43+
44+ protected async processItem ( feed : FeedAIQueueItem ) : Promise < void > {
45+ try {
46+ const aiData = await this . requestAI ( feed ) ;
47+ await this . saveAIResult ( aiData ) ;
48+ } catch ( error ) {
49+ logger . error (
50+ `${ this . nameTag } ${ feed . id } 처리 중 에러 발생: ${ error . message } ` ,
51+ error . stack ,
52+ ) ;
53+ await this . handleFailure ( feed , error ) ;
54+ }
3055 }
3156
3257 private async loadFeeds ( ) {
@@ -49,19 +74,6 @@ export class ClaudeService {
4974 }
5075 }
5176
52- private async processFeed ( feed : FeedAIQueueItem ) {
53- try {
54- const aiData = await this . requestAI ( feed ) ;
55- await this . saveAIResult ( aiData ) ;
56- } catch ( error ) {
57- logger . error (
58- `${ this . nameTag } ${ feed . id } 처리 중 에러 발생: ${ error . message } ` ,
59- error . stack ,
60- ) ;
61- await this . handleFailure ( feed , error ) ;
62- }
63- }
64-
6577 private async requestAI ( feed : FeedAIQueueItem ) {
6678 logger . info ( `${ this . nameTag } AI 요청: ${ JSON . stringify ( feed ) } ` ) ;
6779 const params : Anthropic . MessageCreateParams = {
@@ -93,7 +105,10 @@ export class ClaudeService {
93105 await this . feedRepository . updateSummary ( feed . id , feed . summary ) ;
94106 }
95107
96- private async handleFailure ( feed : FeedAIQueueItem , e : Error ) {
108+ protected async handleFailure (
109+ feed : FeedAIQueueItem ,
110+ e : Error ,
111+ ) : Promise < void > {
97112 if ( feed . deathCount < 3 ) {
98113 feed . deathCount ++ ;
99114 await this . redisConnection . rpush ( redisConstant . FEED_AI_QUEUE , [
@@ -102,7 +117,7 @@ export class ClaudeService {
102117 logger . warn ( `${ this . nameTag } ${ feed . id } 재시도 (${ feed . deathCount } )` ) ;
103118 } else {
104119 logger . error (
105- `${ this . nameTag } ${ feed . id } 의 Death Count 3회 이상 발생 AI 요청 금지 ` ,
120+ `${ this . nameTag } ${ feed . id } 의 Death Count 3회 이상 발생. AI 요청 스킵 ` ,
106121 ) ;
107122 await this . feedRepository . updateNullSummary ( feed . id ) ;
108123 }
0 commit comments