On this page
Managed spell elastic pool๏
๐ก Intermediate ยท Lesson 42
Lease pooled objects and give them back by hand - Existence.managed_spell_quantity. A managed spell's objects live in a pool its root conduit owns. A meld takes an idle object, or builds one when none is waiting; ReleaseManagedSpell().release(obj) gives it back, and the next meld reuses it (the newest released object first). Nothing returns an object automatically: you decide when it goes back.
Elastic is the default mode: a meld never refuses, and managed_spell_limit (256 by default) is how many IDLE objects the pool keeps. With a small limit, a release that would keep more idle objects than the limit destroys the oldest idle one - its disposal methods run. Root teardown disposes the idle objects; describe(cls) shows what is alive, idle and out at any moment.
Before you run๏
Use the Intermediate guide for prerequisite concepts. Run from a checkout with Melder installed and Python 3.14 free-threading selected. The collection download includes the level's local helper modules.
Run the saved script๏
python UX_and_AIX_experiences/02_intermediate/42_managed_spell_elastic_pool.py
py -3.14t UX_and_AIX_experiences/02_intermediate/42_managed_spell_elastic_pool.py
Public surface๏
md.Spellbook.bind (managed_spell_mode, managed_spell_limit, disposal_method_names), md.Existence.managed_spell_quantity, md.ManagedSpellMode.elastic, md.Conduit.meld, md.Conduit.has_live_creation, md.ReleaseManagedSpell (release, describe), md.Conduit.cleanup
Code๏
1"""
2TIER: intermediate (42)
3GOAL: Lease pooled objects and give them back by hand - Existence.managed_spell_quantity.
4 A managed spell's objects live in a pool its root conduit owns. A meld takes an
5 idle object, or builds one when none is waiting; ReleaseManagedSpell().release(obj)
6 gives it back, and the next meld reuses it (the newest released object first).
7 Nothing returns an object automatically: you decide when it goes back.
8
9 Elastic is the default mode: a meld never refuses, and managed_spell_limit (256
10 by default) is how many IDLE objects the pool keeps. With a small limit, a release
11 that would keep more idle objects than the limit destroys the oldest idle one -
12 its disposal methods run. Root teardown disposes the idle objects; describe(cls)
13 shows what is alive, idle and out at any moment.
14SURFACE EXERCISED: md.Spellbook.bind (managed_spell_mode, managed_spell_limit,
15 disposal_method_names), md.Existence.managed_spell_quantity,
16 md.ManagedSpellMode.elastic, md.Conduit.meld,
17 md.Conduit.has_live_creation, md.ReleaseManagedSpell (release, describe),
18 md.Conduit.cleanup
19"""
20from typing import Tuple
21
22import melder as md
23
24
25class DatabaseConnection:
26 """A connection that is expensive to open and cheap to hand to the next caller.
27
28 `close` is its disposal method: the pool calls it when it destroys the object
29 (a trim, or root teardown), never on an ordinary release. `closed` is a lesson
30 diagnostic, so the example can observe disposal from the outside.
31 """
32
33 def __init__(self) -> None:
34 """Open the connection; the lesson only records that it is open."""
35 self.closed: bool = False
36 self.queries: int = 0
37
38 def close(self) -> None:
39 """Close the connection; called by the pool when it destroys this object."""
40 self.closed = True
41
42
43class ScratchBuffer:
44 """A pooled buffer bound with a small idle limit, to show the elastic trim."""
45
46 def __init__(self) -> None:
47 """Allocate the buffer; `closed` records disposal."""
48 self.closed: bool = False
49
50 def close(self) -> None:
51 """Release the buffer; called by the pool when it trims this object."""
52 self.closed = True
53
54
55def pool_counts(cls: type) -> Tuple[int, int, int]:
56 """Return (alive, idle, out) for the one pool of a managed class.
57
58 `ReleaseManagedSpell().describe(cls)` answers one snapshot per pool; this lesson
59 binds each class once, so there is exactly one.
60 """
61 (snapshot,) = md.ReleaseManagedSpell().describe(cls)
62 return snapshot["count"], snapshot["idle_count"], snapshot["out_count"]
63
64
65def main() -> None:
66 """Lease, release, reuse and trim pooled objects, then tear the root down.
67
68 Contract:
69 Every assertion checks an observable outcome: object identity, the pool's
70 counts from describe(), or the disposal flag. The conduit and the book are
71 cleaned in finally blocks.
72 Returns:
73 None.
74 """
75 book = md.Spellbook()
76 try:
77 book.bind(
78 spell=DatabaseConnection,
79 existence=md.Existence.managed_spell_quantity,
80 disposal_method_names=["close"],
81 )
82 book.bind(
83 spell=ScratchBuffer,
84 existence=md.Existence.managed_spell_quantity,
85 managed_spell_mode=md.ManagedSpellMode.elastic,
86 managed_spell_limit=2,
87 disposal_method_names=["close"],
88 )
89 conduit = book.conjure()
90 # Bind the release once: it is the one way back for every managed object.
91 release = md.ReleaseManagedSpell().release
92 try:
93 # The pool exists from conjure on, empty, with the default elastic policy.
94 (snapshot,) = md.ReleaseManagedSpell().describe(DatabaseConnection)
95 assert snapshot["mode"] == "elastic" and snapshot["limit"] == 256
96 assert pool_counts(DatabaseConnection) == (0, 0, 0)
97 assert not conduit.has_live_creation("DatabaseConnection")
98 print("pool ready at conjure:", snapshot["mode"], "limit", snapshot["limit"])
99
100 # Nothing is idle yet, so each meld builds a connection and leases it out.
101 first: DatabaseConnection = conduit.meld("DatabaseConnection")
102 second: DatabaseConnection = conduit.meld("DatabaseConnection")
103 assert first is not second
104 assert pool_counts(DatabaseConnection) == (2, 0, 2)
105 assert conduit.has_live_creation("DatabaseConnection")
106 print("two connections leased (alive, idle, out):", pool_counts(DatabaseConnection))
107
108 # Give one back: it becomes idle, still open, and the next meld reuses it.
109 first.queries += 1
110 release(first)
111 assert pool_counts(DatabaseConnection) == (2, 1, 1) and not first.closed
112 reused: DatabaseConnection = conduit.meld("DatabaseConnection")
113 assert reused is first and reused.queries == 1
114 print("the released connection came back on the next meld:", reused is first)
115
116 # The newest released object is leased first.
117 release(second)
118 release(reused)
119 newest: DatabaseConnection = conduit.meld("DatabaseConnection")
120 assert newest is reused
121 release(newest)
122 assert pool_counts(DatabaseConnection) == (2, 2, 0)
123 print("newest released leased first; all back (alive, idle, out):", pool_counts(DatabaseConnection))
124
125 # Elastic never refuses: with limit 2 a third buffer is still built...
126 buffers = [conduit.meld("ScratchBuffer") for _ in range(3)]
127 assert pool_counts(ScratchBuffer) == (3, 0, 3)
128 # ...but only 2 stay idle: the third release destroys the oldest idle buffer.
129 for buffer in buffers:
130 release(buffer)
131 assert [buffer.closed for buffer in buffers] == [True, False, False]
132 assert pool_counts(ScratchBuffer) == (2, 2, 0)
133 print("limit 2 keeps 2 idle buffers; the oldest was closed:", buffers[0].closed)
134 finally:
135 conduit.cleanup()
136
137 # Root teardown disposes what the pools hold and unregisters them.
138 assert first.closed and second.closed
139 assert md.ReleaseManagedSpell().describe(DatabaseConnection) == ()
140 print("root teardown closed the idle connections:", first.closed and second.closed)
141 finally:
142 book.cleanup()
143
144
145if __name__ == "__main__":
146 main()
Check the outcome๏
The script contains its own assertions or demonstrated refusal paths. Run it to evaluate those checks against your installed version. The code above is taken directly from the saved file; no run output is invented here.