Skip to content

Commit cbcc256

Browse files
committed
feat: optimize play next song data fetching with direct database queries.
1 parent f4e36c1 commit cbcc256

2 files changed

Lines changed: 32 additions & 12 deletions

File tree

server/routes/userRoutes.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -222,16 +222,20 @@ userRouter.route("/guestLogin").post(guestLogin)
222222
userRouter.route("/login-logs").get(authMiddleware, getLoginLogs)
223223

224224
userRouter.route("/profile").get(authMiddleware, async (req, res) => {
225-
const userid = req.user.userid
226-
if (userid) {
225+
try {
226+
const userid = req.user.userid
227+
if (!userid) {
228+
return res.status(401).json({ message: "Unauthorized" })
229+
}
227230
const user = await User.findOne({
228231
where: { userid },
229232
attributes: { exclude: ["password"] },
230233
raw: true,
231234
})
232-
res.status(200).json({ user })
233-
} else {
234-
res.status(401).json({ message: "Unauthorized" })
235+
return res.status(200).json({ user })
236+
} catch (error) {
237+
if (res.headersSent) return
238+
return res.status(500).json({ message: "Failed to fetch profile" })
235239
}
236240
})
237241

server/services/playNextService.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const Song = require("../models/music/Song")
22
const HistorySong = require("../models/music/HistorySong")
33
const { cache } = require("../utils/redis")
4+
const { Op } = require("sequelize")
45

56
const SONG_API_URL = process.env.SONG_API_URL || "https://songapi.thakur.dev"
67
const CACHE_PREFIX = "song:playnext:"
@@ -78,7 +79,6 @@ const initialize = async () => {
7879
const sd = song.songData || {}
7980
const entry = {
8081
songId: song.songId,
81-
songData: sd,
8282
name: song.name || sd.name || "Unknown",
8383
primaryArtist: extractPrimaryArtist(sd),
8484
allPrimaryArtists: extractAllPrimaryArtists(sd),
@@ -107,6 +107,7 @@ const initialize = async () => {
107107

108108
initialized = true
109109
initializing = false
110+
await cache.set("playnext:last_init", Date.now(), 0)
110111
console.log(
111112
`[PlayNext] Initialized: ${songMap.size} songs, ${artistMap.size} artists, ${labelMap.size} labels, ${languageMap.size} languages, ${albumMap.size} albums`,
112113
)
@@ -238,7 +239,10 @@ const getPlayNextSongs = async ({ baseSongId, userId = null, limit = 20, exclude
238239
return external.filter((s) => !excludeSet.has(s.id)).slice(0, limit)
239240
}
240241

241-
if (!initialized) return []
242+
if (!initialized) {
243+
initialize()
244+
return []
245+
}
242246

243247
const baseSong = songMap.get(baseSongId)
244248
if (!baseSong) {
@@ -291,10 +295,19 @@ const getPlayNextSongs = async ({ baseSongId, userId = null, limit = 20, exclude
291295
resultIds = personalized.map((p) => p.songId)
292296
}
293297

294-
return resultIds
295-
.slice(0, limit)
296-
.map((id) => songMap.get(id)?.songData)
297-
.filter(Boolean)
298+
const finalIds = resultIds.slice(0, limit)
299+
if (finalIds.length === 0) return []
300+
301+
const songs = await Song.findAll({
302+
where: { songId: { [Op.in]: finalIds } },
303+
attributes: ["songId", "songData"],
304+
raw: true,
305+
})
306+
307+
const dataMap = new Map()
308+
for (const s of songs) dataMap.set(s.songId, s.songData)
309+
310+
return finalIds.map((id) => dataMap.get(id)).filter(Boolean)
298311
}
299312

300313
const rebuildAllPlayNext = async () => {
@@ -343,7 +356,10 @@ const reload = async () => {
343356
await initialize()
344357
}
345358

346-
setTimeout(() => initialize(), 5000)
359+
cache.get("playnext:last_init").then((ts) => {
360+
if (ts) console.log(`[PlayNext] Last init: ${new Date(ts).toISOString()} — skipping eager load`)
361+
else console.log("[PlayNext] No previous init found — will load lazily on first fallback request")
362+
})
347363

348364
module.exports = {
349365
initialize,

0 commit comments

Comments
 (0)