mirror of
https://github.com/Team254/cheesy-arena-lite.git
synced 2026-03-09 21:56:50 -04:00
Periodically purge unconnected displays.
This commit is contained in:
@@ -873,6 +873,9 @@ func (arena *Arena) runPeriodicTasks() {
|
||||
arena.EventStatusMessage = newEventStatusMessage
|
||||
arena.EventStatusNotifier.Notify()
|
||||
}
|
||||
|
||||
// Clean up the list of displays.
|
||||
arena.purgeDisconnectedDisplays()
|
||||
}
|
||||
|
||||
// Updates the string that indicates how early or late the event is running.
|
||||
|
||||
@@ -13,10 +13,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
minDisplayId = 100
|
||||
minDisplayId = 100
|
||||
displayPurgeTtlMin = 30
|
||||
)
|
||||
|
||||
type DisplayType int
|
||||
@@ -58,12 +60,13 @@ var displayTypePaths = map[DisplayType]string{
|
||||
var displayRegistryMutex sync.Mutex
|
||||
|
||||
type Display struct {
|
||||
Id string
|
||||
Nickname string
|
||||
Type DisplayType
|
||||
Configuration map[string]string
|
||||
IpAddress string
|
||||
ConnectionCount int
|
||||
Id string
|
||||
Nickname string
|
||||
Type DisplayType
|
||||
Configuration map[string]string
|
||||
IpAddress string
|
||||
ConnectionCount int
|
||||
lastConnectedTime time.Time
|
||||
}
|
||||
|
||||
// Parses the given display URL path and query string to extract the configuration.
|
||||
@@ -159,6 +162,7 @@ func (arena *Arena) RegisterDisplay(display *Display) {
|
||||
} else {
|
||||
display.ConnectionCount = 1
|
||||
}
|
||||
display.lastConnectedTime = time.Now()
|
||||
arena.Displays[display.Id] = display
|
||||
}
|
||||
arena.DisplayConfigurationNotifier.Notify()
|
||||
@@ -194,6 +198,25 @@ func (arena *Arena) MarkDisplayDisconnected(display *Display) {
|
||||
} else {
|
||||
existingDisplay.ConnectionCount -= 1
|
||||
}
|
||||
existingDisplay.lastConnectedTime = time.Now()
|
||||
arena.DisplayConfigurationNotifier.Notify()
|
||||
}
|
||||
}
|
||||
|
||||
// Removes any displays from the list that haven't had any active connections for a while and don't have a nickname.
|
||||
func (arena *Arena) purgeDisconnectedDisplays() {
|
||||
displayRegistryMutex.Lock()
|
||||
defer displayRegistryMutex.Unlock()
|
||||
|
||||
deleted := false
|
||||
for id, display := range arena.Displays {
|
||||
if display.ConnectionCount == 0 && display.Nickname == "" &&
|
||||
time.Now().Sub(display.lastConnectedTime).Minutes() >= displayPurgeTtlMin {
|
||||
delete(arena.Displays, id)
|
||||
deleted = true
|
||||
}
|
||||
}
|
||||
if deleted {
|
||||
arena.DisplayConfigurationNotifier.Notify()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package field
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestDisplayFromUrl(t *testing.T) {
|
||||
@@ -123,3 +124,47 @@ func TestDisplayUpdateError(t *testing.T) {
|
||||
assert.Contains(t, err.Error(), "doesn't exist")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisplayPurge(t *testing.T) {
|
||||
arena := setupTestArena(t)
|
||||
|
||||
// Unnamed placeholder gets immediately purged upon disconnection.
|
||||
display := &Display{Id: "254", Type: PlaceholderDisplay, Configuration: map[string]string{}}
|
||||
arena.RegisterDisplay(display)
|
||||
assert.Contains(t, arena.Displays, "254")
|
||||
arena.MarkDisplayDisconnected(display)
|
||||
assert.NotContains(t, arena.Displays, "254")
|
||||
|
||||
// Named placeholder does not get immediately purged upon disconnection.
|
||||
display.Nickname = "Bob"
|
||||
arena.RegisterDisplay(display)
|
||||
assert.Contains(t, arena.Displays, "254")
|
||||
arena.MarkDisplayDisconnected(display)
|
||||
assert.Contains(t, arena.Displays, "254")
|
||||
|
||||
// Unnamed configured display does not get immediately purged upon disconnection.
|
||||
display = &Display{Id: "1114", Type: FieldMonitorDisplay, Configuration: map[string]string{}}
|
||||
arena.RegisterDisplay(display)
|
||||
assert.Contains(t, arena.Displays, "1114")
|
||||
arena.MarkDisplayDisconnected(display)
|
||||
assert.Contains(t, arena.Displays, "1114")
|
||||
arena.purgeDisconnectedDisplays()
|
||||
assert.Contains(t, arena.Displays, "1114")
|
||||
|
||||
// Unnamed configured display gets purged by periodic task.
|
||||
arena.RegisterDisplay(display)
|
||||
assert.Contains(t, arena.Displays, "1114")
|
||||
arena.MarkDisplayDisconnected(display)
|
||||
arena.Displays["1114"].lastConnectedTime = time.Now().Add(-displayPurgeTtlMin * time.Minute)
|
||||
arena.purgeDisconnectedDisplays()
|
||||
assert.NotContains(t, arena.Displays, "1114")
|
||||
|
||||
// Named configured display does not get purged by periodic task.
|
||||
display.Nickname = "Brunhilda"
|
||||
arena.RegisterDisplay(display)
|
||||
assert.Contains(t, arena.Displays, "1114")
|
||||
arena.MarkDisplayDisconnected(display)
|
||||
arena.Displays["1114"].lastConnectedTime = time.Now().Add(-displayPurgeTtlMin * time.Minute)
|
||||
arena.purgeDisconnectedDisplays()
|
||||
assert.Contains(t, arena.Displays, "1114")
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</div>
|
||||
|
||||
<script id="displayTemplate" type="text/x-handlebars-template">
|
||||
<tr>
|
||||
<tr{{"{{#unless ConnectionCount}}"}} class="danger"{{"{{/unless}}"}}>
|
||||
<td>{{"{{Id}}"}}</td>
|
||||
<td>{{"{{ConnectionCount}}"}}</td>
|
||||
<td>{{"{{IpAddress}}"}}</td>
|
||||
|
||||
Reference in New Issue
Block a user