refactor: responder... responds, elegance

This commit is contained in:
cha0s 2020-07-22 03:47:16 -05:00
parent 0ca11a0ec4
commit cc6d4e6250
12 changed files with 65 additions and 58 deletions

View File

@ -4,11 +4,10 @@ import {allModels} from '~/server/models/registrar';
export default { export default {
Packet: AddFavorite, Packet: AddFavorite,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
await req.user.createFavorite({channel: packet.data}); await req.user.createFavorite({channel: packet.data});
socket.to(`/user/${req.userId}`, packet); socket.to(`/user/${req.userId}`, packet);
fn();
}, },
}; };

View File

@ -1,21 +1,29 @@
import {validateUsername} from '~/common/channel';
import AddFriend from '~/common/packets/add-friend.packet'; import AddFriend from '~/common/packets/add-friend.packet';
import {allModels} from '~/server/models/registrar'; import {allModels} from '~/server/models/registrar';
import ValidationError from './validation-error';
export default { export default {
Packet: AddFriend, Packet: AddFriend,
validator: () => true, limiter: {points: 20, duration: 60},
responder: async (packet, socket, fn) => { validator: async ({data: {nameOrStatus}}) => {
if (!validateUsername(nameOrStatus)) {
throw new ValidationError('Invalid username');
}
},
responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
const { const {
Friendship, Friendship,
User, User,
} = allModels(); } = allModels();
const adderId = req.user.id; const adderId = req.user.id;
const user = await User.findOne({where: {redditUsername: packet.data.nameOrStatus}}); const user = (
if (!user) { await User.findOne({where: {redditUsername: packet.data.nameOrStatus}})
return; || await User.create({redditUsername: packet.data.nameOrStatus})
} );
const addeeId = user.id; const addeeId = user.id;
let friendship = await Friendship.findOne({where: {adderId: addeeId, addeeId: adderId}}); let friendship = await Friendship.findOne({where: {adderId: addeeId, addeeId: adderId}});
const friendshipIsActive = !!friendship; const friendshipIsActive = !!friendship;
@ -33,6 +41,6 @@ export default {
nameOrStatus: friendship.status, nameOrStatus: friendship.status,
})); }));
}); });
fn(addeeId); return addeeId;
}, },
}; };

View File

@ -9,8 +9,8 @@ import {removeFavoritedUser} from './remove-favorite';
export default { export default {
Packet: Block, Packet: Block,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
const id = packet.data; const id = packet.data;
const {Friendship, User} = allModels(); const {Friendship, User} = allModels();
@ -29,6 +29,5 @@ export default {
socket.to(`/user/${req.userId}`, packet); socket.to(`/user/${req.userId}`, packet);
socket.to(`/user/${id}`, new RemoveFriend(req.userId)); socket.to(`/user/${id}`, new RemoveFriend(req.userId));
socket.to(`/user/${req.userId}`, new RemoveFriend(id)); socket.to(`/user/${req.userId}`, new RemoveFriend(id));
fn();
}, },
}; };

View File

@ -21,11 +21,11 @@ export const userJoin = async (channel, socket) => {
export default { export default {
Packet: Join, Packet: Join,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
const {channel} = packet.data; const {channel} = packet.data;
await userJoin(channel, socket.socket); await userJoin(channel, socket.socket);
fn(await channelState(req, channel)); return channelState(req, channel);
}, },
}; };

View File

@ -16,10 +16,9 @@ export const userLeave = async (channel, socket) => {
export default { export default {
Packet: Leave, Packet: Leave,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {channel} = packet.data; const {channel} = packet.data;
await userLeave(channel, socket); return userLeave(channel, socket);
fn();
}, },
}; };

View File

