diff options
Diffstat (limited to 'pkg/discord/heartbeat.go')
| -rw-r--r-- | pkg/discord/heartbeat.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/pkg/discord/heartbeat.go b/pkg/discord/heartbeat.go new file mode 100644 index 0000000..5d2972f --- /dev/null +++ b/pkg/discord/heartbeat.go @@ -0,0 +1,67 @@ +package discord + +import ( + "context" + "math/rand" + "time" + + "github.com/rs/zerolog" +) + +type Heartbeat interface { + Start(ctx context.Context, interval uint64) + + ForceHeartbeat() + Ack() +} + +var _ Heartbeat = &HeartbeatImpl{} + +type HeartbeatImpl struct { + ctx context.Context + logger *zerolog.Logger + gateway Gateway +} + +func NewHeartbeat(logger *zerolog.Logger, gateway Gateway) *HeartbeatImpl { + return &HeartbeatImpl{ + ctx: nil, + logger: logger, + gateway: gateway, + } +} + +func (h *HeartbeatImpl) Start(ctx context.Context, interval uint64) { + h.ctx = ctx + go h.heartbeatRoutine(interval) +} + +func (h *HeartbeatImpl) ForceHeartbeat() { + h.gateway.Heartbeat() +} + +func (h *HeartbeatImpl) Ack() { + // What do we do here? + h.logger.Debug().Msg("received heartbeat ack") +} + +func (h *HeartbeatImpl) heartbeatRoutine(interval uint64) { + // REF: heartbeat_interval * jitter + jitter := rand.Intn(int(interval)) + time.Sleep(time.Duration(jitter) * time.Millisecond) + + ticker := time.NewTicker(time.Duration(interval) * time.Millisecond) + defer ticker.Stop() + + for { + select { + case <-h.ctx.Done(): + return + case <-ticker.C: + h.logger.Debug().Msg("sending heartbeat") + if err := h.gateway.Heartbeat(); err != nil { + h.logger.Error().Err(err).Msg("failed to send heartbeat") + } + } + } +} |
