빌리보이님에게 다시 질문드려요. lambda fileUpload

2020. 02. 11. 02:34

전체 소스를 간략하게 올리겠습니다.

serverless를 통해서 handler에 오고

handler.ts의 제가 사용하는 소스부분입니다.

export async function getFunctionExcel(event: lambda.APIGatewayProxyEvent, context: lambda.Context) {
  context.callbackWaitsForEmptyEventLoop = false;
  connection = await db.getConnection();

  const result = await app.getFunctionExcel(connection, event, (event.queryStringParameters as any), context);

  return result.getAPIGatewayProxyResult();
}

app.ts 부분입니다.

export async function getFunctionExcel(connection: Connection, event: any, params: Parameter, context: lambda.Context) {
    const total = [...] //엑셀안에 들어갈 내용으로 db에서 가져온 데이터
    const resultFileName = common.createExcel('excel_', total); // filename , 데이터
    return DefaultResponse.getSuccess({
      message: '목록 조회에 성공했습니다.',
      data: {
        resultFileName,
      }
    })
}

common.ts 부분입니다.

export function createExcel(fileName: string, totalList: any) {
    let key = '';
    try {
        // step 1. workbook 생성
        let wb = XLSX.utils.book_new();

        // step 2. 시트 만들기 [key: 항목 , val: 값] 한글명칭사용하려면 key가 한글이어야 함
        let newWorksheet = XLSX.utils.json_to_sheet(totalList);

        // step 3. workbook에 새로만든 워크시트에 이름을 주고 붙인다.
        XLSX.utils.book_append_sheet(wb, newWorksheet, 'Sheet0');

        // step 4. 엑셀 파일 만들기
        const file = XLSX.write(wb, {type: "buffer"});

        // step 5. s3 업로드, key를 front에 전달
        fileName += moment().format('YYYYMMDD_HHmmss') + '.xlsx';
        key = 'excel' + `/` + fileName;
        fileService.uploadFileStream(file, key);

    } catch (e) {
        console.error(e.message);
    }

    return key;
}

fileService.ts 부분입니다.

export async function uploadFileStream(fileStream: any, key: string, bucketName: string = '') {
    bucketName = bucketName || 'myStorage';
    const uploadParams = {Bucket: bucketName, Key: key, Body: fileStream};
    console.log('5. 엑셀 파일 업로드');
    await s3.putObject(uploadParams, (err, data) => {
        console.log('7. s3.putObject callback function');
        if (data) {
            console.log("Upload Success", data);
        } else if (err) {
            console.log("Error", err);
        }
    });
    console.log('6. 엑셀 파일 업로드 태그 확인');
}

https://www.a-ha.io/questions/423161060adbe5b38b999c975b4f867b 먼저 이 도움 부분으로 fileupload 는 했습니다. (local에서만 돌아서 문제에요 ㅠㅠ)

https://www.a-ha.io/questions/4086d320f3d129488b9ee562df4b04d8?recBy=KP7T7V

어제 알려주신것 중 예시 2) async await 사용하기 는 callback부분이 없으면 로컬에서도 실패합니다.

회사내부에서 callback(), Promise() 는 사용을 안하는 방향으로 하고 있어서 내부 callback으로 해결해야하는데

내부 콜백을.... 안들어오네요 '7. s3.putObject callback function' 이게 찍히면 일단 들어왔다 판단이라도 할텐데...

정말 도움주셔서 감사했습니다. ㅎㅎ

공유하고 돈벌기 ♥︎

총 1개의 답변이 있습니다.

질문자 채택 답변
https://github.com/kangisworking

안녕하세요

현재 올리신 코드 실행하시면, 말씀하신것처럼 s3. putObject 전까지만 딱 정상 작동할것 같습니다.

현재 사용하시려는 것처럼 쓰시려면 await 을 붙여야 하위 코드들의 비동기 액션들을 실행한

결과를 반환합니다.

app.ts 에 common.createExcel 앞에 await 붙이시고

common.ts 을 async 로 변경하시고 uploadFileStream 앞에 await 을 해주셔야 될것 같습니다.

const resultFileName = common.createExcel('excel_', total) 

createExcel 이 단순히 fileName 만 return 하면 상관없는데 안에서 비동기처리까지 진행하니.. await 꼭 붙여주셔야합니다.

흠.. 그리고 이건 다른 얘기인데 코드에 db connection 이 있어서 이거 lambda 끝날때 db connection close 안하고 끝내도 문제 안되시나요? 예전에 제가 다른거 할때 db connection 이 살아있으면 lambda 가 종료안되고 5분인가 지나야 종료되던 문제가 있었는데..

어쨋든 수고하세요~

2020. 02. 11. 04:34
2392