Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

92 rader
2.8 KiB

  1. package decoder
  2. import (
  3. "context"
  4. "log/slog"
  5. "sync"
  6. "github.com/AFASystems/presence/internal/pkg/common/appcontext"
  7. "github.com/AFASystems/presence/internal/pkg/config"
  8. "github.com/AFASystems/presence/internal/pkg/decoder"
  9. "github.com/AFASystems/presence/internal/pkg/kafkaclient"
  10. "github.com/AFASystems/presence/internal/pkg/logger"
  11. "github.com/AFASystems/presence/internal/pkg/model"
  12. )
  13. // DecoderApp holds dependencies for the decoder service.
  14. type DecoderApp struct {
  15. Cfg *config.Config
  16. KafkaManager *kafkaclient.KafkaManager
  17. AppState *appcontext.AppState
  18. ParserRegistry *model.ParserRegistry
  19. ChRaw chan model.BeaconAdvertisement
  20. ChParser chan model.KafkaParser
  21. Cleanup func()
  22. wg sync.WaitGroup
  23. }
  24. // New creates a DecoderApp with Kafka readers (rawbeacons, parser) and writer (alertbeacons).
  25. func New(cfg *config.Config) (*DecoderApp, error) {
  26. appState := appcontext.NewAppState()
  27. kafkaManager := kafkaclient.InitKafkaManager()
  28. srvLogger, cleanup := logger.CreateLogger("decoder.log")
  29. slog.SetDefault(srvLogger)
  30. readerTopics := []string{"rawbeacons", "parser"}
  31. writerTopics := []string{"alertbeacons"}
  32. kafkaManager.PopulateKafkaManager(cfg.KafkaURL, "decoder", readerTopics)
  33. kafkaManager.PopulateKafkaManager(cfg.KafkaURL, "", writerTopics)
  34. slog.Info("decoder service initialized", "readers", readerTopics, "writers", writerTopics)
  35. registry := &model.ParserRegistry{
  36. ParserList: make(map[string]model.BeaconParser),
  37. }
  38. return &DecoderApp{
  39. Cfg: cfg,
  40. KafkaManager: kafkaManager,
  41. AppState: appState,
  42. ParserRegistry: registry,
  43. ChRaw: make(chan model.BeaconAdvertisement, config.LARGE_CHANNEL_SIZE),
  44. ChParser: make(chan model.KafkaParser, config.SMALL_CHANNEL_SIZE),
  45. Cleanup: cleanup,
  46. }, nil
  47. }
  48. // Run starts Kafka consumers and the event loop until ctx is cancelled.
  49. func (a *DecoderApp) Run(ctx context.Context) {
  50. a.wg.Add(2)
  51. go kafkaclient.Consume(a.KafkaManager.GetReader("rawbeacons"), a.ChRaw, ctx, &a.wg)
  52. go kafkaclient.Consume(a.KafkaManager.GetReader("parser"), a.ChParser, ctx, &a.wg)
  53. for {
  54. select {
  55. case <-ctx.Done():
  56. return
  57. case msg := <-a.ChRaw:
  58. decoder.ProcessIncoming(msg, a.AppState, a.KafkaManager.GetWriter("alertbeacons"), a.ParserRegistry)
  59. case msg := <-a.ChParser:
  60. switch msg.ID {
  61. case "add":
  62. a.ParserRegistry.Register(msg.Config.Name, msg.Config)
  63. case "delete":
  64. a.ParserRegistry.Unregister(msg.Name)
  65. case "update":
  66. a.ParserRegistry.Register(msg.Config.Name, msg.Config)
  67. }
  68. }
  69. }
  70. }
  71. // Shutdown waits for consumers and cleans up.
  72. func (a *DecoderApp) Shutdown() {
  73. a.wg.Wait()
  74. a.KafkaManager.CleanKafkaReaders()
  75. a.KafkaManager.CleanKafkaWriters()
  76. if a.Cleanup != nil {
  77. a.Cleanup()
  78. }
  79. slog.Info("decoder service shutdown complete")
  80. }