mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-08-02 22:51:45 +00:00
Add minified listening stats mode
Before stats on the app were taking about 3422ms and returning roughly 360815 bytes for /api/me/listening-stats. After adding an opt-in minified mode that skips items and recentSessions, the same dataset benchmarks at about 102ms average and 11667 bytes while keeping the default response shape unchanged for existing clients.
This commit is contained in:
parent
fbfa6a54c1
commit
377fb71b9c
3 changed files with 40 additions and 25 deletions
|
|
@ -232,10 +232,14 @@ class MeController {
|
|||
*/
|
||||
async getListeningStats(req, res) {
|
||||
const startedAt = Date.now()
|
||||
const minified = req.query.minified === '1' || req.query.minified === 'true'
|
||||
Logger.debug(`[MeController] /api/me/listening-stats user="${req.user.id}" start`)
|
||||
const listeningStats = await this.getUserListeningStatsHelpers(req.user.id)
|
||||
const listeningStats = await this.getUserListeningStatsHelpers(req.user.id, {
|
||||
includeItems: !minified,
|
||||
includeRecentSessions: !minified
|
||||
})
|
||||
Logger.debug(
|
||||
`[MeController] /api/me/listening-stats user="${req.user.id}" totalTime=${listeningStats?.totalTime || 0} recentSessions=${listeningStats?.recentSessions?.length || 0} items=${Object.keys(listeningStats?.items || {}).length} in ${Date.now() - startedAt}ms`
|
||||
`[MeController] /api/me/listening-stats user="${req.user.id}" minified=${minified} totalTime=${listeningStats?.totalTime || 0} recentSessions=${listeningStats?.recentSessions?.length || 0} items=${Object.keys(listeningStats?.items || {}).length} in ${Date.now() - startedAt}ms`
|
||||
)
|
||||
res.json(listeningStats)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,12 +472,16 @@ class UserController {
|
|||
*/
|
||||
async getListeningStats(req, res) {
|
||||
const startedAt = Date.now()
|
||||
const minified = req.query.minified === '1' || req.query.minified === 'true'
|
||||
Logger.debug(
|
||||
`[UserController] /api/users/${req.params.id}/listening-stats reqUser="${req.user.id}" start`
|
||||
)
|
||||
var listeningStats = await this.getUserListeningStatsHelpers(req.params.id)
|
||||
var listeningStats = await this.getUserListeningStatsHelpers(req.params.id, {
|
||||
includeItems: !minified,
|
||||
includeRecentSessions: !minified
|
||||
})
|
||||
Logger.debug(
|
||||
`[UserController] /api/users/${req.params.id}/listening-stats reqUser="${req.user.id}" totalTime=${listeningStats?.totalTime || 0} recentSessions=${listeningStats?.recentSessions?.length || 0} items=${Object.keys(listeningStats?.items || {}).length} in ${Date.now() - startedAt}ms`
|
||||
`[UserController] /api/users/${req.params.id}/listening-stats reqUser="${req.user.id}" minified=${minified} totalTime=${listeningStats?.totalTime || 0} recentSessions=${listeningStats?.recentSessions?.length || 0} items=${Object.keys(listeningStats?.items || {}).length} in ${Date.now() - startedAt}ms`
|
||||
)
|
||||
res.json(listeningStats)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,27 +555,32 @@ class ApiRouter {
|
|||
return userSessions.sort((a, b) => b.updatedAt - a.updatedAt)
|
||||
}
|
||||
|
||||
async getUserListeningStatsHelpers(userId) {
|
||||
async getUserListeningStatsHelpers(userId, options = {}) {
|
||||
const startedAt = Date.now()
|
||||
const today = date.format(new Date(), 'YYYY-MM-DD')
|
||||
const includeItems = options.includeItems !== false
|
||||
const includeRecentSessions = options.includeRecentSessions !== false
|
||||
|
||||
const [listeningSessions, recentSessions] = await Promise.all([
|
||||
Database.getPlaybackSessionsForStats({ userId }),
|
||||
Database.getPlaybackSessions({ userId }, {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
order: [['updatedAt', 'DESC']]
|
||||
})
|
||||
])
|
||||
const tasks = [Database.getPlaybackSessionsForStats({ userId })]
|
||||
if (includeRecentSessions) {
|
||||
tasks.push(
|
||||
Database.getPlaybackSessions({ userId }, {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
order: [['updatedAt', 'DESC']]
|
||||
})
|
||||
)
|
||||
}
|
||||
const [listeningSessions, recentSessions = []] = await Promise.all(tasks)
|
||||
|
||||
const listeningStats = {
|
||||
totalTime: 0,
|
||||
items: {},
|
||||
days: {},
|
||||
dayOfWeek: {},
|
||||
today: 0,
|
||||
recentSessions
|
||||
today: 0
|
||||
}
|
||||
if (includeItems) listeningStats.items = {}
|
||||
if (includeRecentSessions) listeningStats.recentSessions = recentSessions
|
||||
listeningSessions.forEach((s) => {
|
||||
const libraryItemId = s.extraData?.libraryItemId || null
|
||||
let sessionTimeListening = s.timeListening
|
||||
|
|
@ -600,21 +605,23 @@ class ApiRouter {
|
|||
return
|
||||
}
|
||||
|
||||
if (!listeningStats.items[libraryItemId]) {
|
||||
listeningStats.items[libraryItemId] = {
|
||||
id: libraryItemId,
|
||||
timeListening: sessionTimeListening,
|
||||
mediaMetadata: s.mediaMetadata,
|
||||
lastUpdate: s.updatedAt
|
||||
if (includeItems) {
|
||||
if (!listeningStats.items[libraryItemId]) {
|
||||
listeningStats.items[libraryItemId] = {
|
||||
id: libraryItemId,
|
||||
timeListening: sessionTimeListening,
|
||||
mediaMetadata: s.mediaMetadata,
|
||||
lastUpdate: s.updatedAt
|
||||
}
|
||||
} else {
|
||||
listeningStats.items[libraryItemId].timeListening += sessionTimeListening
|
||||
}
|
||||
} else {
|
||||
listeningStats.items[libraryItemId].timeListening += sessionTimeListening
|
||||
}
|
||||
|
||||
listeningStats.totalTime += sessionTimeListening
|
||||
})
|
||||
Logger.debug(
|
||||
`[ApiRouter] Listening stats for user "${userId}" aggregated ${listeningSessions.length} sessions in ${Date.now() - startedAt}ms`
|
||||
`[ApiRouter] Listening stats for user "${userId}" aggregated ${listeningSessions.length} sessions in ${Date.now() - startedAt}ms includeItems=${includeItems} includeRecentSessions=${includeRecentSessions}`
|
||||
)
|
||||
return listeningStats
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue