From 71753cbd44dcc23c5def41a17b0e279eeccd8210 Mon Sep 17 00:00:00 2001 From: Tobiah Date: Tue, 20 Oct 2020 17:23:02 +0000 Subject: [PATCH] fix: process per-shard instead of all shards at once --- .eslintrc.json | 33 --------- package.json | 37 +++++++++- src/embeds/DarvoEmbed.js | 11 +-- src/embeds/FrameEmbed.js | 2 +- src/embeds/WeaponEmbed.js | 2 +- src/notifications/Broadcaster.js | 72 +++++++++----------- src/notifications/TwitchNotifier.js | 4 +- src/resources/emoji.json | 3 +- src/settings/DatabaseQueries/PingsQueries.js | 8 +-- 9 files changed, 81 insertions(+), 91 deletions(-) delete mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 49f3fb72d..000000000 --- a/.eslintrc.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "extends": "airbnb-base", - "parserOptions": { - "sourceType": "script" - }, - "rules": { - "valid-jsdoc": ["error", - { - "requireReturn": false, - "requireReturnDescription": false, - "preferType": { - "String": "string", - "Number": "number", - "Boolean": "boolean", - "Function": "function", - "object": "Object", - "date": "Date", - "error": "Error" - }, - "prefer": { - "return": "returns" - } - }], - "strict": ["error", "safe"], - "linebreak-style": "off", - "no-restricted-syntax": ["off"], - "no-await-in-loop": "off", - "import/no-unresolved": 0, - "no-useless-escape": 0, - "arrow-parens": [2, "as-needed", { "requireForBlockBody": true }], - "global-require": 0 - } -} diff --git a/package.json b/package.json index ac3facc9b..1579e5d02 100644 --- a/package.json +++ b/package.json @@ -78,5 +78,40 @@ "engines": { "node": ">=12.16.1" }, - "snyk": true + "snyk": true, + "eslintConfig": { + "extends": "airbnb-base", + "parserOptions": { + "sourceType": "script" + }, + "rules": { + "valid-jsdoc": ["error", + { + "requireReturn": false, + "requireReturnDescription": false, + "preferType": { + "String": "string", + "Number": "number", + "Boolean": "boolean", + "Function": "function", + "object": "Object", + "date": "Date", + "error": "Error" + }, + "prefer": { + "return": "returns" + } + }], + "strict": ["error", "safe"], + "linebreak-style": "off", + "no-restricted-syntax": ["off"], + "no-await-in-loop": "off", + "import/no-unresolved": 0, + "no-useless-escape": 0, + "arrow-parens": [2, "as-needed", { "requireForBlockBody": true }], + "global-require": 0, + "no-param-reassign": "off", + "no-continue": "off" + } + } } diff --git a/src/embeds/DarvoEmbed.js b/src/embeds/DarvoEmbed.js index e61dcbc23..aa426b436 100644 --- a/src/embeds/DarvoEmbed.js +++ b/src/embeds/DarvoEmbed.js @@ -5,15 +5,7 @@ const { assetBase } = require('../CommonFunctions'); const darvo = `${assetBase}/img/darvo-md.png`; -/** - * Generates daily deal embeds - */ class DarvoEmbed extends BaseEmbed { - /** - * @param {Genesis} bot - An instance of Genesis - * @param {DailyDeal} deal - The deal to be included in the embed - * @param {string} platform - platform - */ constructor(bot, deal, platform) { super(); @@ -24,10 +16,11 @@ class DarvoEmbed extends BaseEmbed { }; this.fields = [ { - name: `${deal.item}, ${deal.salePrice}p - ${deal.total - deal.sold}/${deal.total} left`, + name: `${deal.item}, ${deal.salePrice}p`, value: `Original price: ${deal.originalPrice}p, expires in ${deal.eta}`, }, ]; + this.footer.text = `${deal.total - deal.sold}/${deal.total} left`; } } diff --git a/src/embeds/FrameEmbed.js b/src/embeds/FrameEmbed.js index 97744f48d..15883ef54 100644 --- a/src/embeds/FrameEmbed.js +++ b/src/embeds/FrameEmbed.js @@ -39,7 +39,7 @@ class FrameEmbed extends BaseEmbed { } : false, { name: 'Minimum Mastery', - value: frame.masteryReq || 'N/A', + value: `${frame.masteryReq || 'N/A'} ${emojify('mastery_rank')}`, inline: true, }, { diff --git a/src/embeds/WeaponEmbed.js b/src/embeds/WeaponEmbed.js index 476ed62f0..02603fb04 100644 --- a/src/embeds/WeaponEmbed.js +++ b/src/embeds/WeaponEmbed.js @@ -20,7 +20,7 @@ class WeaponEmbed extends BaseEmbed { this.title = weapon.name; this.url = weapon.wikiaUrl || ''; this.thumbnail = { url: weapon.wikiaThumbnail || '' }; - this.description = `${weapon.type} ${`• MR ${weapon.masteryReq}`}`; + this.description = `${weapon.type} • ${weapon.masteryReq} ${emojify('mastery_rank')}`; this.color = weapon.color || 0x7C0A02; this.fields = []; diff --git a/src/notifications/Broadcaster.js b/src/notifications/Broadcaster.js index 48be70dc7..feb34e19f 100644 --- a/src/notifications/Broadcaster.js +++ b/src/notifications/Broadcaster.js @@ -1,5 +1,7 @@ 'use strict'; +const logger = require('../Logger'); + /** * Broadcast updates out to subscribing channels * @param {Discord.Client} client bot client @@ -13,54 +15,46 @@ class Broadcaster { }) { this.client = client; this.settings = settings; - this.messageManager = messageManager; + this.webhook = messageManager.webhook; + this.wrap = messageManager.webhookWrapEmbed; + this.shards = Number.parseInt(process.env.SHARDS || '1', 10); } /** - * Broadcast embed to all channels for a platform and type - * @param {Object} embed Embed to send to a channel - * @param {string} platform Platform of worldstate - * @param {string} type Type of new data to notify - * @param {Array} [items=[]] Items to broadcast - * @returns {Array.} values for successes - */ + * Broadcast embed to all channels for a platform and type + * @param {Object} embed Embed to send to a channel + * @param {string} platform Platform of worldstate + * @param {string} type Type of new data to notify + * @param {Array} [items=[]] Items to broadcast + * @returns {Array.} values for successes + */ async broadcast(embed, platform, type, items = []) { - const channels = await this.settings.getNotifications(type, platform, items); - embed.bot = undefined; // eslint-disable-line no-param-reassign - + delete embed.bot; const guilds = await this.settings.getGuilds(); - return Promise.all(channels.map(async (result) => { - // need some way to do this other than getting all channels.... - // let's try looping over a list of ids - const ctx = await this.settings.getCommandContext(result.channelId); - - if (embed.locale && ctx.language.toLowerCase() !== embed.locale.toLowerCase()) { - return false; - } - - let guild; - - Object.entries(guilds).forEach(([, g]) => { - if (g.channels.includes(result.channelId)) { - guild = g; + for (let shard = 0; shard < this.shards; shard += 1) { + const channels = await this.settings + .getAgnosticNotifications(type, platform, items, { shard, shards: this.shards }); + for (const result of channels) { + const ctx = await this.settings.getCommandContext(result.channelId); + if (embed.locale && ctx.language.toLowerCase() !== embed.locale.toLowerCase()) { + continue; } - }); - - const prepend = await this.settings.getPing(guild, (items || []).concat([type])); - if (!embed.embeds) { - return this.messageManager.webhook( - ctx, - { text: prepend, embed: this.messageManager.webhookWrapEmbed(embed, ctx) }, - ); + const guild = Object.entries(guilds) + .filter(([, g]) => g.channels.includes(result.channelId))[0]; + try { + const prepend = await this.settings.getPing(guild, (items || []).concat([type])); + if (!embed.embeds) { + await this.webhook(ctx, { text: prepend, embed: this.wrap(embed, ctx) }); + } else { + await this.webhook(ctx, { text: prepend, embed }); + } + } catch (e) { + logger.error(e); + } } - - return this.messageManager.webhook( - ctx, - { text: prepend, embed }, - ); - })); + } } } diff --git a/src/notifications/TwitchNotifier.js b/src/notifications/TwitchNotifier.js index 60f0da6b2..847872473 100644 --- a/src/notifications/TwitchNotifier.js +++ b/src/notifications/TwitchNotifier.js @@ -1,6 +1,6 @@ 'use strict'; -const TwitchClient = require('twitch').default; +const { ApiClient } = require('twitch'); const WebHookListener = require('twitch-webhooks').default; const TwitchEmbed = require('../embeds/TwitchEmbed'); @@ -26,7 +26,7 @@ class TwitchNotifier { if (process.env.TWITCH_CLIENT_ID && process.env.TWITCH_CLIENT_SECRET) { const id = process.env.TWITCH_CLIENT_ID; const secret = process.env.TWITCH_CLIENT_SECRET; - this.client = TwitchClient.withClientCredentials(id, secret); + this.client = ApiClient.withClientCredentials(id, secret); } else { logger.debug('[Twitch] Cannot initialize Twitch Notifier... invalid credentials'); } diff --git a/src/resources/emoji.json b/src/resources/emoji.json index 981f6605a..4687142e2 100644 --- a/src/resources/emoji.json +++ b/src/resources/emoji.json @@ -26,5 +26,6 @@ "credits": "<:credits:668499068342763573>", "ducats": "<:ducats:668499069169041420>", "green_tick": "<:green_tick:326794577006690305>", - "red_tick":"<:red_tick:326794577426251796>" + "red_tick":"<:red_tick:326794577426251796>", + "mastery_rank": "<:mastery:768133694253826084>" } diff --git a/src/settings/DatabaseQueries/PingsQueries.js b/src/settings/DatabaseQueries/PingsQueries.js index 3879043cd..1fbe18ee1 100644 --- a/src/settings/DatabaseQueries/PingsQueries.js +++ b/src/settings/DatabaseQueries/PingsQueries.js @@ -103,9 +103,6 @@ class PingsQueries { * @returns {Promise.>} */ async getNotifications(type, platform, items) { - if (this.scope === 'worker') { - return this.getAgnosticNotifications(type, platform, items); - } try { const query = SQL`SELECT DISTINCT channels.id as channelId FROM type_notifications` @@ -131,9 +128,11 @@ class PingsQueries { * @param {string} type The type of the event * @param {string} platform The platform of the event * @param {Array.} items The items in the reward that is being notified + * @param {number} shard Shard id to notify + * @param {number} shards Total number of shards * @returns {Promise.>} */ - async getAgnosticNotifications(type, platform, items) { + async getAgnosticNotifications(type, platform, items, { shard, shards }) { if (this.scope !== 'worker') { return this.getNotifications(type, platform, items); } @@ -146,6 +145,7 @@ class PingsQueries { .append(SQL` INNER JOIN settings ON channels.id = settings.channel_id`) .append(SQL` WHERE type_notifications.type = ${String(type)} + AND MOD(IFNULL(channels.guild_id, 0) >> 22, ${shards}) = ${shard} AND settings.setting = "platform" AND (settings.val = ${platform || 'pc'} OR settings.val IS NULL) `) .append(items && items.length ? SQL`AND item_notifications.item IN (${items}) AND item_notifications.channel_id = settings.channel_id;` : SQL`;`);