service-notifications/main.go
James Coleman 42d3251251 Fix misrouted notifications from SQLite lock contention
send_message silently fell back to the default conversation whenever the
plan-time or slack-channel lookup errored, because the query error was
ignored. A transient "database is locked" (from the channel-creation/sync
routine holding the write lock while making slow Slack API calls) thus
misrouted a service notification to the admin DM instead of the event
channel.

- api.go: capture lookup errors and only treat gorm.ErrRecordNotFound as
  "no service / no channel"; on any other error, fail so the caller retries
  rather than posting to the wrong conversation.
- database.go: open SQLite with WAL journaling and a 10s busy timeout so
  reads proceed alongside the sync writer instead of locking.
- Bump version to 0.2.2.
2026-06-21 10:19:41 -05:00

59 lines
1.2 KiB
Go

package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/slack-go/slack"
"gorm.io/gorm"
)
const (
serviceName = "service-notifications"
serviceDescription = "Notifications for church services"
serviceVersion = "0.2.2"
)
// App is the global application structure for communicating between servers and storing information.
type App struct {
flags *Flags
config *Config
db *gorm.DB
slack *slack.Client
http *HTTPServer
}
var app *App
func main() {
app = new(App)
app.ParseFlags()
app.ReadConfig()
app.InitDB()
app.slack = slack.New(app.config.Slack.APIToken)
// If update is requested, run updates and end the program.
if app.flags.Update {
UpdatePCData()
UpdateSlackData()
CreateSlackChannels()
return
}
// Configure the HTTP server.
app.http = NewHTTPServer()
// Setup context with cancellation function to allow background services to gracefully stop.
ctx, ctxCancel := context.WithCancel(context.Background())
app.http.Start(ctx)
// Monitor common signals.
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
// Wiat for a signal.
<-c
// Stop the HTTP server and end.
ctxCancel()
}