mirror of
https://github.com/go-admin-team/go-admin.git
synced 2026-09-23 10:51:09 +00:00
core's contract says what the four phases promise. This says which line of
cmd/api/server.go each of them is, which is the part an application author
cannot read out of core.
Three things are recorded because getting them wrong is silent:
- BeforeRouter is not the before registry. Those callbacks run from
runStartupHooks, which is after initRouter has built the engine; the phase
is before it. The two are one line apart in the same function and describing
them as equivalent is the mistake this paragraph exists to prevent.
- AfterResource runs again after every configuration reload, so a callback
there is idempotent with respect to a resource rather than doing nothing
the second time. The queue consumers are the worked example, in both
directions: a new adapter must get consumers, the same adapter must not get
them twice. Identity has to come from where the resource is created -
GetQueueAdapter and GetQueuePrefix build a fresh wrapper per call, so two
of them never compare equal however often the adapter underneath changed.
- Consumers must be registered before the queue is started, and which
implementation is behind the interface decides whether that matters:
QueueConfig.Setup hands back queue.NewMemory when there is no redis
section, and that one does not care; a redis section reaches
LegacyQueueAdapter, whose Register cannot report a refusal. The table says
so rather than leaving "only on redis" as a claim. What is silent is the
registration alone - every publish afterwards is refused with ErrNoHandler
and logged at error level, so the symptom is missing log rows plus a lot of
noise, not a quiet nothing.
The third-layer table loses its "queue consumers are lost after a hot reload"
row, which is what AfterResource is for, and gains the honest replacement: the
four phases are the only mount points there are. There is no "after the routes
are installed, before the socket is listening".
AfterListen is described as the port being bound rather than Serve being in its
accept loop. Serve runs on another goroutine and may not have reached the first
Accept; what is true is that the bind returned, so the kernel is queueing
connections. A bind that fails produces no phase at all - the error returns
from run() and the banner never prints.