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.
| Call | What 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.
| Answer | Means | Do |
|---|---|---|
true, Applied | Queued. Applied is a handle to watch. | Watch ObserveFates for ops that matter. |
Refused or Full | The reducer said no on the current data. Nothing queued. | Tell the player. |
Backlog | 4,096 ops or 1.5 MiB are waiting. | Flush, then apply again. |
Busy | Another server's unfinished trade work decides this op. | Try again later. |
Behind or Closed | A newer build owns the key, or the server is closing. | Stop. |
Invalid | The 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
| Call | Answer |
|---|---|
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