diff --git a/src/server/middleware/authenticate.js b/src/server/middleware/authenticate.js index fac9593..ccd66f9 100755 --- a/src/server/middleware/authenticate.js +++ b/src/server/middleware/authenticate.js @@ -187,7 +187,7 @@ const authenticate_noerror_WithUser = async (req, res, next) => { try { const token = req.header('x-auth'); const refreshToken = req.header('x-refrtok'); - console.log(' ### Authenticate_noerror: token', !!token); + console.log(' ### authenticate_noerror_WithUser: token', !!token); if (!token) { req.user = null; @@ -229,7 +229,7 @@ const authenticate_noerror_WithUserLean = async (req, res, next) => { try { const token = req.header('x-auth'); const refreshToken = req.header('x-refrtok'); - console.log(' ### Authenticate_noerror: token', !!token); + console.log(' ### authenticate_noerror_WithUserLean: token', !!token); if (!token) { req.user = null; diff --git a/src/server/models/user.js b/src/server/models/user.js index d416f32..5d6b726 100755 --- a/src/server/models/user.js +++ b/src/server/models/user.js @@ -752,6 +752,7 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, wi let code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN; let user = null; let decoded; + const start = process.hrtime.bigint(); if (!token) return { user, code }; @@ -780,7 +781,7 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, wi access: typeaccess, }, }, - }, project).lean(); + }, project).lean(); } else { user = await User.findOne({ _id: decoded.smart, @@ -791,7 +792,7 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, wi }, }, }, project); - } + } } else { project = { perm: 1, _id: 1, idapp: 1, username: 1, deleted: 1, aportador_solidario: 1, aportador_solidario_nome_completo: 1, 'profile.socioresidente': 1 }; @@ -816,6 +817,9 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, wi } } + const end = process.hrtime.bigint(); + console.log(` findByToken impiega ${Math.round(Number(end - start) / 1e6) / 1000} secondi.`); + return { user, code }; }; @@ -5847,117 +5851,111 @@ UserSchema.statics.getProfilePerActivitiesByUsername = async function (idapp, us }; UserSchema.statics.addExtraInfo = async function (idapp, recUser, version) { - try { - // tools.startTimeLog('addExtraInfo') - + // Verifica e aggiornamento della versione (blocco sequenziale) if (version && recUser) { - let versattualeuser = 0; - if (!recUser?.profile?.version) { - recUser.version = 0; - versattualeuser = 0; - } else { - versattualeuser = recUser.profile?.version; - } - - // versattualeuser = 0; // TOGLIERE! - + const versattualeuser = recUser?.profile?.version || 0; if (versattualeuser < version) { - // Aggiornamento versione + // Aggiorna la versione utente (eventuali chiamate dipendenti vanno eseguite in sequenza) recUser = await User.updateVersion(versattualeuser, recUser); - await User.findOneAndUpdate({ _id: recUser._id }, { $set: { 'profile.version': version } }); } } - const listSentMyRequestFriends = await User.find({ - idapp, - 'profile.req_friends': { - $elemMatch: { username: { $eq: recUser.username } }, - }, - $or: [ - { deleted: { $exists: false } }, - { deleted: { $exists: true, $eq: false } }], - }, { username: 1 }).lean(); + // Esegui le query indipendenti in parallelo + const [ + listSentMyRequestFriends, + listSentMyRequestGroups, + listRefusedGroups, + listManageGroups, + reactions, + userstoverify, + circuitobj, + useraccounts, + calcstat, + calcOther + ] = await Promise.all([ + // Richiesta per gli amici a cui è stata mandata una richiesta + User.find( + { + idapp, + 'profile.req_friends': { $elemMatch: { username: recUser.username } }, + $or: [{ deleted: { $exists: false } }, { deleted: { $eq: false } }] + }, + { username: 1 } + ).lean(), - recUser.profile.asked_friends = listSentMyRequestFriends - ? listSentMyRequestFriends - : []; + // Richiesta per i gruppi a cui è stata mandata una richiesta + MyGroup.find( + { + idapp, + 'req_users': { $elemMatch: { username: recUser.username } }, + $or: [{ deleted: { $exists: false } }, { deleted: { $eq: false } }] + }, + MyGroup.getWhatToShow_Unknown() + ).lean(), - const listSentMyRequestGroups = await MyGroup.find({ - idapp, - 'req_users': { - $elemMatch: { username: { $eq: recUser.username } }, - }, - $or: [ - { deleted: { $exists: false } }, - { deleted: { $exists: true, $eq: false } }], - }, MyGroup.getWhatToShow_Unknown()).lean(); + // Richiesta per i gruppi rifiutati + MyGroup.find( + { + idapp, + 'refused_users': { $elemMatch: { username: recUser.username } }, + $or: [{ deleted: { $exists: false } }, { deleted: { $eq: false } }] + }, + MyGroup.getWhatToShow_Unknown() + ).lean(), - recUser.profile.asked_groups = listSentMyRequestGroups - ? listSentMyRequestGroups - : []; + // Richiesta per i gruppi gestiti (admin) + MyGroup.find( + { + idapp, + 'admins': { $elemMatch: { username: recUser.username } }, + $or: [{ deleted: { $exists: false } }, { deleted: { $eq: false } }] + } + ).lean(), - const listRefusedGroups = await MyGroup.find({ - idapp, - 'refused_users': { - $elemMatch: { username: { $eq: recUser.username } }, - }, - $or: [ - { deleted: { $exists: false } }, - { deleted: { $exists: true, $eq: false } }], - }, MyGroup.getWhatToShow_Unknown()).lean(); + // Reazioni + Reaction.find({ idapp, username: recUser.username }).lean(), - recUser.profile.refused_groups = listRefusedGroups - ? listRefusedGroups - : []; + // Altri utenti da verificare + User.getUsersToVerify(idapp, recUser.username), - const listManageGroups = await MyGroup.find({ - idapp, - 'admins': { - $elemMatch: { username: { $eq: recUser.username } }, - }, - $or: [ - { deleted: { $exists: false } }, - { deleted: { $exists: true, $eq: false } }], - }).lean(); + // Circuiti associati + Circuit.getCircuitsByUsername(idapp, recUser.username, recUser, 5), - recUser.profile.reaction = await Reaction.find({ idapp, username: recUser.username }).lean(); + // Conto degli account utente + Account.getUserAccounts(idapp, recUser.username), - recUser.profile.userstoverify = await User.getUsersToVerify(idapp, recUser.username); + // Statistiche dell'utente + User.calculateStat(idapp, recUser.username), - recUser.profile.manage_mygroups = listManageGroups - ? listManageGroups - : []; + // Altri calcoli per l'utente + User.calcOtherByUser(idapp, recUser._id) + ]); - // Circuit> - - const circuitobj = await Circuit.getCircuitsByUsername(idapp, recUser.username, recUser, 5); - - const useraccounts = await Account.getUserAccounts(idapp, recUser.username); - - for (const group of listManageGroups) { - const myaccounts = await Account.getGroupAccounts(idapp, group.groupname); - if (myaccounts && myaccounts.length > 0) - group.account = myaccounts[0]; - else - group.account = null; - } + // Per ogni gruppo gestito, recupera gli account in parallelo + const manageGroupsWithAccounts = await Promise.all( + listManageGroups.map(async (group) => { + const myaccounts = await Account.getGroupAccounts(idapp, group.groupname); + return { ...group, account: (myaccounts && myaccounts.length > 0) ? myaccounts[0] : null }; + }) + ); + // Assegna i risultati al profilo utente + recUser.profile.asked_friends = listSentMyRequestFriends || []; + recUser.profile.asked_groups = listSentMyRequestGroups || []; + recUser.profile.refused_groups = listRefusedGroups || []; + recUser.profile.reaction = reactions; + recUser.profile.userstoverify = userstoverify; + recUser.profile.manage_mygroups = manageGroupsWithAccounts; recUser.profile = { ...recUser.profile, ...circuitobj, useraccounts }; - - recUser.calcstat = await User.calculateStat(idapp, recUser.username); - - recUser.profile.calc = await User.calcOtherByUser(idapp, recUser._id); - - // tools.endTimeLog('addExtraInfo') + recUser.calcstat = calcstat; + recUser.profile.calc = calcOther; return recUser; - } catch (e) { console.error('Err addExtraInfo', e); } - return recUser; }; diff --git a/src/server/router/index_router.js b/src/server/router/index_router.js index 9ae85a0..161acd7 100755 --- a/src/server/router/index_router.js +++ b/src/server/router/index_router.js @@ -1822,6 +1822,46 @@ router.get('/loadsite/:userId/:idapp/:vers', authenticate_noerror_WithUserLean, } }); +async function measurePromises(promises) { + const keys = Object.keys(promises); + const timings = {}; // memorizza il tempo per ogni promise + const startTotal = process.hrtime(); // tempo iniziale totale + + // Avvolgo ogni promise per misurare il tempo + const wrappedPromises = keys.map(key => { + const promise = promises[key]; + return (async () => { + const start = process.hrtime(); // inizio timer per questa promise + const result = await promise; + const diff = process.hrtime(start); + // Calcola i secondi (precisione in nanosecondi) + const seconds = diff[0] + diff[1] / 1e9; + timings[key] = seconds; + return result; + })(); + }); + + // Attendo tutte le promise in parallelo + const results = await Promise.all(wrappedPromises); + const diffTotal = process.hrtime(startTotal); + const totalTime = diffTotal[0] + diffTotal[1] / 1e9; + + // Ricostruisco l'oggetto data con i risultati + const data = keys.reduce((acc, key, index) => { + acc[key] = results[index]; + return acc; + }, {}); + + // Ordina le chiamate per tempo decrescente e prende le 10 più lente + const slowCalls = Object.entries(timings) + .sort(([, timeA], [, timeB]) => timeB - timeA) + .slice(0, 10) + .map(([key, time]) => ({ key, time })); + + return { data, totalTime, slowCalls }; +} + + async function load(req, res, version = '0') { try { console.log(' ... 1) richiesta LOAD'); @@ -1922,12 +1962,18 @@ async function load(req, res, version = '0') { }; // Esecuzione parallela di tutte le promesse - const keys = Object.keys(promises); + /*const keys = Object.keys(promises); const results = await Promise.all(Object.values(promises)); const data = keys.reduce((acc, key, index) => { acc[key] = results[index]; return acc; }, {}); + */ + + const { data, totalTime, slowCalls } = await measurePromises(promises); + // console.log('Risultati delle promise:', data); + console.log('Tempo totale di esecuzione:', totalTime, 'secondi'); + console.log('Le 10 chiamate più lente:', slowCalls); // Aggiornamento delle informazioni dell'utente, se presente let myuser = req.user; diff --git a/src/server/version.txt b/src/server/version.txt index d79a5f8..05060b8 100644 --- a/src/server/version.txt +++ b/src/server/version.txt @@ -1 +1 @@ -1.2.14 \ No newline at end of file +1.2.15 \ No newline at end of file