Documentation
¶
Overview ¶
Package architecture is the compiled source for docs/guide/architecture.md.
One application with every hook filled in, so that the page's central claim — which goroutine each piece of your code runs on, and what is waiting behind it — is attached to code that compiles rather than to a diagram.
Index ¶
Constants ¶
const ( // EventShout is the one event a browser may send. EventShout = "room.shout" // FragmentBoard is the one live region. FragmentBoard = "room.board" // FieldBody is the form field EventShout carries. FieldBody = "body" )
Variables ¶
This section is empty.
Functions ¶
func Config ¶
Config is the whole application, and the comment above each hook is the goroutine it runs on.
func Reducer ¶
Reducer is the pure transition, and it runs on the session's actor goroutine.
One goroutine owns this session's state and is the only writer, so the function it returns needs no mutex and gets none. What it may not do is the price of that: no I/O, no clock, no randomness, no logging, and no mutation of the state it was handed. It returns the work it wants done as a value.
Types ¶
type Room ¶
type Room struct {
// contains filtered or unexported fields
}
Room is state shared between sessions, and it is the application's, not the library's. Every session has its own goroutine, so anything reachable from more than one of them is yours to synchronise — which is why this has a mutex and State does not.
func (*Room) Authorize ¶
func (r *Room) Authorize(_ context.Context, _ live.Session[live.AnonymousIdentity], ev live.Event) error
Authorize runs on the connection's read pump, ahead of the mailbox, and not on the session's actor goroutine.
That placement is the security property: an event is rate limited, checked against the registered names and fragments, and authorized before it occupies a mailbox slot, so a refused event costs the session nothing. Its consequence is the one to remember while writing this hook — blocking in here stalls the whole connection, acknowledgements and heartbeats included, where blocking in a reducer would stall only the mailbox behind it.
func (*Room) Join ¶
Join and Leave are called from Init and Teardown, both on the session's actor goroutine but from different sessions, so they lock.
func (*Room) ShoutEffect ¶
ShoutEffect is the I/O the reducer asks for rather than performs.
Its Run is not on the actor goroutine, and that is the point: it is allowed to block, to call a database, to take as long as it takes. The session keeps handling events while it runs, and what it produces reaches the reducer as an ordinary event rather than as a return value. The source names the effect on every patch it causes and in every metric it moves: the origin source becomes "effect:room.shout".
type State ¶
State is one session's state. It is per session and per connection: two tabs are two sessions with two of these, and neither can reach the other's.
It is comparable, which is what lets the library tell a transition that changed state from one that did not, and suppress the patch for the second.