Something went wrong. Try again.
Something went wrong. Try again.
bsky-bookmarks main.go
2.9 kB · 137 lines
Go
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138package main
import ( "context" "errors" "log" "log/slog" "os" "os/signal" "path" "syscall" "time"
"github.com/avast/retry-go/v4" "github.com/bugsnag/bugsnag-go/v2" "github.com/joho/godotenv" "github.com/willdot/bskyfeedgen/store")
const ( defaultServerAddr = "wss://jetstream.atproto.tools/subscribe")
func main() { configureLogger()
err := godotenv.Load() if err != nil { if !os.IsNotExist(err) { log.Fatal("Error loading .env file") } }
signals := make(chan os.Signal, 1) signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)
enableJS := os.Getenv("ENABLE_JETSTREAM") bugsnagAPIKey := os.Getenv("BUGSNAG_API_KEY")
feedDidBase := os.Getenv("FEED_DID_BASE") if feedDidBase == "" { slog.Error("FEED_DID_BASE not set") os.Exit(1) } feedHost := os.Getenv("FEED_HOST_NAME") if feedHost == "" { slog.Error("FEED_HOST_NAME not set") os.Exit(1) } dbMountPath := os.Getenv("RAILWAY_VOLUME_MOUNT_PATH") if dbMountPath == "" { slog.Error("RAILWAY_VOLUME_MOUNT_PATH env not set") os.Exit(1) }
if bugsnagAPIKey != "" { bugsnag.Configure(bugsnag.Configuration{ APIKey: bugsnagAPIKey, ReleaseStage: "production", // The import paths for the Go packages containing your source files ProjectPackages: []string{"main", "github.com/willdot/bskyfeedgen"}, // more configuration options AutoCaptureSessions: false, }) }
dbFilename := path.Join(dbMountPath, "database.db") store, err := store.New(dbFilename) if err != nil { slog.Error("create new store", "error", err) _ = bugsnag.Notify(err) return } defer store.Close()
feeder := NewFeedGenerator(store)
ctx, cancel := context.WithCancel(context.Background()) defer cancel()
if enableJS == "true" { slog.Info("enabling jetstream consume") go consumeLoop(ctx, store) }
dmService, err := NewDmService(store, time.Second*30) if err != nil { slog.Error("create new dm service", "error", err) _ = bugsnag.Notify(err) return } go dmService.Start(ctx)
server, err := NewServer(443, feeder, feedHost, feedDidBase, store) if err != nil { slog.Error("create new server", "error", err) _ = bugsnag.Notify(err) return } go func() { <-signals cancel() _ = server.Stop(context.Background()) }()
server.Run()
// give time for bugsnags to be sent time.Sleep(time.Second)}
func consumeLoop(ctx context.Context, store *store.Store) { handler := handler{ store: store, }
jsServerAddr := os.Getenv("JS_SERVER_ADDR") if jsServerAddr == "" { jsServerAddr = defaultServerAddr }
consumer := NewConsumer(jsServerAddr, slog.Default(), &handler)
_ = retry.Do(func() error { err := consumer.Consume(ctx) if err != nil { if errors.Is(err, context.Canceled) { return nil } slog.Error("consume loop", "error", err) return err } return nil }, retry.Attempts(0)) // retry indefinitly until context canceled
slog.Warn("exiting consume loop")}