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

False (default)

release() โ†’ flush() โ†’ close()

True

flush() โ†’ close() โ†’ release()

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

phase_scheduler_workers_per_spellbook

Worker count for the compile pipeline

phase_scheduler_barrier_timeout_milliseconds

Maximum wait at a phase barrier, in milliseconds

disposal

Stored configuration flag; matched method names drive current cleanup registration

disposal_method_names

Ordered book-wide teardown candidates, matched once per new spell

enforce_priority_disposal_methods

Place the book block first (True) or last (False, default)

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.

Share policy intentionally๏ƒ

The shared-policy lesson passes the same configuration object to two books and asserts its identity. The books retain distinct registrations and named roots. Do not confuse shared book policy with the world's posture: the latter determines whether structural operations such as linking are available.

Continue with lifecycle hooks to observe the configured runtime.

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๏ƒ

All intermediate examples ยท Level contents ยท Full contents

Canonical page source