mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-02-19 00:18:56 +01:00
Add:Daily cron that closes stale open playback sessions
This commit is contained in:
parent
43217657d7
commit
fed5ff4863
@ -74,7 +74,7 @@ class Server {
|
|||||||
this.podcastManager = new PodcastManager(this.watcher, this.notificationManager)
|
this.podcastManager = new PodcastManager(this.watcher, this.notificationManager)
|
||||||
this.audioMetadataManager = new AudioMetadataMangaer()
|
this.audioMetadataManager = new AudioMetadataMangaer()
|
||||||
this.rssFeedManager = new RssFeedManager()
|
this.rssFeedManager = new RssFeedManager()
|
||||||
this.cronManager = new CronManager(this.podcastManager)
|
this.cronManager = new CronManager(this.podcastManager, this.playbackSessionManager)
|
||||||
this.apiCacheManager = new ApiCacheManager()
|
this.apiCacheManager = new ApiCacheManager()
|
||||||
this.binaryManager = new BinaryManager()
|
this.binaryManager = new BinaryManager()
|
||||||
|
|
||||||
|
@ -233,6 +233,7 @@ class ShareController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
playbackSession.currentTime = Math.min(currentTime, playbackSession.duration)
|
playbackSession.currentTime = Math.min(currentTime, playbackSession.duration)
|
||||||
|
playbackSession.updatedAt = Date.now()
|
||||||
Logger.debug(`[ShareController] Update share playback session ${req.cookies.share_session_id} currentTime: ${playbackSession.currentTime}`)
|
Logger.debug(`[ShareController] Update share playback session ${req.cookies.share_session_id} currentTime: ${playbackSession.currentTime}`)
|
||||||
res.sendStatus(204)
|
res.sendStatus(204)
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,14 @@ const Logger = require('../Logger')
|
|||||||
const Database = require('../Database')
|
const Database = require('../Database')
|
||||||
const LibraryScanner = require('../scanner/LibraryScanner')
|
const LibraryScanner = require('../scanner/LibraryScanner')
|
||||||
|
|
||||||
|
const ShareManager = require('./ShareManager')
|
||||||
|
|
||||||
class CronManager {
|
class CronManager {
|
||||||
constructor(podcastManager) {
|
constructor(podcastManager, playbackSessionManager) {
|
||||||
|
/** @type {import('./PodcastManager')} */
|
||||||
this.podcastManager = podcastManager
|
this.podcastManager = podcastManager
|
||||||
|
/** @type {import('./PlaybackSessionManager')} */
|
||||||
|
this.playbackSessionManager = playbackSessionManager
|
||||||
|
|
||||||
this.libraryScanCrons = []
|
this.libraryScanCrons = []
|
||||||
this.podcastCrons = []
|
this.podcastCrons = []
|
||||||
@ -19,10 +24,26 @@ class CronManager {
|
|||||||
* @param {import('../objects/Library')[]} libraries
|
* @param {import('../objects/Library')[]} libraries
|
||||||
*/
|
*/
|
||||||
async init(libraries) {
|
async init(libraries) {
|
||||||
|
this.initOpenSessionCleanupCron()
|
||||||
this.initLibraryScanCrons(libraries)
|
this.initLibraryScanCrons(libraries)
|
||||||
await this.initPodcastCrons()
|
await this.initPodcastCrons()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize open session cleanup cron
|
||||||
|
* Runs every day at 00:30
|
||||||
|
* Closes open share sessions that have not been updated in 24 hours
|
||||||
|
* Closes open playback sessions that have not been updated in 36 hours
|
||||||
|
* TODO: Clients should re-open the session if it is closed so that stale sessions can be closed sooner
|
||||||
|
*/
|
||||||
|
initOpenSessionCleanupCron() {
|
||||||
|
cron.schedule('30 0 * * *', async () => {
|
||||||
|
Logger.debug('[CronManager] Open session cleanup cron executing')
|
||||||
|
ShareManager.closeStaleOpenShareSessions()
|
||||||
|
await this.playbackSessionManager.closeStaleOpenSessions()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize library scan crons
|
* Initialize library scan crons
|
||||||
* @param {import('../objects/Library')[]} libraries
|
* @param {import('../objects/Library')[]} libraries
|
||||||
|
@ -21,6 +21,8 @@ class PlaybackSessionManager {
|
|||||||
this.StreamsPath = Path.join(global.MetadataPath, 'streams')
|
this.StreamsPath = Path.join(global.MetadataPath, 'streams')
|
||||||
|
|
||||||
this.oldPlaybackSessionMap = {} // TODO: Remove after updated mobile versions
|
this.oldPlaybackSessionMap = {} // TODO: Remove after updated mobile versions
|
||||||
|
|
||||||
|
/** @type {PlaybackSession[]} */
|
||||||
this.sessions = []
|
this.sessions = []
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,6 +348,10 @@ class PlaybackSessionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} sessionId
|
||||||
|
*/
|
||||||
async removeSession(sessionId) {
|
async removeSession(sessionId) {
|
||||||
const session = this.sessions.find((s) => s.id === sessionId)
|
const session = this.sessions.find((s) => s.id === sessionId)
|
||||||
if (!session) return
|
if (!session) return
|
||||||
@ -378,5 +384,18 @@ class PlaybackSessionManager {
|
|||||||
Logger.error(`[PlaybackSessionManager] cleanOrphanStreams failed`, error)
|
Logger.error(`[PlaybackSessionManager] cleanOrphanStreams failed`, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close all open sessions that have not been updated in the last 36 hours
|
||||||
|
*/
|
||||||
|
async closeStaleOpenSessions() {
|
||||||
|
const updatedAtTimeCutoff = Date.now() - 1000 * 60 * 60 * 36
|
||||||
|
const staleSessions = this.sessions.filter((session) => session.updatedAt < updatedAtTimeCutoff)
|
||||||
|
for (const session of staleSessions) {
|
||||||
|
const sessionLastUpdate = new Date(session.updatedAt)
|
||||||
|
Logger.info(`[PlaybackSessionManager] Closing stale session "${session.displayTitle}" (${session.id}) last updated at ${sessionLastUpdate}`)
|
||||||
|
await this.removeSession(session.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports = PlaybackSessionManager
|
module.exports = PlaybackSessionManager
|
||||||
|
@ -162,5 +162,18 @@ class ShareManager {
|
|||||||
destroyMediaItemShare(mediaItemShareId) {
|
destroyMediaItemShare(mediaItemShareId) {
|
||||||
return Database.models.mediaItemShare.destroy({ where: { id: mediaItemShareId } })
|
return Database.models.mediaItemShare.destroy({ where: { id: mediaItemShareId } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close open share sessions that have not been updated in the last 24 hours
|
||||||
|
*/
|
||||||
|
closeStaleOpenShareSessions() {
|
||||||
|
const updatedAtTimeCutoff = Date.now() - 1000 * 60 * 60 * 24
|
||||||
|
const staleSessions = this.openSharePlaybackSessions.filter((session) => session.updatedAt < updatedAtTimeCutoff)
|
||||||
|
for (const session of staleSessions) {
|
||||||
|
const sessionLastUpdate = new Date(session.updatedAt)
|
||||||
|
Logger.info(`[PlaybackSessionManager] Closing stale session "${session.displayTitle}" (${session.id}) last updated at ${sessionLastUpdate}`)
|
||||||
|
this.closeSharePlaybackSession(session)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports = new ShareManager()
|
module.exports = new ShareManager()
|
||||||
|
Loading…
Reference in New Issue
Block a user