Skip to content

Persist commitment costs on scheduling job meta - #2418

Merged
Flix6x merged 3 commits into
mainfrom
fix/persist-commitment-costs-job-meta
Aug 8, 2026
Merged

Persist commitment costs on scheduling job meta#2418
Flix6x merged 3 commits into
mainfrom
fix/persist-commitment-costs-job-meta

Conversation

@Flix6x

@Flix6x Flix6x commented Aug 8, 2026

Copy link
Copy Markdown
Member

The bug

make_schedule records the scheduler's commitment cost breakdown on the job:

if rq_job and result.get("name") == "commitment_costs":
    rq_job.meta["scheduler_info"]["commitment_costs"] = result["data"]

…but this runs after the function's last rq_job.save_meta() call, and RQ persists a finishing job with include_meta=False. So the costs were computed and then silently dropped: no scheduling job has ever carried commitment_costs in the meta actually stored in Redis. The ordering has been wrong since the feature was introduced in #1946, so this never worked. Any consumer reading job meta (e.g. the jobs API) saw a scheduler_info without them.

Observed live: after a successful StorageScheduler job, Job.fetch(...) returns scheduler_info containing only {"scheduler": ...}, while the in-memory job object in the worker (e.g. seen from an RQ success callback) still holds the full cost dict.

The fix

Call rq_job.save_meta() right where the costs are recorded, with a comment explaining why the explicit save is load-bearing.

The test

The assertions live in test_scheduling_a_battery, which already runs a real battery scheduling job with these fixtures. After the job finishes it fetches a fresh Job instance from Redis and asserts the persisted meta carries a non-empty, finite cost breakdown — deliberately not inspecting the worker's in-memory object, which held the data even when the bug was live.

Mutation-tested (each mutant applied to scheduling.py, test rerun):

Mutant Outcome
Fix reverted (no save_meta) killed
save_meta() before the assignment killed
Costs stored under a wrong key killed
Costs replaced by {} killed
Branch condition inverted killed

Pristine fix: passes. Full test_scheduling_jobs.py module: 14 passed.

No changelog entry: the feature this repairs is itself part of unreleased v1.0.0 (#1946).

🤖 Generated with Claude Code

https://claude.ai/code/session_01UKx19DmqHiTBS7iEeFTijs

The cost breakdown was written to rq_job.meta after the job's last
save_meta() call, and RQ persists a finishing job with include_meta=False,
so the costs were computed and then silently lost from Redis — for every
scheduling job, since the feature's introduction in #1946. Any consumer
reading job meta (e.g. the jobs API) saw a scheduler_info without them.

Save the meta right where the costs are recorded. The regression test
fetches a fresh Job instance from Redis, so it asserts what was actually
persisted rather than the worker's in-memory object; it was additionally
mutation-tested (5/5 targeted mutants killed: fix reverted, save-before-set,
wrong key, empty payload, branch inverted).

No changelog entry: the feature this repairs is itself unreleased (v1.0.0).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UKx19DmqHiTBS7iEeFTijs
Signed-off-by: F.N. Claessen <felix@seita.nl>

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

Fixes a bug where make_schedule computed and attached commitment_costs to the RQ job meta but never persisted it to Redis, meaning downstream consumers (e.g. jobs API) could not read commitment cost breakdowns from stored job meta.

Changes:

  • Persist commitment_costs immediately via rq_job.save_meta() at the point they are written to rq_job.meta["scheduler_info"]
  • Add a regression test that runs a real scheduling job and then re-fetches the Job from Redis to assert the persisted meta contains finite, non-empty commitment costs

Reviewed changes

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

File Description
flexmeasures/data/services/scheduling.py Persist commitment_costs into Redis by saving job meta immediately after writing the field
flexmeasures/data/tests/test_scheduling_jobs.py Add regression test verifying commitment_costs are present on a freshly fetched finished job

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread flexmeasures/data/tests/test_scheduling_jobs.py Outdated
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UKx19DmqHiTBS7iEeFTijs
Signed-off-by: F.N. Claessen <felix@seita.nl>

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

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@read-the-docs-community

read-the-docs-community Bot commented Aug 8, 2026

Copy link
Copy Markdown

Documentation build overview

📚 flexmeasures | 🛠️ Build #33972054 | 📁 Comparing 811b236 against latest (8c4e7d3)

  🔍 Preview build  

1 file changed
± api/v3_0.html

Comment thread flexmeasures/data/tests/test_scheduling_jobs.py
@Flix6x Flix6x added this to the 1.0.0 milestone Aug 8, 2026
@Flix6x Flix6x self-assigned this Aug 8, 2026
…tery test

Context:
- Review: a whole new scheduling test is not needed just to assert these; the
  checks belong in an existing scheduling test

Change:
- Moved the assertions into test_scheduling_a_battery, which already runs the
  same job with the same fixtures, and dropped the separate test
- Still fetches a fresh Job from Redis, so only what was actually persisted is
  asserted (verified to fail when the fix is reverted)

Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x
Flix6x merged commit 18f43b5 into main Aug 8, 2026
13 checks passed
@Flix6x
Flix6x deleted the fix/persist-commitment-costs-job-meta branch August 8, 2026 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants