Repository navigation
fix(examples): handle N jobs and job errors in thread-queue-timer; make three checks falsifiable - #478
Merged
Conversation
…ke three checks falsifiable The thread-queue-timer pattern stopped its drain after the first result, leaving a second job's result stranded, and a raising job left the timer polling forever. The snippet and skill now count pending jobs, drain everything per tick, and have the worker put the exception. Three examples carried checks that passed by construction: the image-pixels orientation check compared two Python lists, the extension --validate-only falsifier reached exit 4 by tautology, and the timers main-thread and still-registered checks could never fire. Each now fails only through the Blender behavior it claims, with a catalog falsifier per check. Closes #463 Closes #470 Signed-off-by: TMHSDigital <tmhospitalitystrategies@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #463
Closes #470
What changed
#463: thread-queue-timer handles N jobs and job errors
snippets/thread-queue-timer.pyandskills/timers-modal-and-threading/SKILL.mdnow keep a pending-job counter. Each tick takes every result that has arrived, and the drain unregisters only when the count reaches 0. The worker wrapsjob()intry/except BaseExceptionand puts(False, e), so the main thread reports the error and the drain never polls forever.examples/timers-modal-threadingruns that pattern with three concurrent jobs, one of which raisesValueError. It asserts that both results are applied, the error is reported, the pending count reaches 0 and the drain unregisters itself.#470: three examples with checks that passed by construction or could not fire
Image.save()and the PNG is decoded withzlib+structonly, nobpy. Every PNG rowkmust match card rowH-1-k, and the origin marker must be in the file's last row. This is new exit 13.--wrong-originwrites the flipped buffer through Blender and now expects 13. Theforeachround trip (exit 4) no longer claims to cover orientation.--validate-only, which could only reach exit 4 by tautology, is replaced by--ship-wheel. That flag creates the wheel the manifest names, sobuildsucceeds and the check must exit 4.threading.get_ident()recorded in each worker against the ident of the code that touchesbpy. The oldcurrent_thread() is main_thread()check ran inside a timer, so it was always true.still_registeredis read beforeread_factory_settings. Before, the file load had already dropped every plain timer, so the read was alwaysFalse.New catalog falsifiers for timers-modal-threading:
--windowed-background-child--return-zero-once--return-late-onceis_registered(read before the load) is True--apply-in-worker--no-event-timerTIMERevents, modal never finishes--non-persistent--stop-after-first--no-catchExit codes 2, 10 and 11 are not used for any contract.
Evidence
Live run (local, via
tests/smoke/run_catalog.pyon a scratch catalog of these three rows):.scratch/blender-5.2.1-windows-x64/blender.exe, reports5.2.1 LTS hash 9e2066aef7ef): all three happy paths PASS, and every falsifier exits exactly as declared..scratch/blender-4.5.11-windows-x64/blender.exe, reports4.5.11 LTS hash 4db51e9d1e1e): all three happy paths PASS, and every falsifier exits exactly as declared.--apply-in-workerexited 4 first. Its windowed child logged "Saved session recovery to quit.blend" without writing its JSON, which is what closing the Blender window does, and the window opened on the user's desktop. I infer the window was closed by hand. A clean re-run exited 6 as declared.Measured falsifier output:
--wrong-origin: row error 0.9216, marker in rows 0..40, exit 13 (5.2.1 and 4.5.11).--ship-wheel: validate exit 0, build exit 0, zip written, exit 4 (5.2.1 and 4.5.11).--return-zero-once: once ran 30x on 5.2.1 and 21x on 4.5.11, exit 5.--return-late-once: once=1, registered=[True, False], exit 5.--apply-in-worker: handled on the worker idents, exit 6.--no-event-timer: ticks=0, result=None, exit 7.--stop-after-first: got{'heights': 3}vs expected heights+labels, exit 9.--no-catch: errors=[], pending=1, drain registered, exit 12.Inspection only: Blender 5.1 was not re-run locally. The README tables say so, and the weekly cron covers it. CI xvfb runs the full matrix on 5.2 and 4.5.
Validators:
python tests/run_all.py: 31 passed, 0 failed.scripts/build_examples_index.pyandscripts/build_gallery.pywere re-run. I read the regenerateddocs/gallery/image-pixels-testcard/index.html: the new list item, the exit-13 row and the img alt are correct.examples/gallery.jsonis unchanged.🤖 Generated with Claude Code