Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions flexmeasures/data/services/scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,10 @@ def make_schedule( # noqa: C901
continue
if rq_job and result.get("name") == "commitment_costs":
rq_job.meta["scheduler_info"]["commitment_costs"] = result["data"]
# Persist right away: this runs after the job's last save_meta() call,
# and RQ saves a finishing job with include_meta=False,
# so without an explicit save here the costs never reach Redis.
rq_job.save_meta()
continue
if "sensor" not in result:
continue
Expand Down
16 changes: 16 additions & 0 deletions flexmeasures/data/tests/test_scheduling_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def test_scheduling_a_battery(
"""Test one clean run of one scheduling job:
- data source was made,
- schedule has been made
- the commitment costs reached the job meta stored in Redis — regression for #2418
- success is logged once (not before compute) — regression for #2049
"""

Expand Down Expand Up @@ -94,6 +95,21 @@ def test_scheduling_a_battery(
sum(v.event_value for v in power_values) < -0.5
), "some cycling should have occurred to make a profit, resulting in overall consumption due to losses"

# Regression #2418: the commitment costs used to be written to the job meta after the
# job's last save_meta() call, and RQ persists a finishing job with include_meta=False,
# so they were computed and then silently lost. Fetch a fresh Job to see only what
# actually reached Redis, rather than the worker's in-memory job object.
finished_job = Job.fetch(job.id, connection=app.queues["scheduling"].connection)
assert finished_job.is_finished
commitment_costs = finished_job.meta["scheduler_info"]["commitment_costs"]
assert (
commitment_costs
), "the scheduler reported commitment costs, so the persisted job meta must carry them"
assert all(
isinstance(cost, float) and np.isfinite(cost)
for cost in commitment_costs.values()
)
Comment thread
Flix6x marked this conversation as resolved.

# Regression #2049: success message only after compute, not the pre-compute copy-paste echo.
# Count only this job's message — the RQ worker may also process other queued jobs.
out = capsys.readouterr().out
Expand Down
Loading