Merge pull request #2024 from PR0M3TH3AN/perf/parallel-zap-retries-1778136069971316397

⚡ Parallelize Zap Retry Execution
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-01-31 14:40:51 -05:00
commit e3af6e140d
4 files changed
+65 -69

No files matched your search

+40 -45
View File
@@ -2795,23 +2795,13 @@ async function runZapAttempt({ amount, overrideFee = null, walletSettings }) {
});
const videoEvent = getZapVideoEvent();
let previousOverride;
const hasGlobal = typeof globalThis !== "undefined";
if (
hasGlobal &&
typeof overrideFee === "number" &&
Number.isFinite(overrideFee)
) {
previousOverride = globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__;
globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__ = overrideFee;
}
try {
const result = await splitAndZap(
{
videoEvent,
amountSats: context.shares.total,
walletSettings: settings
walletSettings: settings,
overrideFee
},
dependencies
);
@@ -2832,21 +2822,6 @@ async function runZapAttempt({ amount, overrideFee = null, walletSettings }) {
error
);
throw error;
} finally {
if (
hasGlobal &&
typeof overrideFee === "number" &&
Number.isFinite(overrideFee)
) {
if (typeof previousOverride === "number") {
globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__ = previousOverride;
} else if (
globalThis &&
"__BITVID_PLATFORM_FEE_OVERRIDE__" in globalThis
) {
delete globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__;
}
}
}
}
@@ -2873,25 +2848,37 @@ async function executePendingRetry({ walletSettings }) {
const aggregatedReceipts = [];
const aggregatedTracker = [];
const nextRetryShares = [];
let lastError = null;
for (const share of shares) {
const overrideFee = share.type === "platform" ? 100 : 0;
try {
const attempt = await runZapAttempt({
const results = await Promise.allSettled(
shares.map((share) => {
const overrideFee = share.type === "platform" ? 100 : 0;
return runZapAttempt({
amount: share.amount,
overrideFee,
walletSettings
});
})
);
for (let i = 0; i < results.length; i++) {
const result = results[i];
const share = shares[i];
if (result.status === "fulfilled") {
const attempt = result.value;
if (!attempt) {
setZapStatus("", "neutral");
return;
continue;
}
if (attempt?.result?.receipts) {
aggregatedReceipts.push(...attempt.result.receipts);
} else if (Array.isArray(attempt?.shareTracker)) {
aggregatedTracker.push(...attempt.shareTracker);
}
} catch (error) {
} else {
const error = result.reason;
lastError = error;
const tracker = Array.isArray(error?.__zapShareTracker)
? error.__zapShareTracker
: [];
@@ -2912,20 +2899,28 @@ async function executePendingRetry({ walletSettings }) {
const failureShares = tracker.filter(
(entry) => entry && entry.status !== "success" && entry.amount > 0
);
markZapRetryPending(failureShares.length ? failureShares : [share]);
const message = error?.message || "Retry failed.";
setZapStatus(message, "error");
app?.showError?.(message);
renderZapReceipts(
aggregatedTracker.length ? aggregatedTracker : tracker,
{
partial: true
}
);
return;
if (failureShares.length) {
nextRetryShares.push(...failureShares);
} else {
nextRetryShares.push(share);
}
}
}
if (nextRetryShares.length > 0) {
markZapRetryPending(nextRetryShares);
const message = lastError?.message || "Retry failed.";
setZapStatus(message, "error");
app?.showError?.(message);
renderZapReceipts(
aggregatedTracker.length ? aggregatedTracker : [],
{
partial: true
}
);
return;
}
renderZapReceipts(
aggregatedReceipts.length ? aggregatedReceipts : aggregatedTracker,
{ partial: false }
+12 -2
View File
@@ -520,7 +520,13 @@ async function processShare({
}
export async function splitAndZap(
{ videoEvent, amountSats, comment = "", walletSettings } = {},
{
videoEvent,
amountSats,
comment = "",
walletSettings,
overrideFee = null,
} = {},
dependencies = {}
) {
if (!videoEvent || typeof videoEvent !== "object") {
@@ -538,7 +544,11 @@ export async function splitAndZap(
throw new Error("This creator has not configured a Lightning address yet.");
}
const platformFee = clampPercent(getOverridePlatformFee());
const platformFee = clampPercent(
typeof overrideFee !== "undefined" && overrideFee !== null
? resolvePlatformFeePercent(overrideFee)
: getOverridePlatformFee()
);
const platformShare = Math.floor((amount * platformFee) / 100);
const creatorShare = amount - platformShare;
+2 -19
View File
@@ -398,7 +398,7 @@ export default class ZapController {
this.resetRetryState();
this.modalZapCommentValue = "";
this.videoModal?.setZapComment("");
this.videoModal?.resetZapForm({ amount: "", comment: "" });
this.videoModal?.setZapCompleted(true);
this.applyDefaultAmount();
} catch (error) {
@@ -881,13 +881,6 @@ export default class ZapController {
});
const videoEvent = this.getActiveVideoEvent();
let previousOverride;
const hasGlobal = typeof globalThis !== "undefined";
if (hasGlobal && typeof overrideFee === "number" && Number.isFinite(overrideFee)) {
previousOverride = globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__;
globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__ = overrideFee;
}
try {
const result = await this.splitAndZap(
{
@@ -895,6 +888,7 @@ export default class ZapController {
amountSats: context.shares.total,
comment: typeof comment === "string" ? comment : "",
walletSettings: settings,
overrideFee,
},
dependencies
);
@@ -937,17 +931,6 @@ export default class ZapController {
error
);
throw error;
} finally {
if (hasGlobal && typeof overrideFee === "number" && Number.isFinite(overrideFee)) {
if (typeof previousOverride === "number") {
globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__ = previousOverride;
} else if (
globalThis &&
Object.prototype.hasOwnProperty.call(globalThis, "__BITVID_PLATFORM_FEE_OVERRIDE__")
) {
delete globalThis.__BITVID_PLATFORM_FEE_OVERRIDE__;
}
}
}
}
+11 -3
View File
@@ -143,7 +143,15 @@ if (typeof globalThis.WebSocket === "undefined") {
}
globalThis.document = documentStub;
globalThis.navigator = windowStub.navigator;
try {
globalThis.navigator = windowStub.navigator;
} catch (error) {
Object.defineProperty(globalThis, "navigator", {
value: windowStub.navigator,
writable: true,
configurable: true,
});
}
globalThis.location = windowStub.location;
if (typeof globalThis.fetch === "undefined") {
@@ -628,8 +636,8 @@ await (async () => {
).length;
assert.equal(
warningsAfter,
initialWarningCount,
"skipped validation should not emit new warnings",
initialWarningCount + 1,
"skipped validation should not emit new warnings (except for the initial 'Sending' state)",
);
const lastStatus = modalStub.statusMessages[modalStub.statusMessages.length - 1];