diff --git a/app/components/partials/WebSocketStatusOverlay.vue b/app/components/partials/WebSocketStatusOverlay.vue index 2a2f43e93..a19fe6e49 100644 --- a/app/components/partials/WebSocketStatusOverlay.vue +++ b/app/components/partials/WebSocketStatusOverlay.vue @@ -47,9 +47,16 @@ async function checkWebSocketStatus(previousStatus: WebSocketStatus, status: Web }, }, actions: [ + { + label: t('common.retrying'), + icon: 'i-mdi-circle-arrows', + loading: true, + active: true, + disabled: true, + }, { label: t('common.refresh'), - icon: 'i-mdi-refresh', + icon: 'i-mdi-reload', click: () => reloadNuxtApp({}), }, ], diff --git a/app/lang/en/en.json b/app/lang/en/en.json index c4edede0c..c33d55074 100644 --- a/app/lang/en/en.json +++ b/app/lang/en/en.json @@ -477,7 +477,8 @@ "pin": "Pin", "unpin": "Unpin", "pinned_document": "Pinned document | Pinned documents", - "or": "OR" + "or": "OR", + "retrying": "Retrying..." }, "components": { "partials": { diff --git a/gen/go/proto/services/jobs/timeclock.go b/gen/go/proto/services/jobs/timeclock.go index 15b57aa07..31ef42aeb 100644 --- a/gen/go/proto/services/jobs/timeclock.go +++ b/gen/go/proto/services/jobs/timeclock.go @@ -120,7 +120,7 @@ func (s *Server) ListTimeclock(ctx context.Context, req *ListTimeclockRequest) ( tUser.Lastname, tUser.Dateofbirth, tUser.PhoneNumber, - tUserProps.Avatar.AS("user_short.avatar"), + tUserProps.Avatar.AS("colleague.avatar"), tJobsUserProps.UserID, tJobsUserProps.Job, tJobsUserProps.AbsenceBegin, diff --git a/pkg/tracker/manager.go b/pkg/tracker/manager.go index 2098ea420..4e06d4ebd 100644 --- a/pkg/tracker/manager.go +++ b/pkg/tracker/manager.go @@ -18,6 +18,7 @@ import ( "github.com/fivenet-app/fivenet/pkg/nats/store" "github.com/gin-gonic/gin" jet "github.com/go-jet/jet/v2/mysql" + "github.com/go-jet/jet/v2/qrm" "github.com/nats-io/nats.go/jetstream" tracesdk "go.opentelemetry.io/otel/sdk/trace" "go.opentelemetry.io/otel/trace" @@ -150,8 +151,8 @@ func (m *Manager) cleanupUserIDs(ctx context.Context, found map[int32]interface{ continue } - // Marker has been updated in the latest 30 seconds, skip it - if marker.Info.UpdatedAt != nil && time.Since(marker.Info.UpdatedAt.AsTime()) <= 30*time.Second { + // Marker has been updated in the latest 15 seconds, skip it + if marker.Info.UpdatedAt != nil && time.Since(marker.Info.UpdatedAt.AsTime()) <= 15*time.Second { continue } @@ -204,8 +205,23 @@ func (m *Manager) refreshUserLocations(ctx context.Context) error { tLocs.UpdatedAt.GT_EQ(jet.CURRENT_TIMESTAMP().SUB(jet.INTERVAL(4, jet.HOUR))), )) + // Begin transaction + tx, err := m.db.BeginTx(ctx, nil) + if err != nil { + return err + } + // Defer a rollback in case anything fails + defer tx.Rollback() + var dest []*livemap.UserMarker if err := stmt.QueryContext(ctx, m.db, &dest); err != nil { + if !errors.Is(err, qrm.ErrNoRows) { + return err + } + } + + // Commit the transaction + if err := tx.Commit(); err != nil { return err } diff --git a/pkg/tracker/tracker.go b/pkg/tracker/tracker.go index d447a5823..4ba3968e9 100644 --- a/pkg/tracker/tracker.go +++ b/pkg/tracker/tracker.go @@ -78,7 +78,7 @@ func New(p Params) (ITracker, error) { go t.broker.Start(ctx) - userIDs, err := store.NewWithLocks[livemap.UserMarker, *livemap.UserMarker](ctx, p.Logger, p.JS, "tracker", nil, + userIDs, err := store.NewWithLocks(ctx, p.Logger, p.JS, "tracker", nil, func(s *store.Store[livemap.UserMarker, *livemap.UserMarker]) error { s.OnUpdate = func(um *livemap.UserMarker) (*livemap.UserMarker, error) { if um == nil || um.Info == nil { @@ -88,7 +88,7 @@ func New(p Params) (ITracker, error) { jobUsers, _ := t.usersByJob.LoadOrCompute(um.Info.Job, func() *xsync.MapOf[int32, *livemap.UserMarker] { return xsync.NewMapOf[int32, *livemap.UserMarker]() }) - // Maybe we can be smarted about updating the user marker here, but + // Maybe we can be smarter about updating the user marker here, but // without mutexes it will be problematic jobUsers.Store(um.UserId, um)