Skip to content

Keep DataPoint under BSON cap; terminal state on worker failure (fixes #851) - #852

Merged
brianlball merged 1 commit into
developfrom
fix/dp-bson-cap-and-terminal-state
Jul 22, 2026
Merged

Keep DataPoint under BSON cap; terminal state on worker failure (fixes #851)#852
brianlball merged 1 commit into
developfrom
fix/dp-bson-cap-and-terminal-state

Conversation

@brianlball

Copy link
Copy Markdown
Contributor

Fixes #851.

Problem

A datapoint whose simulation SUCCEEDS can still be lost: an oversized artifact (observed: generic_qaqc summary_report, ~19MB inlined via results) pushes the DataPoint document over mongo's 16MB BSON cap. The save raises, every later save of the now-dirty document re-raises, the Resque wrapper's catch-all rescue only logs, and the dp is left status: started forever. R-driven algorithms (morris/sobol/nsga2) then poll to timeout, fill the design with 1e+18 penalties, and crash in result assembly — one oversized measure report kills the whole analysis with no failure recorded.

Full forensics in #851 (docker 3.11.0 images, 27-zone model, morris r=6).

Changes

  • prune_oversized_results (dj job): when measure_attributes.json exceeds MAX_INLINE_RESULTS_BYTES (5MB), per-measure results larger than MAX_INLINE_RESULTS_MEASURE_BYTES (1MB) are replaced with a stub. Small results — objective values the algorithms need — are preserved. Complements the existing MAX_INLINE_SDP_LOG_* truncation.
  • dj rescue path: reload the DataPoint before terminal-state saves so a dirty oversized document can't re-raise the same persistence error out of the rescue.
  • Resque wrapper: on unhandled exception, set error flag + complete state (after reload) so the dp reaches a terminal state (completed / datapoint failure) instead of zombie-ing as started.

Testing

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens datapoint execution against MongoDB’s 16MB BSON document limit and ensures datapoints reliably reach a terminal state when workers fail, preventing “zombie” datapoints that remain started indefinitely and destabilize downstream R-driven analyses.

Changes:

  • Add terminal-state handling in the Resque wrapper on unhandled exceptions (reload + error + complete) to avoid leaving datapoints stuck in started.
  • Prune oversized inlined results (from measure_attributes.json) by stubbing per-measure payloads above a configured threshold when the overall results file is large.
  • Reload the DataPoint in the DJ rescue path before terminal-state saves so a dirty/oversized in-memory document doesn’t cause repeated persistence failures.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
server/app/jobs/resque_jobs/run_simulate_data_point.rb Ensures unhandled Resque worker exceptions attempt to put the DataPoint into a terminal failure state after reload.
server/app/jobs/dj_jobs/run_simulate_data_point.rb Adds oversized-results pruning before saving results, and reloads the DataPoint before terminal-state saves in the rescue path.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +69 to +72
begin
d&.reload
d&.set_error_flag
d&.set_complete_state

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed: rebased onto develop with #853, which guards both rescue paths — a nil d now logs via Rails.logger with the datapoint id and re-raises the original error before these log calls, so the terminal-state block only runs with d bound (safe navigation dropped accordingly).

…er failure

- prune_oversized_results: when measure_attributes.json exceeds
  MAX_INLINE_RESULTS_BYTES, replace per-measure results larger than
  MAX_INLINE_RESULTS_MEASURE_BYTES with a stub (small objective values
  preserved) so a successful simulation cannot fail its own save.
- dj rescue: reload before terminal-state saves so a dirty oversized
  document cannot re-raise the same persistence error.
- resque wrapper: on unhandled exception, set error flag + complete
  state (after reload) instead of leaving the dp 'started' forever,
  which made R algorithms spin to timeout and crash the analysis.

Fixes #851

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@brianlball
brianlball force-pushed the fix/dp-bson-cap-and-terminal-state branch from c4c4f86 to 2fef1f3 Compare July 22, 2026 20:49
@brianlball
brianlball merged commit 8a65647 into develop Jul 22, 2026
5 checks passed
@brianlball
brianlball deleted the fix/dp-bson-cap-and-terminal-state branch July 22, 2026 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Oversized datapoint artifacts (e.g. 19MB generic_qaqc log) exceed BSON 16MB cap -> dp zombies as 'started', R algorithms crash; successful sims lost

2 participants