Changeset View
Standalone View
keyserver/src/push/send.js
Show All 27 Lines | import { | ||||
type MessageInfo, | type MessageInfo, | ||||
messageTypes, | messageTypes, | ||||
} from 'lib/types/message-types.js'; | } from 'lib/types/message-types.js'; | ||||
import type { ServerThreadInfo, ThreadInfo } from 'lib/types/thread-types.js'; | import type { ServerThreadInfo, ThreadInfo } from 'lib/types/thread-types.js'; | ||||
import { updateTypes } from 'lib/types/update-types.js'; | import { updateTypes } from 'lib/types/update-types.js'; | ||||
import { promiseAll } from 'lib/utils/promises.js'; | import { promiseAll } from 'lib/utils/promises.js'; | ||||
import { getAPNsNotificationTopic } from './providers.js'; | import { getAPNsNotificationTopic } from './providers.js'; | ||||
import { rescindPushNotifs } from './rescind.js'; | |||||
import { | import { | ||||
apnPush, | apnPush, | ||||
fcmPush, | fcmPush, | ||||
getUnreadCounts, | getUnreadCounts, | ||||
apnMaxNotificationPayloadByteSize, | apnMaxNotificationPayloadByteSize, | ||||
fcmMaxNotificationPayloadByteSize, | fcmMaxNotificationPayloadByteSize, | ||||
} from './utils.js'; | } from './utils.js'; | ||||
import createIDs from '../creators/id-creator.js'; | import createIDs from '../creators/id-creator.js'; | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | async function sendPushNotifs(pushInfo: PushInfo) { | ||||
const [deliveryResults] = await Promise.all([ | const [deliveryResults] = await Promise.all([ | ||||
Promise.all(deliveryPromises), | Promise.all(deliveryPromises), | ||||
Promise.all(cleanUpPromises), | Promise.all(cleanUpPromises), | ||||
]); | ]); | ||||
await saveNotifResults(deliveryResults, notifications, true); | await saveNotifResults(deliveryResults, notifications, true); | ||||
} | } | ||||
async function sendRescindNotifs(rescindInfo: PushInfo) { | |||||
if (Object.keys(rescindInfo).length === 0) { | |||||
return; | |||||
} | |||||
const [{ usersToCollapsableNotifInfo }] = await Promise.all([ | |||||
ashoat: What is `Promise.all` doing here? | |||||
fetchInfos(rescindInfo), | |||||
ashoatUnsubmitted Not Done Inline ActionsYou are calling fetchInfos, but only looking at usersToCollapsableNotifInfo. Why aren't you calling fetchCollapsableNotifs instead? This is a lot of wasted work... ashoat: You are calling `fetchInfos`, but only looking at `usersToCollapsableNotifInfo`. Why aren't you… | |||||
]); | |||||
const promises = []; | |||||
for (const userID in usersToCollapsableNotifInfo) { | |||||
for (const notifInfo of usersToCollapsableNotifInfo[userID]) { | |||||
if (notifInfo.existingMessageInfos.length === 0) { | |||||
ashoatUnsubmitted Not Done Inline ActionsWhat does this condition do? ashoat: What does this condition do? | |||||
ginsuAuthorUnsubmitted Done Inline ActionsI was trying to keep consistent with the sendPushNotifs function above, and sendPushNotifs had a similar condition. However, after taking second look it is unnecessary here since we will never enter the loop below if notifInfo.existingMessageInfos.length === 0. ginsu: I was trying to keep consistent with the `sendPushNotifs` function above, and `sendPushNotifs`… | |||||
continue; | |||||
} | |||||
for (const existingMessageInfo of notifInfo.existingMessageInfos) { | |||||
const rescindCondition = SQL` | |||||
n.user = ${userID} AND | |||||
n.thread = ${existingMessageInfo.threadID} AND | |||||
n.message = ${existingMessageInfo.id} | |||||
`; | |||||
const inputCountCondition = SQL` | |||||
IF(m.thread = ${existingMessageInfo.threadID}, NULL, m.thread) | |||||
ashoatUnsubmitted Not Done Inline ActionsIt appears like you're assuming that the thread is read now, but I'm not sure why you're making that assumption. At a baseline we know from ENG-3066 that this is not true in terms of what MySQL thinks. Even if that task was addressed, we still have no guaranteed that this thread should be considered "read" after this notif is rescinded. Eg. if somebody likes a message, then somebody else sends a message, and finally the original liker unlikes... in that scenario, why are we concluding that this thread is now read? ashoat: It appears like you're assuming that the thread is read now, but I'm not sure why you're making… | |||||
ginsuAuthorUnsubmitted Done Inline ActionsI intially thought this would be something that we would preemptively need for ENG-3066, but after reading the example you provided above, and rethinking this, my initial assumption is incorrect ginsu: I intially thought this would be something that we would preemptively need for ENG-3066, but… | |||||
`; | |||||
promises.push(rescindPushNotifs(rescindCondition, inputCountCondition)); | |||||
} | |||||
} | |||||
} | |||||
await Promise.all(promises); | |||||
} | |||||
// The results in deliveryResults will be combined with the rows | // The results in deliveryResults will be combined with the rows | ||||
// in rowsToSave and then written to the notifications table | // in rowsToSave and then written to the notifications table | ||||
async function saveNotifResults( | async function saveNotifResults( | ||||
deliveryResults: $ReadOnlyArray<IOSResult | AndroidResult>, | deliveryResults: $ReadOnlyArray<IOSResult | AndroidResult>, | ||||
inputRowsToSave: Map<string, NotificationRow>, | inputRowsToSave: Map<string, NotificationRow>, | ||||
rescindable: boolean, | rescindable: boolean, | ||||
) { | ) { | ||||
const rowsToSave = new Map(inputRowsToSave); | const rowsToSave = new Map(inputRowsToSave); | ||||
▲ Show 20 Lines • Show All 580 Lines • ▼ Show 20 Lines | for (const [codeVer, deviceTokens] of androidVersionsToTokens) { | ||||
); | ); | ||||
} | } | ||||
} | } | ||||
const deliveryResults = await Promise.all(deliveryPromises); | const deliveryResults = await Promise.all(deliveryPromises); | ||||
await saveNotifResults(deliveryResults, new Map(), false); | await saveNotifResults(deliveryResults, new Map(), false); | ||||
} | } | ||||
export { sendPushNotifs, updateBadgeCount }; | export { sendPushNotifs, sendRescindNotifs, updateBadgeCount }; |
What is Promise.all doing here?