Application state
globals, request.globals and services — data versus live objects.
There are three separate stores, and they are deliberately not mixed:
$app.globals.set("site_name", "Satış Katla") # data, for the process
$app.request.globals.set("user", $user) # data, this request only
$redis = $app.services.once("redis", func() # live object, for the process
return new redis({host: "localhost", port: 6379}).connect()
end func)| Store | Belongs to | Lifetime | Carries |
|---|---|---|---|
$app.globals | the application | the process | data (passes through JSON) |
$app.request.globals | the current request | ends with the request | data |
$app.services | the application | the process | live objects |
session | the user | the session | data (in Redis) |
globals#
| Call | Effect |
|---|---|
.set($name, $value) | writes |
.get($name) · .get($name, $default) | reads |
.has($name) | whether it exists |
.delete($name) | removes |
The backing store can change; the calls do not:
$app.globals.provider = $redisThe default is memory; Redis is not required. Redis keys are written under the lexer:global:<name> namespace.
Values pass through JSON in both stores. Otherwise the same code would break when the provider changed: memory would return a live object and Redis a JSON string. This is why globals cannot carry a database connection.
request.globals#
$app.request.globals.set("user", $user) # authentication layer
$user = $app.request.globals.get("user") # page / partialWithout the distinction, a value such as "the current user" would accidentally sit application-wide — even in Redis — and leak into the next request.
globals belongs to the application, session to the user. They answer different questions.
services#
globals carries data; services carries live objects.
$redis = $app.services.once("redis", func()
return new redis({host: "localhost", port: 6379}).connect()
end func)once runs the given function only on the first call. Every request after that gets the same instance:
$redis = $app.services.get("redis")The connection is established once and every file reaches the same instance, removing the cost of reconnecting per request.
The page runs from the top on every request#
This is the one thing to keep in mind when writing state:
$app.globals.set("counter", 0) # resets to 0 on EVERY requestBecause the file is executed from the top on every request, this line runs every time too. Things that should be set up once need services.once or an existence check:
if not $app.globals.has("counter") then
$app.globals.set("counter", 0)
end ifHeavy values built once at startup and read for the life of the process — a search index, for example — belong in globals, but make sure the code that builds them also runs only once.