노드 JS 앱을 만들었습니다. 데이터베이스에서 100000 개가 넘는 레코드를 명시 적으로 다운로드하고 있습니다. 요청이 진행되는 동안 이전 요청이 완료되지 않으면 응답하지 않는 다른 브라우저에서 동일한 애플리케이션에 로그인하려고합니다. 어떤 생각? 이벤트 루프 또는 스레드와 관련된 작업은 무엇입니까 ?? 여기 내 논리가 있습니다. 1 단계에서 API 요청을합니다. API는 2 단계에서 데이터베이스 계층을 호출합니다. 데이터베이스는 단지 21 개의 레코드 만 반환합니다. json2csv의로드를 테스트하기 위해 무거운 렌더링을 만들기 위해 100000 * 21을 명시 적으로 반복하고 있습니다. 이렇게하는 동안 서버에 대한 다른 요청은 마지막 처리가 완료 될 때까지 응답하지 않습니다.노드 JS 요청이 다른 요청을 차단합니다.
Step 1:
router.get('/report/downloadOverdueTrainings/:criteria', function (req, res, next) {
var overDueTrainings = [];
var reportManager = new ReportManager();
var result = reportManager.getOverdueTrainings(JSON.parse(req.params.criteria));
result.then(function (result) {
var fields = ['Over Due Trainings'];
for (var i = 0; i < 100000; i++) { //Testing purpose
for (var training of result) {
overDueTrainings.push({
'Over Due Trainings': training.OverDueTrainings
})
}
}
json2csv({
data: overDueTrainings,
fields: fields
}, function (err, csv) {
if (err)
throw err;
res.setHeader('Content-disposition', 'attachment; filename=OverdueTrainings.csv');
res.set('Content-Type', 'text/csv');
res.send(csv);
});
}).catch(function (err) {
next(err);
});
});
Step 2: Database Logic
var xtrDatabaseConnection =require('./xtrDatabaseConnection').XTRDatabaseConnection;
ReportData.prototype.getOverdueTrainings = async function (params) {
var connection = new xtrDatabaseConnection();
var sequelize = connection.getSequelize();
try {
var query = "CALL report_getOverdueTrainings(:p_CourseCode,:p_Revision,:p_RevisionNo,:p_UserGroup,:p_Username,:p_Status,:p_SortColoumnNo,:p_SortColoumnDirection,:p_callType,:p_StartIndex,:p_PageSize)";
var replacements = {
p_CourseCode: params.CourseCode,
p_Revision: params.Revision,
p_RevisionNo: (params.RevisionNo == '' || params.RevisionNo == null) ? 0 : params.RevisionNo,
p_UserGroup: params.UserGroup,
p_Username: params.Username,
p_Status: params.Status,
p_SortColoumnNo: params.SortColoumnNo,
p_SortColoumnDirection: params.SortColoumnDirection,
p_callType: params.callType,
p_StartIndex: params.startIndex,
p_PageSize: params.pageSize
};
//console.log(replacements);
return await connection.executeQuerySequelize(sequelize, query, Sequelize.QueryTypes.RAW, replacements);
} catch (e) {
throw (e);
} finally {
//To close connections
sequelize.connectionManager.close().then(() => console.log('Connection Closed'));
}
}
XTRDatabaseConnection.prototype.executeQuerySequelize = function (sequelize, query, queryType, replacements) {
return sequelize.authenticate()
.then(() => {
return sequelize.query(query, {
replacements: replacements,
type: queryType
}).
then(result => result)
.catch(err => {
throw (err);
});
})
.catch(err => {
xtrUtility.logErrorsToWinstonTransports('Unable to connect to the database or some error occurred while executing your query. ', err);
throw new AppError(err, "dbError", "Unable to connect to the database or some error occurred while executing your query.");
});
}
어떤 오류가 발생 했습니까? –
CSV 파일을 다운로드하라는 요청을 생성 할 때 어떤 오류도 발생하지 않습니다. 파일이 다운로드 될 때까지 응답하지 않는 다른 모든 기능을 수행합니다. 뭔가가 차단되고 있음을 의미합니다. –
그것은 for 루프 때문에 이벤트 루프를 막았습니다. 클러스터 또는 자식 프로세스를 사용해 볼 수 있습니다 –