@ -8,7 +8,7 @@ import {allModels} from '~/server/models/registrar';
export default { export default {
Packet: Message, Packet: Message,
limiter: {points: 10, duration: 15}, limiter: {points: 10, duration: 15},
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket, fn) => {
const {req} = socket; const {req} = socket;
const {pubClient} = req.adapter; const {pubClient} = req.adapter;
@ -35,15 +35,17 @@ export default {
uuid, uuid,
})) }))
)); ));
pubClient return new Promise((resolve, reject) => {
.multi() pubClient
.set(key, JSON.stringify({ .multi()
message, .set(key, JSON.stringify({
owner, message,
socket: socket.id, owner,
timestamp, socket: socket.id,
})) timestamp,
.expire(key, '/r/anonymous' === channel ? 60 : 600) }))
.exec(() => fn([timestamp, uuid])); .expire(key, '/r/anonymous' === channel ? 60 : 600)
.exec((error) => (error ? reject(error) : resolve([timestamp, uuid])));
});
}, },
}; };

View File

@ -18,8 +18,8 @@ export const removeFavoritedUser = async (socket, user, other) => {
export default { export default {
Packet: RemoveFavorite, Packet: RemoveFavorite,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
const {Favorite} = allModels(); const {Favorite} = allModels();
const favorites = await req.user.getFavorites(); const favorites = await req.user.getFavorites();
@ -30,6 +30,5 @@ export default {
}, },
}); });
socket.to(`/user/${req.userId}`, packet); socket.to(`/user/${req.userId}`, packet);
fn(); },
},
}; };

View File

@ -8,8 +8,8 @@ import {removeFavoritedUser} from './remove-favorite';
export default { export default {
Packet: RemoveFriend, Packet: RemoveFriend,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
const id = packet.data; const id = packet.data;
const {Friendship, User} = allModels(); const {Friendship, User} = allModels();
@ -26,6 +26,5 @@ export default {
const user = await User.findByPk(id); const user = await User.findByPk(id);
removeFavoritedUser(socket, user, req.user); removeFavoritedUser(socket, user, req.user);
removeFavoritedUser(socket, req.user, user); removeFavoritedUser(socket, req.user, user);
fn();
}, },
}; };

View File

@ -4,8 +4,8 @@ import {allModels} from '~/server/models/registrar';
export default { export default {
Packet: Unblock, Packet: Unblock,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet, socket) => {
const {req} = socket; const {req} = socket;
const {Block: BlockModel} = allModels(); const {Block: BlockModel} = allModels();
await BlockModel.destroy({ await BlockModel.destroy({
@ -15,6 +15,5 @@ export default {
}, },
}); });
socket.to(`/user/${req.userId}`, packet); socket.to(`/user/${req.userId}`, packet);
fn();
}, },
}; };

View File

@ -4,11 +4,11 @@ import {allModels} from '~/server/models/registrar';
export default { export default {
Packet: Usernames, Packet: Usernames,
validator: () => true, validator: async () => true,
responder: async (packet, socket, fn) => { responder: async (packet) => {
const {User} = allModels(); const {User} = allModels();
fn(await Promise.all(packet.data.map( return Promise.all(packet.data.map(
async (id) => (await User.findByPk(id)).redditUsername, async (id) => (await User.findByPk(id)).redditUsername,
))); ));
}, },
}; };

View File

@ -0,0 +1 @@
export default class ValidationError extends Error {}

View File

@ -63,22 +63,24 @@ export function createSocketServer(httpServer) {
}); });
socketServer.on('connect', (socket) => { socketServer.on('connect', (socket) => {
socket.on('packet', async (packet, fn) => { socket.on('packet', async (packet, fn) => {
const {limiter, responder} = packetHandlers.get(packet.constructor); const {limiter, responder, validator} = packetHandlers.get(packet.constructor);
if (limiter) { try {
try { if (limiter) {
await limiter.consume(socket.id); await limiter.consume(socket.id);
responder(packet, socket, (...args) => fn(undefined, ...args));
}
catch (error) {
if (error instanceof Error) {
fn({code: 500});
throw error;
}
fn({code: 429, ttr: Math.round(error.msBeforeNext / 1000) || 1});
} }
await validator(packet, socket);
fn(undefined, await responder(packet, socket));
} }
else { catch (error) {
responder(packet, socket, (...args) => fn(undefined, ...args)); if (error instanceof Error) {
fn({code: 500});
throw error;
}
if (error.msBeforeNext) {
fn({code: 429, ttr: Math.round(error.msBeforeNext / 1000) || 1});
return;
}
fn(error);
} }
}); });
socket.on('disconnecting', async () => { socket.on('disconnecting', async () => {