From 4962f47577ef4560d1aec7dbd7b085086f813cc7 Mon Sep 17 00:00:00 2001 From: Richard Kettelerij Date: Mon, 24 Jun 2024 21:55:03 +0200 Subject: [PATCH 1/2] feat(slack) add rate limiting --- internal/service/slack.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/internal/service/slack.go b/internal/service/slack.go index 61a52de..2c46784 100644 --- a/internal/service/slack.go +++ b/internal/service/slack.go @@ -5,23 +5,38 @@ import ( "github.com/PDOK/uptime-operator/internal/model" "github.com/slack-go/slack" + "golang.org/x/time/rate" "sigs.k8s.io/controller-runtime/pkg/log" ) +const ( + nrOfMessagesPerSec = 1 + nrOfMessagesPerBurst = 10 +) + type Slack struct { webhookURL string channelID string + + rateLimit *rate.Limiter } func NewSlack(webhookURL, channelID string) *Slack { return &Slack{ webhookURL: webhookURL, channelID: channelID, + + // see https://api.slack.com/apis/rate-limits + rateLimit: rate.NewLimiter(nrOfMessagesPerSec, nrOfMessagesPerBurst), } } func (s *Slack) Send(ctx context.Context, message string) { - err := slack.PostWebhook(s.webhookURL, &slack.WebhookMessage{ + err := s.rateLimit.Wait(ctx) + if err != nil { + log.FromContext(ctx).Error(err, "failed waiting for slack rate limit") + } + err = slack.PostWebhook(s.webhookURL, &slack.WebhookMessage{ Channel: s.channelID, Text: message, Username: model.OperatorName, From 19c96f00a73b01bddd56a046a422acce062e46e2 Mon Sep 17 00:00:00 2001 From: Richard Kettelerij Date: Mon, 24 Jun 2024 22:00:35 +0200 Subject: [PATCH 2/2] chore: tidy --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index aca3007..2c578ff 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/slack-go/slack v0.13.0 github.com/stretchr/testify v1.9.0 github.com/traefik/traefik/v2 v2.11.5 + golang.org/x/time v0.5.0 golang.org/x/tools v0.22.0 k8s.io/apimachinery v0.30.2 k8s.io/client-go v0.30.2 @@ -72,7 +73,6 @@ require ( golang.org/x/sys v0.21.0 // indirect golang.org/x/term v0.21.0 // indirect golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect