Releases
What changed, and what you have to change with it.
+ is new, - is gone, ! is something you have to know about before you upgrade.
4.1.0
+ Store:Stale, a stream of the keys this server changedUpgrading
Drop it in. Nothing about the stored record changed, and nothing you have written needs an edit.
Ledger pushes a key onto the stream once a write has gone through. Edit, Reserve, Confirm,
Release, Bump and Reset push the key they wrote. Transfer and Grant push both keys. Tx
pushes every leg key onto that leg's own store. A write the reducer refuses pushes nothing.
Listeners on this stream run on their own thread and may yield. Every other stream in Ledger calls its listeners inline.
See Stale.
4.0.6
- A transaction that left a leg parked not putting that key on the recovery sweep, so it waited for a readUpgrading
Drop it in. Nothing about the stored record changed.
A key that is already carrying a leg from before the upgrade does not fix itself. The sweep is told
about a key when the transaction ends, so one that ended before you upgraded was never handed over.
Any read or write to that key picks it up, and Resettle does it on demand.
4.0.5
+ Optimized Measure by ~9x
+ Minor optimizations with lazy loading
- Grant handing units over after something else had already taken the reservation, so they ended up on both keys
- Confirm saying it had spent units that a grant had already moved to another key
- Transfers left half finished when a player left while their data was still loading
- An error in your reducer reaching Session:Apply instead of the op being refused
- Session:Apply accepting state that could never be saved, so every save after it failed
- Session:Apply throwing when a reducer returned State itself instead of a copy
- A warning that your reducer is not deterministic, when the cause was another server compacting the key
! Confirm answers Held while a grant is moving those units
! Confirm answers Refused once a grant has moved them, it used to answer trueUpgrading
Drop it in. The rest of this only matters if you use Grant.
Finish the deploy before you grant again, the same as 4.0.3. A grant writes one more step that older
builds don't know. Until every server is on 4.0.5, a key you have granted from stops compacting, and
an old server still reads that reservation as open, so a Confirm there can spend units the other key
already has.
Confirm now answers false if a grant already moved the units. It used to answer true, so if you
read that as the units being yours to spend, you counted the same units twice. While a grant is still
running, Confirm answers Held, the same as Release does. Wait for the
grant to finish rather than confirming again.
4.0.4
- A key that never compacts again, after a session wrote an op the record could not fold
- Commit answering Refused for an op it had already writtenUpgrading
Drop it in. Nothing about the stored record changed.
A key that already carries one of these ops does not fix itself. Upgrading stops another one being written and leaves the one that is there, so that key keeps warning and its log keeps growing. Ledger names the key and the op kind in the warning, so you know which keys and which kind.
To clear one, make your reducer take that kind instead of turning it away. Hand back a copy of the state and change nothing:
if Op.Kind == "OpenCase" and State.Inventory.Items[Op.CaseId] == nil then
return table.clone(State)
endDeploy that and the key compacts the next time it is written to. Put the guard back afterwards.
Reset does not do it. It writes an op of its own behind the one that is stuck, so the key ends up
one op longer than it started.
4.0.3
+ Simulation V2
- A transaction decided by a server still driving an earlier transaction of the same name
- Release giving back units that Grant had already handed to another key, so they were on both
! Release answers Held while a grant is handing those units over
! Grant costs four requests, it used to be threeUpgrading
Handle Held from Release. A grant that has started moving the units answers it. They are not on
the sender to give back, and they are not certainly delivered either, so only recovery can say which.
Tell the player to wait rather than releasing again. Nothing is lost in the meantime.
Finish the deploy before granting. A hand over writes a step older builds don't know, and an old
build reading that key holds the step back rather than dropping it, the same way it already does for
a reserved op it doesn't handle. That key stops compacting until every server is on 4.0.3. Worse, an
old build still gives those units back on a Release, which is the bug above. Roll it out, then use
Grant.
4.0.2
+ Folding a log is about a fifth faster, and every read folds one
+ A Future holds less than half the memory it used to
+ An Observer sends a value about three times faster
- A transfer name used by two senders, where a record written before 4.0.1 could settle the wrong hold
- Session:Apply answering Refused for an op that only holds once a parked transaction goes through
! An Observer sends to its listeners in the order they subscribedUpgrading
Drop it in. A delivery now says who sent it from the delivery itself rather than from its name, so a record written by an older build is read the same way as a new one.
Session:Apply answers Busy or Unresolved in one more place. An op that the reducer turns away
now, but would take once a parked transaction goes through, answers
Unresolved instead of Refused. Store:Edit
already answered that way, so the two agree now. Ask again once the transaction settles rather than
telling the player no.
4.0.1
- Two senders using one transfer name, where one of the amounts was destroyed and both calls said true
- Recovery settling a hold against a delivery that came from a different sender
- Reset dropping units set aside for another key, so a grant could leave them on both
- A commit refused by a newer write staying in the log and stopping that key compacting for good
! A transfer name now means the sender as well as the amount and the receiver
! Reset answers Busy while the key holds units set aside for another key
! A compaction holds back a reserved op this build does not handle, the same as it does for yoursUpgrading
A transfer name belongs to one sender now. Two senders were never meant to share one, and doing it
used to destroy an amount without saying so. It answers Spent instead.
Handle Busy from Reset if you call it. A key holding units for another key refuses the reset the
same way a key with a transaction parked on it already did. Hand the units over or release them
first.
4.0.0
+ Ledger.UseClock takes a second argument, the wait Ledger polls on
! The files inside the module were all moved and renamedComplete rewrite, cleaner code, same api, less lines