|
1 | 1 | const Song = require("../models/music/Song") |
2 | 2 | const HistorySong = require("../models/music/HistorySong") |
3 | 3 | const { cache } = require("../utils/redis") |
| 4 | +const { Op } = require("sequelize") |
4 | 5 |
|
5 | 6 | const SONG_API_URL = process.env.SONG_API_URL || "https://songapi.thakur.dev" |
6 | 7 | const CACHE_PREFIX = "song:playnext:" |
@@ -78,7 +79,6 @@ const initialize = async () => { |
78 | 79 | const sd = song.songData || {} |
79 | 80 | const entry = { |
80 | 81 | songId: song.songId, |
81 | | - songData: sd, |
82 | 82 | name: song.name || sd.name || "Unknown", |
83 | 83 | primaryArtist: extractPrimaryArtist(sd), |
84 | 84 | allPrimaryArtists: extractAllPrimaryArtists(sd), |
@@ -107,6 +107,7 @@ const initialize = async () => { |
107 | 107 |
|
108 | 108 | initialized = true |
109 | 109 | initializing = false |
| 110 | + await cache.set("playnext:last_init", Date.now(), 0) |
110 | 111 | console.log( |
111 | 112 | `[PlayNext] Initialized: ${songMap.size} songs, ${artistMap.size} artists, ${labelMap.size} labels, ${languageMap.size} languages, ${albumMap.size} albums`, |
112 | 113 | ) |
@@ -238,7 +239,10 @@ const getPlayNextSongs = async ({ baseSongId, userId = null, limit = 20, exclude |
238 | 239 | return external.filter((s) => !excludeSet.has(s.id)).slice(0, limit) |
239 | 240 | } |
240 | 241 |
|
241 | | - if (!initialized) return [] |
| 242 | + if (!initialized) { |
| 243 | + initialize() |
| 244 | + return [] |
| 245 | + } |
242 | 246 |
|
243 | 247 | const baseSong = songMap.get(baseSongId) |
244 | 248 | if (!baseSong) { |
@@ -291,10 +295,19 @@ const getPlayNextSongs = async ({ baseSongId, userId = null, limit = 20, exclude |
291 | 295 | resultIds = personalized.map((p) => p.songId) |
292 | 296 | } |
293 | 297 |
|
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) |
298 | 311 | } |
299 | 312 |
|
300 | 313 | const rebuildAllPlayNext = async () => { |
@@ -343,7 +356,10 @@ const reload = async () => { |
343 | 356 | await initialize() |
344 | 357 | } |
345 | 358 |
|
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 | +}) |
347 | 363 |
|
348 | 364 | module.exports = { |
349 | 365 | initialize, |
|
0 commit comments