tidy up code

This commit is contained in:
2025-05-10 15:13:31 +01:00
parent 56bc155aa5
commit 92e9900bbc

36
main.go
View File

@@ -36,20 +36,24 @@ type location struct {
ianaName string ianaName string
} }
// pageTemplate stores all pre-compiled HTML templates for the application
type pageTemplate struct { type pageTemplate struct {
summary *template.Template summary *template.Template
} }
// summaryTemplateData stores template data for summary.html
type summaryTemplateData struct { type summaryTemplateData struct {
Summary string Summary string
Location string Location string
} }
// updateSubscription is the request body for creating/updating registration
type updateSubscription struct { type updateSubscription struct {
Subscription webpush.Subscription `json:"subscription"` Subscription webpush.Subscription `json:"subscription"`
Locations []string `json:"locations"` Locations []string `json:"locations"`
} }
// registeredSubscription represents a registered webpush subscription.
type registeredSubscription struct { type registeredSubscription struct {
ID uuid.UUID `json:"id"` ID uuid.UUID `json:"id"`
Subscription *webpush.Subscription `json:"-"` Subscription *webpush.Subscription `json:"-"`
@@ -63,13 +67,21 @@ type state struct {
apiKey apiKey apiKey apiKey
template pageTemplate template pageTemplate
summaries sync.Map // summaries maps location keys to their latest weather summary
summaries sync.Map
// summaryChans stores a map of location key to the corresponding summary channel
// which is used to track summary updates
summaryChans map[string]chan string summaryChans map[string]chan string
subscriptions map[string][]registeredSubscription // subscriptions maps location keys to the list of registered subscriptions
// that are subscribed to updates for the location
subscriptions map[string][]registeredSubscription
// subscriptionsMutex syncs writes to subscriptions
subscriptionsMutex sync.Mutex subscriptionsMutex sync.Mutex
vapidPublicKey string // vapidPublicKey is the base64 url encoded VAPID public key
vapidPublicKey string
// vapidPrivateKey is the base64 url encoded VAPID private key
vapidPrivateKey string vapidPrivateKey string
} }
@@ -133,6 +145,7 @@ func main() {
var schedulers []gocron.Scheduler var schedulers []gocron.Scheduler
// schedule periodic updates of weather summary for each supported location
for locKey, loc := range supportedLocations { for locKey, loc := range supportedLocations {
l, err := time.LoadLocation(loc.ianaName) l, err := time.LoadLocation(loc.ianaName)
if err != nil { if err != nil {
@@ -159,6 +172,7 @@ func main() {
state.subscriptions[locKey] = []registeredSubscription{} state.subscriptions[locKey] = []registeredSubscription{}
state.summaryChans[locKey] = c state.summaryChans[locKey] = c
// listen for summary updates, and publish updates to all update subscribers via web push
go listenForSummaryUpdates(&state, locKey) go listenForSummaryUpdates(&state, locKey)
s.Start() s.Start()
@@ -399,7 +413,9 @@ func registerSubscription(state *state, sub *updateSubscription) (*registeredSub
} }
for _, l := range sub.Locations { for _, l := range sub.Locations {
state.subscriptionsMutex.Lock()
state.subscriptions[l] = append(state.subscriptions[l], reg) state.subscriptions[l] = append(state.subscriptions[l], reg)
state.subscriptionsMutex.Unlock()
} }
return &reg, nil return &reg, nil
@@ -450,6 +466,13 @@ func updateSummaries(state *state, locKey string, loc *location) {
func listenForSummaryUpdates(state *state, locKey string) { func listenForSummaryUpdates(state *state, locKey string) {
c := state.summaryChans[locKey] c := state.summaryChans[locKey]
opts := webpush.Options{
VAPIDPublicKey: state.vapidPublicKey,
VAPIDPrivateKey: state.vapidPrivateKey,
TTL: 30,
}
for { for {
select { select {
case summary := <-c: case summary := <-c:
@@ -460,12 +483,7 @@ func listenForSummaryUpdates(state *state, locKey string) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
_, err := webpush.SendNotificationWithContext(state.ctx, []byte(summary), sub.Subscription, &opts)
_, err := webpush.SendNotificationWithContext(state.ctx, []byte(summary), sub.Subscription, &webpush.Options{
VAPIDPublicKey: state.vapidPublicKey,
VAPIDPrivateKey: state.vapidPrivateKey,
TTL: 30,
})
if err != nil { if err != nil {
log.Printf("failed to send summary for %v to sub id %v: %e\n", locKey, sub.ID, err) log.Printf("failed to send summary for %v to sub id %v: %e\n", locKey, sub.ID, err)
} }