Periodically purge unconnected displays.

This commit is contained in:
Patrick Fairbank
2020-03-29 14:31:32 -07:00
parent df9c5dfbd9
commit 305db8e0f2
4 changed files with 79 additions and 8 deletions

View File

@@ -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.

View File

@@ -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()
}
}

View File

@@ -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")
}

View File

@@ -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>