Skip to content

Commit 36bbe99

Browse files
aadamsxclaude
andcommitted
fix: address PR feedback - periodic size checks and error handling
Changes based on code review feedback: 1. Made size check periodic in loop.ts (every 10 iterations) - Avoids expensive JSON.stringify on every iteration - Matches pattern used in block-executor.ts (every 50 logs) 2. Fixed error handling in estimateObjectSize/estimateBlockLogsSize - Now returns MAX + 1 instead of MAX on serialization failure - Ensures `size > MAX` evaluates to true, triggering cleanup - Prevents circular references from silently bypassing limits Note: Array slicing logic is correct as-is: - `.slice(discardCount)` keeps indices discardCount to end (newest) - This is intended behavior: keep recent data, discard old 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent aae7c40 commit 36bbe99

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

apps/sim/executor/execution/block-executor.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,12 +700,14 @@ export class BlockExecutor {
700700

701701
/**
702702
* Estimates the memory size of block logs in bytes.
703+
* Returns a value exceeding the limit on serialization failure to trigger cleanup.
703704
*/
704705
private estimateBlockLogsSize(logs: BlockLog[]): number {
705706
try {
706707
return JSON.stringify(logs).length * 2
707708
} catch {
708-
return DEFAULTS.MAX_BLOCK_LOGS_SIZE_BYTES
709+
// Return a value that exceeds the limit to trigger cleanup on serialization failure
710+
return DEFAULTS.MAX_BLOCK_LOGS_SIZE_BYTES + 1
709711
}
710712
}
711713
}

apps/sim/executor/orchestrators/loop.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -493,21 +493,23 @@ export class LoopOrchestrator {
493493
})
494494
}
495495

496-
// Check memory size limit (approximate)
497-
const estimatedSize = this.estimateObjectSize(scope.allIterationOutputs)
498-
if (estimatedSize > DEFAULTS.MAX_ITERATION_OUTPUTS_SIZE_BYTES) {
499-
// Discard oldest half of iterations when memory limit exceeded
500-
const halfLength = Math.floor(scope.allIterationOutputs.length / 2)
501-
const discardCount = Math.max(halfLength, 1)
502-
scope.allIterationOutputs = scope.allIterationOutputs.slice(discardCount)
503-
logger.warn('Loop iteration outputs exceeded memory limit, discarding older iterations', {
504-
loopId,
505-
iteration: scope.iteration,
506-
estimatedSizeBytes: estimatedSize,
507-
maxSizeBytes: DEFAULTS.MAX_ITERATION_OUTPUTS_SIZE_BYTES,
508-
discardedCount: discardCount,
509-
retainedCount: scope.allIterationOutputs.length,
510-
})
496+
// Periodically check memory size limit (every 10 iterations to avoid frequent serialization)
497+
if (scope.allIterationOutputs.length % 10 === 0) {
498+
const estimatedSize = this.estimateObjectSize(scope.allIterationOutputs)
499+
if (estimatedSize > DEFAULTS.MAX_ITERATION_OUTPUTS_SIZE_BYTES) {
500+
// Discard oldest half of iterations when memory limit exceeded
501+
const halfLength = Math.floor(scope.allIterationOutputs.length / 2)
502+
const discardCount = Math.max(halfLength, 1)
503+
scope.allIterationOutputs = scope.allIterationOutputs.slice(discardCount)
504+
logger.warn('Loop iteration outputs exceeded memory limit, discarding older iterations', {
505+
loopId,
506+
iteration: scope.iteration,
507+
estimatedSizeBytes: estimatedSize,
508+
maxSizeBytes: DEFAULTS.MAX_ITERATION_OUTPUTS_SIZE_BYTES,
509+
discardedCount: discardCount,
510+
retainedCount: scope.allIterationOutputs.length,
511+
})
512+
}
511513
}
512514
}
513515

@@ -522,9 +524,9 @@ export class LoopOrchestrator {
522524
// Multiply by 2 for UTF-16 encoding overhead in JS strings
523525
return JSON.stringify(obj).length * 2
524526
} catch {
525-
// If serialization fails (circular refs, etc.), return a large estimate
526-
// to trigger cleanup as a safety measure
527-
return DEFAULTS.MAX_ITERATION_OUTPUTS_SIZE_BYTES
527+
// If serialization fails (circular refs, etc.), return a value that exceeds
528+
// the limit to trigger cleanup as a safety measure
529+
return DEFAULTS.MAX_ITERATION_OUTPUTS_SIZE_BYTES + 1
528530
}
529531
}
530532
}

0 commit comments

Comments
 (0)