forked from EO2-WAVY/WavyBackend
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[EO2-WAVY#120] ML 서버 시작 Interceptor 개발 및 GET /auth/token에 적용
GET /auth/token에 적용한 이유는 해당 API가 호출되었다면 회원가입 또는 로그인이 이루어졌으므로, 조금 후 분석이 일어날 수 있기 때문이다. 차후 Google Analytics와의 연동으로 접속자 수에 따라 ML 서버를 시작 / 종료하게 만들 계획이다.
- Loading branch information
Showing
4 changed files
with
106 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { | ||
CallHandler, | ||
ExecutionContext, | ||
Injectable, | ||
NestInterceptor, | ||
} from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { EC2 } from 'aws-sdk'; | ||
import { InjectAwsService } from 'nest-aws-sdk'; | ||
import { Observable } from 'rxjs'; | ||
|
||
@Injectable() | ||
export class StartMLInstanceInterceptor implements NestInterceptor { | ||
static instanceId: string; | ||
|
||
constructor( | ||
@InjectAwsService(EC2) | ||
private readonly ec2Service: EC2, | ||
private readonly config: ConfigService, | ||
) { | ||
StartMLInstanceInterceptor.instanceId = | ||
this.config.get('AWS_ML_INSTANCE_ID'); | ||
} | ||
intercept( | ||
context: ExecutionContext, | ||
next: CallHandler<any>, | ||
): Observable<any> | Promise<Observable<any>> { | ||
this.startInstance(); | ||
return next.handle(); | ||
} | ||
|
||
async startInstance() { | ||
const instanceStatusResult = await this.ec2Service | ||
.describeInstances({ | ||
DryRun: false, | ||
InstanceIds: [StartMLInstanceInterceptor.instanceId], | ||
}) | ||
.promise(); | ||
|
||
if (instanceStatusResult.$response.error) { | ||
const error = instanceStatusResult.$response.error; | ||
const errString = `${error.name}(${error.code}): ${error.message}`; | ||
throw Error(errString); | ||
} | ||
|
||
const mlInstance = instanceStatusResult.Reservations[0].Instances[0]; | ||
const instanceState = mlInstance.State.Name; | ||
|
||
if (instanceState == 'stopping') { | ||
this.startWhileStopping(); | ||
} else if (instanceState == 'stopped') { | ||
this.start(); | ||
} else if ( | ||
instanceState == 'terminated' || | ||
instanceState == 'shutting-down' | ||
) { | ||
throw new Error(`!!! MLInstance is ${instanceState}. !!!`); | ||
} | ||
} | ||
|
||
private async start() { | ||
const result = await this.ec2Service | ||
.startInstances({ | ||
DryRun: false, | ||
InstanceIds: [StartMLInstanceInterceptor.instanceId], | ||
}) | ||
.promise(); | ||
return result.StartingInstances[0].InstanceId; | ||
} | ||
private async startWhileStopping() { | ||
await this.ec2Service | ||
.waitFor('instanceStopped', { | ||
DryRun: false, | ||
InstanceIds: [StartMLInstanceInterceptor.instanceId], | ||
$waiter: { | ||
delay: 3, | ||
}, | ||
}) | ||
.promise(); | ||
return await this.start(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters