- fatta ottimizzazione della funzione addExtraInfo, chiamando parallelamente tutte le promise...

This commit is contained in:
Surya Paolo
2025-03-13 12:48:23 +01:00
parent 0017f04e45
commit f32bd189dc
4 changed files with 136 additions and 92 deletions

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -1 +1 @@
1.2.14
1.2.15