Pārlūkot izejas kodu

Improved job system concurrency, priorities, specifically for YouTube module

Kristian Vos 3 gadi atpakaļ
vecāks
revīzija
cd2ff2a66d

+ 17 - 9
backend/core.js

@@ -292,15 +292,22 @@ class MovingAverageCalculator {
 }
 
 export default class CoreClass {
-	// eslint-disable-next-line require-jsdoc
-	constructor(name) {
+	/**
+	 *
+	 * @param {string} name - the name of the class
+	 * @param {object} options - optional options
+	 * @param {number} options.concurrency - how many jobs can run at the same time
+	 * @param {object} options.priorities - custom priorities for jobs
+	 */
+	constructor(name, options) {
 		this.name = name;
 		this.status = "UNINITIALIZED";
 		// this.log("Core constructor");
-		this.jobQueue = new Queue((job, options) => this._runJob(job, options), 10);
+		this.concurrency = options && options.concurrency ? options.concurrency : 10;
+		this.jobQueue = new Queue((job, options) => this._runJob(job, options), this.concurrency);
 		this.jobQueue.pause();
 		this.runningJobs = [];
-		this.priorities = {};
+		this.priorities = options && options.priorities ? options.priorities : {};
 		this.stage = 0;
 		this.jobStatistics = {};
 
@@ -499,11 +506,12 @@ export default class CoreClass {
 
 		// if (options.bypassQueue) this._runJob(job, options, () => {});
 		// else {
-		const calculatedPriority = Math.min(
-			_priority || Infinity,
-			_parentJob ? _parentJob.task.priority : Infinity,
-			this.priorities[name] ? this.priorities[name] : 10
-		);
+		let calculatedPriority = null;
+		if (_priority) calculatedPriority = _priority;
+		else if (this.priorities[name]) calculatedPriority = this.priorities[name];
+		else if (_parentJob) calculatedPriority = _parentJob.task.priority;
+		else calculatedPriority = 10;
+
 		this.jobQueue.push(job, _options, calculatedPriority);
 
 		if (

+ 1 - 1
backend/logic/actions/playlists.js

@@ -697,7 +697,7 @@ export default {
 				);
 				return cb({
 					status: "success",
-					message: `Playlist has been imported. ${addSongsStats.successful} were addedd successfully, ${addSongsStats.failed} failed (${addSongsStats.alreadyInPlaylist} were already in the playlist)`,
+					message: `Playlist has been imported. ${addSongsStats.successful} were added successfully, ${addSongsStats.failed} failed (${addSongsStats.alreadyInPlaylist} were already in the playlist)`,
 					data: playlist.songs,
 					stats: {
 						videosInPlaylistTotal,

+ 5 - 6
backend/logic/actions/stations.js

@@ -112,13 +112,12 @@ CacheModule.runJob("SUB", {
 			StationsModule.runJob("GET_SOCKETS_THAT_CAN_KNOW_ABOUT_STATION", {
 				room: `home`,
 				station
-			})
-				.then(response => {
-					const { socketsThatCan } = response;
-					socketsThatCan.forEach(socket => {
-						socket.emit("event:station.pause", { stationId });
-					});
+			}).then(response => {
+				const { socketsThatCan } = response;
+				socketsThatCan.forEach(socket => {
+					socket.emit("event:station.pause", { stationId });
 				});
+			});
 		});
 	}
 });

+ 21 - 13
backend/logic/youtube.js

@@ -10,7 +10,12 @@ let YouTubeModule;
 class _YouTubeModule extends CoreClass {
 	// eslint-disable-next-line require-jsdoc
 	constructor() {
-		super("youtube");
+		super("youtube", {
+			concurrency: 1,
+			priorities: {
+				GET_PLAYLIST: 11
+			}
+		});
 
 		YouTubeModule = this;
 	}
@@ -135,17 +140,20 @@ class _YouTubeModule extends CoreClass {
 								next(null, nextPageToken !== undefined);
 							},
 							next => {
-								YouTubeModule.runJob("GET_PLAYLIST_PAGE", { playlistId, nextPageToken }, this)
-									// eslint-disable-next-line no-loop-func
-									.then(response => {
-										songs = songs.concat(response.songs);
-										nextPageToken = response.nextPageToken;
-										next();
-									})
-									// eslint-disable-next-line no-loop-func
-									.catch(err => {
-										next(err);
-									});
+								// Add 250ms delay between each job request
+								setTimeout(() => {
+									YouTubeModule.runJob("GET_PLAYLIST_PAGE", { playlistId, nextPageToken }, this)
+										// eslint-disable-next-line no-loop-func
+										.then(response => {
+											songs = songs.concat(response.songs);
+											nextPageToken = response.nextPageToken;
+											next();
+										})
+										// eslint-disable-next-line no-loop-func
+										.catch(err => {
+											next(err);
+										});
+								}, 250);
 							},
 							err => {
 								next(err, songs);
@@ -277,7 +285,7 @@ class _YouTubeModule extends CoreClass {
 					}
 				});
 
-				return YouTubeModule.runJob("FILTER_MUSIC_VIDEOS", { videoIds: payload.videoIds, page: page + 1 })
+				return YouTubeModule.runJob("FILTER_MUSIC_VIDEOS", { videoIds: payload.videoIds, page: page + 1 }, this)
 					.then(result => {
 						resolve({ songIds: songIds.concat(result.songIds) });
 					})