aboutsummaryrefslogtreecommitdiff
path: root/internal/game/owner.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/owner.go')
-rw-r--r--internal/game/owner.go31
1 files changed, 31 insertions, 0 deletions
diff --git a/internal/game/owner.go b/internal/game/owner.go
index 2fb4777..4a3646e 100644
--- a/internal/game/owner.go
+++ b/internal/game/owner.go
@@ -122,6 +122,37 @@ func (g *Game) run(fn func()) {
<-task
}
+// RunAdminOnOwner synchronously executes one complete editor request. Unlike
+// RunOnOwner it rejects work during shutdown and NEVER falls back to executing
+// on the HTTP goroutine when the owner has stopped. Call only from outside the
+// owner; runtime callbacks within fn must call owner-only methods directly.
+func (g *Game) RunAdminOnOwner(fn func()) bool {
+ if g.isShuttingDown() {
+ return false
+ }
+ accepted := false
+ task := func() {
+ if !g.isShuttingDown() {
+ fn()
+ accepted = true
+ }
+ }
+ if g.owner == nil {
+ // Synthetic Games only; production always has an owner.
+ task()
+ return accepted
+ }
+ done := make(chan struct{})
+ if !g.owner.enqueue(func() {
+ task()
+ close(done)
+ }) {
+ return false
+ }
+ <-done
+ return accepted
+}
+
// tryRun executes fn on the owner if it is currently idle-draining; it is
// not currently used for correctness paths but exists for future non-blocking
// administrative reads. It returns false when the queue is full.