Ledger

Session

The object Store:Load gives you for one player.

Look up any call on a player's session.

local Session = Store:Load(Player) -- yields until the data is in
if Session == nil then
	return -- OnLoadFailed ran, and the player is kicked
end

Player:SetAttribute("Gold", Session:Get().Gold)
Session:Observe():Subscribe(function(State)
	Player:SetAttribute("Gold", State.Gold)
end)

A session holds one player's data in memory while they are in the server. You get one from Store:Load, Store:Get, Store:Expect or Store:WaitForLoaded. Player stores only. See Players.

Every session call throws on a session that was released. Calls that wait also throw inside an observer listener.

CallWhat it does
Get()The player's data now. No request.
Observe()An observer that emits the data each time it changes. It has no first value, so call Get() first.
ObserveFates()An observer of what became of each Apply.
Apply(Op)A change that answers at once and is saved soon.
Commit(Op, Options?)A change that is saved before it answers.
DidApply(Name, Options?)Did a named op take effect?
Flush()Saves queued Applys now.
Refresh()Reads the key now, to pick up changes made elsewhere.
Release()Saves and ends the session.

Apply

local Ok, Result = Session:Apply({ Kind = "AddGold", Amount = Amount })

Apply judges the op on the session's data, queues it and answers at once. It is saved by the next save (every 30 s), a Flush, a Commit, a Release, or shutdown. A true is not a save: the op is judged again when saved and may be turned away.

AnswerMeansDo
true, AppliedQueued. Applied is a handle to watch.Watch ObserveFates for ops that matter.
Refused or FullThe reducer said no on the current data. Nothing queued.Tell the player.
Backlog4,096 ops or 1.5 MiB are waiting.Flush, then apply again.
BusyAnother server's unfinished trade work decides this op.Try again later.
Behind or ClosedA newer build owns the key, or the server is closing.Stop.
InvalidThe op cannot be stored.Fix the op.

Apply never answers Unresolved. It takes no options.

ObserveFates

Session:ObserveFates():Subscribe(function(Fate)
	if Fate.Fate.Kind == "Turned" then
		warn("turned away:", Fate.Fate.Why)
	end
end)

Each applied op gets one fate, once: Took (saved), Turned (refused at save; Why and State say why) or Unknown (we cannot tell). Subscribe before you apply.

Commit

local Ok, Result = Session:Commit({ Kind = "AddGold", Amount = Amount })

Saves before it answers, and saves queued Applys in the same write. Options is { Id?, IdAt? }, as for Edit. On true, Result is the saved data. The answers are the same as Store:Edit, with Info.State on Refused and Info.Outcome on Unresolved. See Store.

Flush, Refresh, Release

CallAnswer
Flush()true once the save was answered, or after about 30 s. true does not mean the ops were saved: read the fates. false, Closed or false, Behind. Nothing queued answers true.
Refresh()true once the read is in. false with Unresolved, Behind, Unreadable or Closed. With ops queued it works like Flush. The view never goes back to older data.
Release()Saves once, waits up to about 30 s, and ends the session. Answers true even if the last save failed. Fates say what was saved.

Store:Unload(Player) is the same as Release. Use Flush before a Ledger.Tx on the player's key, and Refresh after it to show the result.

Next: Quantity

On this page