moonpool resource pools

Resource pools · no I/O

A pool that
answers, not acts

moonpool decides which connection to lend, when to open another, which to retire, and when to refuse — and leaves the opening, the closing and the waiting to you. Time and randomness are arguments, so a run through an hour of traffic is a test you can read.

$ moon add moonbitstack/moonpool
Lane board ten lanes, as the preset sizes them
5 lent · 3 idle · 2 never made live 8 of 10
6answers a take can give
0sockets, clocks or threads touched
15public functions
10lanes in the preset

One call, six answers

What take can say

It never blocks and never opens anything. Each answer is an instruction to the caller.

Ready an idle one

Use it, then give it back.

The most recently returned one comes out first: a warm connection is likelier to still be good, and handing out the newest lets the oldest age out.

Stale too old to use

Close it, then take again.

An idle one past keep or life is handed over rather than skipped, so nothing is lost if the eviction timer has not run.

Make there is room

Open one, then call made — or unmade if that fails.

The room is already reserved, so a slow connect does not let the pool overfill while it is in flight.

Wait all in use

Queue the caller.

The pool has no queue of its own: waiting needs a runtime, and this package has none. Whether a caller waits, fails fast, or tries elsewhere is a policy above it.

Later not yet

Try again after that span.

Making is held back by a token bucket that spaces connections out, or by backoff after a make that failed.

Shed refuse

Fail now.

The breaker has seen enough failures from the backend, or the shedder has seen the process go hot with calls still in flight.

The four knobs

Limits

Every pool carries four numbers, and the preset is the one most services end up at.

fieldpresetwhat it decides
size10How many resources may be live at once — idle, lent, and being made.
idle10How many may sit idle. Equal to size, so a pool that grew under load keeps what it made.
keep30 minHow long an idle resource may sit before it is retired.
lifeforeverHow long a resource may live at all, however busy it has been.

Zero means no limit for the two ages. Limits::new takes any of them by name; { ..limits, size: 32 } changes one and keeps the rest.

In front of the backend

The ward

Four parts, every one optional. A pool with an empty ward behaves exactly as a pool without one.

breaker

Refuses new connections at the rate a failing backend deserves. unmade tells it a make failed; made tells it one worked.

bucket

Spaces makes out. A reconnection storm arrives as a queue instead of a spike.

backoff

After a failed make, holds every make back for a delay that grows with each failure in a row.

shedder

Stops lending while the process is hot and has more calls in flight than it has shown it can finish.

Where to go

Next