perf(go): cut redundant signed-session writes, progress-callback churn, tombstone growth

This commit is contained in:
zarzet
2026-07-26 22:14:58 +07:00
parent 183744c41e
commit 6fcfb67af2
3 changed files with 63 additions and 19 deletions
+10 -2
View File
@@ -292,6 +292,7 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value {
}
var written int64
var lastProgressNotify int64
buf := make([]byte, 32*1024)
// copyBody streams resp into progressWriter. fatal is a terminal JS error
@@ -321,7 +322,11 @@ func (r *extensionRuntime) fileDownload(call goja.FunctionCall) goja.Value {
return r.jsError("short write"), nil
}
if onProgress != nil && contentLength > 0 {
// Throttle the JS callback like the native progress writer:
// per-read invocation is interpreter work inside the copy loop.
if onProgress != nil && contentLength > 0 &&
(written-lastProgressNotify >= progressUpdateThreshold || written >= contentLength) {
lastProgressNotify = written
_, _ = onProgress(goja.Undefined(), r.vm.ToValue(written), r.vm.ToValue(contentLength))
}
}
@@ -535,6 +540,7 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full
}
var totalWritten int64
var lastProgressNotify int64
buf := make([]byte, 32*1024)
maxRetries := 3
@@ -616,7 +622,9 @@ func (r *extensionRuntime) fileDownloadChunked(client *http.Client, urlStr, full
return r.jsError("short write")
}
if onProgress != nil && totalSize > 0 {
if onProgress != nil && totalSize > 0 &&
(totalWritten-lastProgressNotify >= progressUpdateThreshold || totalWritten >= totalSize) {
lastProgressNotify = totalWritten
_, _ = onProgress(goja.Undefined(), r.vm.ToValue(totalWritten), r.vm.ToValue(totalSize))
}
}
+27 -17
View File
@@ -95,9 +95,6 @@ func (r *extensionRuntime) signedSessionFilePath(config SignedSessionConfig) (st
baseDir = r.dataDir
}
dir := filepath.Join(baseDir, "signed_sessions")
if err := os.MkdirAll(dir, 0700); err != nil {
return "", err
}
scope := strings.Join([]string{
namespace,
strings.TrimSpace(strings.ToLower(config.BaseURL)),
@@ -128,32 +125,41 @@ func (r *extensionRuntime) loadSignedSession(config SignedSessionConfig) (*signe
if data, err := os.ReadFile(path); err == nil {
_ = json.Unmarshal(data, record)
}
changed := false
if strings.TrimSpace(record.InstallID) == "" {
record.InstallID = randomHex(16)
changed = true
}
normalizeSignedSessionRecordScope(config, record)
if err := r.saveSignedSession(config, record); err != nil {
return nil, err
if normalizeSignedSessionRecordScope(config, record) {
changed = true
}
// Only rewrite the file when the record actually changed; loads happen on
// every signed request and preflight.
if changed {
if err := r.saveSignedSession(config, record); err != nil {
return nil, err
}
}
return record, nil
}
func normalizeSignedSessionRecordScope(config SignedSessionConfig, record *signedSessionRecord) {
// normalizeSignedSessionRecordScope stamps the config scope onto the record,
// resetting the session when the scope changed. Returns whether the record
// was modified.
func normalizeSignedSessionRecordScope(config SignedSessionConfig, record *signedSessionRecord) bool {
namespace := sanitizeSignedSessionNamespace(config.Namespace)
baseURL := strings.TrimSpace(config.BaseURL)
appVersion := strings.TrimSpace(config.AppVersion)
platform := strings.TrimSpace(config.Platform)
if record.Namespace == "" && record.BaseURL == "" && record.AppVersion == "" && record.Platform == "" {
record.Namespace = namespace
record.BaseURL = baseURL
record.AppVersion = appVersion
record.Platform = platform
return
if record.Namespace == namespace &&
record.BaseURL == baseURL &&
record.AppVersion == appVersion &&
record.Platform == platform {
return false
}
if record.Namespace != namespace ||
record.BaseURL != baseURL ||
record.AppVersion != appVersion ||
record.Platform != platform {
blankScope := record.Namespace == "" && record.BaseURL == "" &&
record.AppVersion == "" && record.Platform == ""
if !blankScope {
record.SessionID = ""
record.SessionSecret = ""
record.ExpiresAt = ""
@@ -162,6 +168,7 @@ func normalizeSignedSessionRecordScope(config SignedSessionConfig, record *signe
record.BaseURL = baseURL
record.AppVersion = appVersion
record.Platform = platform
return true
}
func (r *extensionRuntime) saveSignedSession(config SignedSessionConfig, record *signedSessionRecord) error {
@@ -169,6 +176,9 @@ func (r *extensionRuntime) saveSignedSession(config SignedSessionConfig, record
if err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
return err
}
data, err := json.MarshalIndent(record, "", " ")
if err != nil {
return err
+26
View File
@@ -3,6 +3,7 @@ package gobackend
import (
"encoding/json"
"math"
"sort"
"sync"
"time"
)
@@ -334,6 +335,11 @@ func SetItemFinalizing(itemID string) {
}
}
// maxRemovedProgressEntries bounds the removal tombstones a long batch session
// can accumulate; pruning bumps multiProgressReset so lagging delta clients
// fall back to a full resync instead of missing removals.
const maxRemovedProgressEntries = 512
func RemoveItemProgress(itemID string) {
multiMu.Lock()
defer multiMu.Unlock()
@@ -341,10 +347,30 @@ func RemoveItemProgress(itemID string) {
if _, ok := multiProgress.Items[itemID]; ok {
delete(multiProgress.Items, itemID)
removedProgressSeq[itemID] = nextMultiProgressSeqLocked()
if len(removedProgressSeq) > maxRemovedProgressEntries {
pruneRemovedProgressLocked()
}
}
markMultiProgressDirtyLocked()
}
func pruneRemovedProgressLocked() {
revisions := make([]int64, 0, len(removedProgressSeq))
for _, revision := range removedProgressSeq {
revisions = append(revisions, revision)
}
sort.Slice(revisions, func(i, j int) bool { return revisions[i] < revisions[j] })
cutoff := revisions[len(revisions)/2]
for id, revision := range removedProgressSeq {
if revision <= cutoff {
delete(removedProgressSeq, id)
}
}
if cutoff > multiProgressReset {
multiProgressReset = cutoff
}
}
func GetItemProgress(itemID string) string {
multiMu.RLock()
defer multiMu.RUnlock()