Skip to content

Instantly share code, notes, and snippets.

@xxshady
Last active May 28, 2024 20:02
Show Gist options
  • Save xxshady/c5be44c3aae2d70ab7a578f80f94df25 to your computer and use it in GitHub Desktop.
Save xxshady/c5be44c3aae2d70ab7a578f80f94df25 to your computer and use it in GitHub Desktop.
Saving clientside JS heap snaphot as file on alt:V
import alt from "alt-client"
const STRING_LIMIT = 2 ** 12
const sendSnapshot = async (string) => {
const len = string.length
const parts = Math.ceil(len / STRING_LIMIT)
alt.log("sendSnapshot", "parts:", parts, "len:", len)
let currentIdx = 0
for (let i = 0; i < parts; ++i) {
const end = currentIdx + STRING_LIMIT
const part = string.slice(currentIdx, end)
const partType = (currentIdx === 0)
? "start"
: (end > string.length ? "end" : "middle")
alt.emitServerRaw("snapshot", part, partType)
if (partType === "end") {
break
}
currentIdx = end
if (i % 1000 === 0) {
alt.log("sent", i)
await alt.Utils.wait(0)
}
}
}
new alt.Utils.ConsoleCommand("snapshot", async () => {
await sendSnapshot(await alt.Profiler.takeHeapSnapshot())
})
import alt from "alt-server"
import fs from "fs"
const pendingSnapshots = new WeakMap()
alt.onClient("snapshot", (player, data, part) => {
switch (part) {
case "start":
if (pendingSnapshots.has(player)) {
throw new Error("received start but its in pending")
}
pendingSnapshots.set(player, data)
break
case "middle":
{
let snapshot = pendingSnapshots.get(player)
if (!snapshot) {
throw new Error("received middle but its not in pending")
}
snapshot += data
pendingSnapshots.set(player, snapshot)
}
break
case "end":
{
let snapshot = pendingSnapshots.get(player)
if (!snapshot) {
throw new Error("received end but its not in pending")
}
pendingSnapshots.delete(player)
snapshot += data
alt.log("~gl~received end:", data.length)
alt.log("saving snapshot...")
fs.writeFileSync("snapshot.heapsnapshot", snapshot)
alt.log("~gl~saved snapshot")
}
break
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment