From 96c62ab9258ef0be8dd56af8207721d958c3776b Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Thu, 15 Aug 2024 21:25:30 +0200 Subject: [PATCH] concurrency for the expiry time --- cmd/templaterender/render.go | 2 +- pkg/models/state.go | 18 +++++++++++++++++- pkg/server/matchmaker/matchmaker.go | 4 ++-- pkg/server/templates/sessions.templ | 4 ++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/cmd/templaterender/render.go b/cmd/templaterender/render.go index 42e70f7..bcffddb 100644 --- a/cmd/templaterender/render.go +++ b/cmd/templaterender/render.go @@ -92,8 +92,8 @@ func main() { OS: "linux", Shell: "/bin/bash", }, - ExpiryTime: time.Now().In(japan).Add(10 * time.Minute), } + agent.SetExpiryTime(time.Now().In(japan).Add(10 * time.Minute)) state.Agents.Put(agent.Guid, &agent) client := models.Client{ Guid: models.ClientGuid(strconv.Itoa(rand.Int())), diff --git a/pkg/models/state.go b/pkg/models/state.go index 880f533..0b30a4d 100644 --- a/pkg/models/state.go +++ b/pkg/models/state.go @@ -3,9 +3,16 @@ package models import ( "git.wamblee.org/converge/pkg/comms" "git.wamblee.org/converge/pkg/support/collections" + "sync/atomic" "time" ) +// Concurrency design: +// 1. State is immutable +// 2. The MatchMakers uses copy-on-write and never modifies a state directly. +// 3. the matchmaker modifies the expiry time of the agent. This is dealt with using the +// sync/atomic package by storing the expiry time as an int64 using time.Time.UnixNano() + type RendezVousId string type AgentGuid string type ClientGuid string @@ -22,7 +29,16 @@ type Agent struct { // TODO add remote address. EnvironmentInfo comms.EnvironmentInfo - ExpiryTime time.Time + expiryTime int64 +} + +func (agent *Agent) SetExpiryTime(t time.Time) { + atomic.StoreInt64(&agent.expiryTime, t.UnixNano()) +} + +func (agent *Agent) GetExpiryTime() time.Time { + t := atomic.LoadInt64(&agent.expiryTime) + return time.Unix(0, t) } type Client struct { diff --git a/pkg/server/matchmaker/matchmaker.go b/pkg/server/matchmaker/matchmaker.go index 4e570b4..75f9044 100644 --- a/pkg/server/matchmaker/matchmaker.go +++ b/pkg/server/matchmaker/matchmaker.go @@ -56,7 +56,7 @@ func (converge *MatchMaker) Register(publicId models.RendezVousId, conn io.ReadW converge.admin.SetSessionType(models.ClientId(session.ClientId), models.SessionType(session.SessionType)) }, func(expiry comms.ExpiryTimeUpdate) { - agent.ExpiryTime = expiry.ExpiryTime + agent.SetExpiryTime(expiry.ExpiryTime) converge.logStatus() }) }() @@ -137,7 +137,7 @@ func logStatusImpl(admin *models.State, notifier Notifier) { for agent := range admin.Agents.RangeValues() { lines = append(lines, fmt.Sprintf(format, agent.PublicId, agent.StartTime.Format(time.DateTime), - agent.ExpiryTime.Format(time.DateTime), + agent.GetExpiryTime().Format(time.DateTime), agent.EnvironmentInfo.Username, agent.EnvironmentInfo.Hostname, agent.EnvironmentInfo.OS)) diff --git a/pkg/server/templates/sessions.templ b/pkg/server/templates/sessions.templ index 777d0b8..f8e7937 100644 --- a/pkg/server/templates/sessions.templ +++ b/pkg/server/templates/sessions.templ @@ -39,7 +39,7 @@ templ State(state *models.State, location *time.Location) { rendez-vous id start time - expiry time + time username host os @@ -50,7 +50,7 @@ templ State(state *models.State, location *time.Location) { {string(agent.PublicId)} {agent.StartTime.In(location).Format(time.DateTime)} - {agent.ExpiryTime.In(location).Format(time.DateTime)} + {agent.GetExpiryTime().In(location).Format(time.DateTime)} {agent.EnvironmentInfo.Username} {agent.EnvironmentInfo.Hostname} {agent.EnvironmentInfo.OS}