Skip to content

Conversation

grgbkr
Copy link
Contributor

@grgbkr grgbkr commented May 6, 2023

Problem

Monday's revalidate connections cron is failing every time due to it exceeding memory limits. This is because the full list of connections is too large to fit in memory.

Solution

Refactor the two places where the AuthDO lists all connections (_authRevalidateConnections and _authInvalidateAll), to instead incrementally load the connections.

For _authRevalidateConnections we need to group the connections by roomID, since we revalidate connections a room at a time by fetching the room's current connections. To do this incrementally without having to iterate the entire list of connections incrementally for each room necessitates creating a new index by room id over the connections. To handle the creation of this index for existings AuthDO's, an AuthDO Storage Schema Version is introduced and stored in the AuthDO's storage at key auth_do_storage_schema_version. The AuthDO ensures the storage schema version is upgraded to the current version before processing any fetch.

Fixes #487

@vercel
Copy link

vercel bot commented May 6, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
replicache-docs-trunk ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 8, 2023 5:21pm

@grgbkr grgbkr requested review from aboodman and arv May 6, 2023 19:38
@grgbkr grgbkr marked this pull request as ready for review May 6, 2023 19:39
Copy link
Contributor

@aboodman aboodman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to be such a common need that it might be useful to just implement a general purpose index facility. I suppose it could be abstracted out later though.

}

const CONNECTION_KEY_PREFIX = 'connection/';
const CONNECTION_ROOM_INDEX_PREFIX = 'connection_room/';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like connections_by_room would be a more immediately obvious name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree. done.

return `${CONNECTION_KEY_PREFIX}${encodeURIComponent(userID)}/`;
}

function connectionKeyToConnectionRoomIndexString(key: ConnectionKey): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you purposely end it with /?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was just keeping this consistent with what I did for the connectionKeyToString and I can't remember why I ended that with slash.

}

function connectionKeyToConnectionRoomIndexString(key: ConnectionKey): string {
return `${CONNECTION_ROOM_INDEX_PREFIX}${encodeURIComponent(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, but you could use the below function inside this function to ensure they remain in sync.

Copy link
Contributor Author