go project - add a migration and rename the dockerfiles so that Go is the primary

This commit is contained in:
2026-08-06 15:54:40 -05:00
parent 459b90dcd7
commit e17fbc14a0
15 changed files with 771 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
package store
import (
"sync"
"time"
)
// uploadHistory tracks running total/count of upload durations for one device.
type uploadHistory struct {
mu sync.Mutex
total time.Duration
count int64
}
func (u *uploadHistory) add(d time.Duration) {
u.mu.Lock()
defer u.mu.Unlock()
u.total += d
u.count++
}
func (u *uploadHistory) average() time.Duration {
u.mu.Lock()
defer u.mu.Unlock()
if u.count == 0 {
return 0
}
// Truncating integer division — same idea as C# BigInteger total / count.
return u.total / time.Duration(u.count)
}
func (s *Store) uploadFor(id DeviceID) *uploadHistory {
s.mu.Lock()
defer s.mu.Unlock()
u, ok := s.uploads[id]
if !ok {
u = &uploadHistory{}
s.uploads[id] = u
}
return u
}
// AddUpload records an upload duration (nanoseconds as time.Duration) for deviceID.
// sent_at from the API is intentionally ignored here; the HTTP layer still accepts it.
func (s *Store) AddUpload(deviceID DeviceID, uploadTime time.Duration) {
s.uploadFor(deviceID).add(uploadTime)
}
// AverageUploadTime returns the mean upload duration for deviceID.
// Formatting for the API (duration.String()) belongs at the HTTP edge.
// Unknown / never-seen devices return 0.
func (s *Store) AverageUploadTime(deviceID DeviceID) time.Duration {
s.mu.Lock()
u, ok := s.uploads[deviceID]
s.mu.Unlock()
if !ok {
return 0
}
return u.average()
}