Browse Source

refactor(Stations): Moved vote skip processing to own job that holds voting to skip when station paused

Owen Diffey 2 years ago
parent
commit
5286844704
2 changed files with 102 additions and 48 deletions
  1. 10 48
      backend/logic/actions/stations.js
  2. 92 0
      backend/logic/stations.js

+ 10 - 48
backend/logic/actions/stations.js

@@ -1174,9 +1174,6 @@ export default {
 	voteSkip: isLoginRequired(async function voteSkip(session, stationId, cb) {
 		const stationModel = await DBModule.runJob("GET_MODEL", { modelName: "station" }, this);
 
-		let skipVotes = 0;
-		let shouldSkip = false;
-
 		async.waterfall(
 			[
 				next => {
@@ -1220,43 +1217,10 @@ export default {
 
 				(station, next) => {
 					if (!station) return next("Station not found.");
-					return next(null, station);
-				},
 
-				(station, next) => {
-					skipVotes = station.currentSong.skipVotes.length;
-					WSModule.runJob("GET_SOCKETS_FOR_ROOM", { room: `station.${stationId}` }, this)
-						.then(sockets => next(null, sockets))
+					return StationsModule.runJob("PROCESS_VOTE_SKIPS", { stationId }, this)
+						.then(() => next())
 						.catch(next);
-				},
-
-				(sockets, next) => {
-					if (sockets.length <= skipVotes) {
-						shouldSkip = true;
-						return next();
-					}
-
-					const users = [];
-
-					return async.each(
-						sockets,
-						(socketId, next) => {
-							WSModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }, this)
-								.then(socket => {
-									if (socket && socket.session && socket.session.userId) {
-										if (!users.includes(socket.session.userId)) users.push(socket.session.userId);
-									}
-									return next();
-								})
-								.catch(next);
-						},
-						err => {
-							if (err) return next(err);
-
-							if (users.length <= skipVotes) shouldSkip = true;
-							return next();
-						}
-					);
 				}
 			],
 			async err => {
@@ -1272,10 +1236,6 @@ export default {
 					value: stationId
 				});
 
-				if (shouldSkip) {
-					StationsModule.runJob("SKIP_STATION", { stationId, natural: false });
-				}
-
 				return cb({
 					status: "success",
 					message: "Successfully voted to skip the song."
@@ -1505,9 +1465,7 @@ export default {
 
 				(res, next) => {
 					StationsModule.runJob("UPDATE_STATION", { stationId }, this)
-						.then(station => {
-							next(null, station);
-						})
+						.then(() => next())
 						.catch(next);
 				}
 			],
@@ -1574,9 +1532,13 @@ export default {
 
 				(res, next) => {
 					StationsModule.runJob("UPDATE_STATION", { stationId }, this)
-						.then(station => {
-							next(null, station);
-						})
+						.then(() => next())
+						.catch(next);
+				},
+
+				next => {
+					StationsModule.runJob("PROCESS_VOTE_SKIPS", { stationId }, this)
+						.then(() => next())
 						.catch(next);
 				}
 			],

+ 92 - 0
backend/logic/stations.js

@@ -708,6 +708,98 @@ class _StationsModule extends CoreClass {
 		});
 	}
 
+	/**
+	 * Process vote to skips for a station
+	 *
+	 * @param {object} payload - object that contains the payload
+	 * @param {string} payload.stationId - the id of the station to process
+	 * @returns {Promise} - returns a promise (resolve, reject)
+	 */
+	PROCESS_VOTE_SKIPS(payload) {
+		return new Promise((resolve, reject) => {
+			StationsModule.log("INFO", `Processing vote skips for station ${payload.stationId}.`);
+
+			async.waterfall(
+				[
+					next => {
+						StationsModule.runJob(
+							"GET_STATION",
+							{
+								stationId: payload.stationId
+							},
+							this
+						)
+							.then(station => next(null, station))
+							.catch(next);
+					},
+
+					(station, next) => {
+						if (!station) return next("Station not found.");
+						return next(null, station);
+					},
+
+					(station, next) => {
+						WSModule.runJob("GET_SOCKETS_FOR_ROOM", { room: `station.${station._id}` }, this)
+							.then(sockets => next(null, station, sockets))
+							.catch(next);
+					},
+
+					(station, sockets, next) => {
+						const skipVotes = station.currentSong.skipVotes.length;
+						let shouldSkip = false;
+
+						if (sockets.length <= skipVotes) {
+							if (!station.paused) shouldSkip = true;
+							return next(null, shouldSkip);
+						}
+
+						const users = [];
+
+						return async.each(
+							sockets,
+							(socketId, next) => {
+								WSModule.runJob("SOCKET_FROM_SOCKET_ID", { socketId }, this)
+									.then(socket => {
+										if (socket && socket.session && socket.session.userId) {
+											if (!users.includes(socket.session.userId))
+												users.push(socket.session.userId);
+										}
+										return next();
+									})
+									.catch(next);
+							},
+							err => {
+								if (err) return next(err);
+
+								if (!station.paused && users.length <= skipVotes) shouldSkip = true;
+								return next(null, shouldSkip);
+							}
+						);
+					},
+
+					(shouldSkip, next) => {
+						if (shouldSkip)
+							StationsModule.runJob(
+								"SKIP_STATION",
+								{
+									stationId: payload.stationId,
+									natural: false
+								},
+								this
+							)
+								.then(() => next())
+								.catch(next);
+						else next();
+					}
+				],
+				err => {
+					if (err) reject(err);
+					else resolve();
+				}
+			);
+		});
+	}
+
 	/**
 	 * Skips a station
 	 *