On this page
Configure the book before conjure๏
Prerequisite: bind โ conjure โ meld. A
SpellbookConfiguration states the book's policy: teardown vocabulary and
scheduler settings are common reasons to provide one explicitly.
Choose defaults or supply a complete policy๏
Use with_defaults() for the standard policy, then adjust mutable scheduler
settings before conjure. If you need a custom disposal vocabulary, build that
configuration explicitly before handing it to Spellbook(configuration=...).
The saved disposal lesson shows the complete setup rather than a fragment that
depends on an already-initialized configuration.
Conjure validates and freezes the configuration. Disposal names and priority are resolved for each spell at bind time, so establish them before binding. The configuration lessons also demonstrate unknown-property and incomplete-configuration failures.
Ordered disposal: book block first or last๏
Per-bind disposal_method_names belong to that binding. Book-configured names
apply to every new binding that implements them. Matching happens once at bind;
cleanup consumes the resulting list without rereading configuration.
config = md.SpellbookConfiguration()
config.with_disposal_method_names(["flush", "close"])
config.with_enforce_priority_disposal_methods(False) # default: book block last
config.with_defaults().finalize()
book = md.Spellbook(configuration=config)
book.bind(
spell=Resource,
existence="many",
disposal_method_names=["close", "release", "flush"],
)
Assuming Resource declares all three methods:
Priority flag |
Calls on each instance |
|---|---|
|
|
|
|
The book owns shared names in both modes. Its complete matching block keeps configuration order; spell-only methods keep their own order beside it. Missing names are omitted and each accepted name runs once. An empty per-bind list does not suppress book methods.
The existing matching scope is class-profile methods declared on the class; inherited-only methods, factory returns, and prebuilt-instance methods are not discovered by this binding path. Supply a class with explicit methods when you want automatic disposal registration.
The method-name property is set-once; choose it before with_defaults() fills it.
The priority flag can be adjusted during configuration assembly and freezes with
the configuration. This is creation-time policy, not a post-bind mutation API.
Existing scope/key/bucket teardown order is unchanged. Within one object, a method failure stops its remaining methods; other objects still receive cleanup. Crystals preserve the resolved order, and replay applies the receiving book's normal binding policy. A different policy can yield a different content ID.
Tune the compile phase deliberately๏
Property |
Meaning |
|---|---|
|
Worker count for the compile pipeline |
|
Maximum wait at a phase barrier, in milliseconds |
|
Stored configuration flag; matched method names drive current cleanup registration |
|
Ordered book-wide teardown candidates, matched once per new spell |
|
Place the book block first ( |
A larger timeout allows slower work to complete; it does not repair a dependency error. The scheduler lesson checks that constructor DI still works with one worker and an explicitly chosen barrier timeout.
The workflow in code๏
These are the core steps from the saved example. Use its complete linked script for all class definitions and setup.
1def main() -> None:
2 """Verify configuration timing and both ordered disposal arrangements."""
3 # CONFIGURE, THEN LOCK - the order is the lesson.
4 # The disposal pair is SET-ONCE. A book you construct bare has already
5 # taken the standard default set, and that set is COMPLETE - it fills
6 # every required property, disposal included. Complete means finished:
7 # there is no room left to write disposal into it afterwards.
8 # So you pick one path. Take the defaults and live with them, or state
9 # your own policy up front and hand it to the book. This lesson states
10 # its own.
11 config = md.SpellbookConfiguration()
12 config.set_property("disposal", True)
13 config.set_property("disposal_method_names", ["close"])
14 config.set_property("phase_scheduler_workers_per_spellbook", 5)
15 config.set_property(
16 "phase_scheduler_barrier_timeout_milliseconds", 60000)
17
18 book = md.Spellbook(configuration=config)
19 book.bind(spell=PooledThing, existence="unique")
20
21 # IDEMPOTENT LAW: these two are set-once. A second set refuses.
22 try:
23 config.set_property("disposal", False)
24 print("idempotent re-set unexpectedly succeeded")
25 except Exception as err:
26 print("idempotent re-set refused:", type(err).__name__)
27
28 conduit = book.conjure()
29 thing = conduit.meld("PooledThing")
30 conduit.cleanup()
31 print("disposal vocabulary fired at cleanup:", thing.closed)
32
33 # FREEZE LAW: conjure froze the whole configuration.
34 try:
35 config.set_property("phase_scheduler_workers_per_spellbook", 2)
36 print("post-conjure set unexpectedly succeeded")
37 except Exception as err:
38 print("post-conjure set refused:", type(err).__name__)
39 book.cleanup()
40 demonstrate_priority(False)
41 demonstrate_priority(True)
Runnable examples๏
Config disposal and the frozen law โ Intermediate 30
Spellbook configuration basics โ Intermediate 19
Phase scheduler knobs โ Intermediate 20
Spellbook config defined โ Intermediate 31
One config every book โ Intermediate 35
All intermediate examples ยท Level contents ยท Full contents