Skip to content

Commit 11f7b1b

Browse files
authored
chore: remove notifications experiment (#14869)
Notifications have proved stable in the [mainline release of v2.15](https://github.com/coder/coder/releases/tag/v2.15.0), and in preparation for v2.16 we're moving this to stable.
1 parent edb4485 commit 11f7b1b

File tree

17 files changed

+95
-90
lines changed

17 files changed

+95
-90
lines changed

cli/notifications_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ func createOpts(t *testing.T) *coderdtest.Options {
2020
t.Helper()
2121

2222
dt := coderdtest.DeploymentValues(t)
23-
dt.Experiments = []string{string(codersdk.ExperimentNotifications)}
2423
return &coderdtest.Options{
2524
DeploymentValues: dt,
2625
}

cli/server.go

Lines changed: 42 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,16 @@ import (
5656

5757
"cdr.dev/slog"
5858
"cdr.dev/slog/sloggers/sloghuman"
59-
"github.com/coder/coder/v2/coderd/entitlements"
60-
"github.com/coder/coder/v2/coderd/notifications/reports"
61-
"github.com/coder/coder/v2/coderd/runtimeconfig"
6259
"github.com/coder/pretty"
6360
"github.com/coder/quartz"
6461
"github.com/coder/retry"
6562
"github.com/coder/serpent"
6663
"github.com/coder/wgtunnel/tunnelsdk"
6764

65+
"github.com/coder/coder/v2/coderd/entitlements"
66+
"github.com/coder/coder/v2/coderd/notifications/reports"
67+
"github.com/coder/coder/v2/coderd/runtimeconfig"
68+
6869
"github.com/coder/coder/v2/buildinfo"
6970
"github.com/coder/coder/v2/cli/clilog"
7071
"github.com/coder/coder/v2/cli/cliui"
@@ -684,10 +685,6 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
684685
options.OIDCConfig = oc
685686
}
686687

687-
experiments := coderd.ReadExperiments(
688-
options.Logger, options.DeploymentValues.Experiments.Value(),
689-
)
690-
691688
// We'll read from this channel in the select below that tracks shutdown. If it remains
692689
// nil, that case of the select will just never fire, but it's important not to have a
693690
// "bare" read on this channel.
@@ -951,6 +948,33 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
951948
return xerrors.Errorf("write config url: %w", err)
952949
}
953950

951+
// Manage notifications.
952+
cfg := options.DeploymentValues.Notifications
953+
metrics := notifications.NewMetrics(options.PrometheusRegistry)
954+
helpers := templateHelpers(options)
955+
956+
// The enqueuer is responsible for enqueueing notifications to the given store.
957+
enqueuer, err := notifications.NewStoreEnqueuer(cfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
958+
if err != nil {
959+
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
960+
}
961+
options.NotificationsEnqueuer = enqueuer
962+
963+
// The notification manager is responsible for:
964+
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
965+
// - keeping the store updated with status updates
966+
notificationsManager, err := notifications.NewManager(cfg, options.Database, helpers, metrics, logger.Named("notifications.manager"))
967+
if err != nil {
968+
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
969+
}
970+
971+
// nolint:gocritic // TODO: create own role.
972+
notificationsManager.Run(dbauthz.AsSystemRestricted(ctx))
973+
974+
// Run report generator to distribute periodic reports.
975+
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
976+
defer notificationReportGenerator.Close()
977+
954978
// Since errCh only has one buffered slot, all routines
955979
// sending on it must be wrapped in a select/default to
956980
// avoid leaving dangling goroutines waiting for the
@@ -1007,38 +1031,6 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
10071031
options.WorkspaceUsageTracker = tracker
10081032
defer tracker.Close()
10091033

1010-
// Manage notifications.
1011-
var (
1012-
notificationsManager *notifications.Manager
1013-
)
1014-
if experiments.Enabled(codersdk.ExperimentNotifications) {
1015-
cfg := options.DeploymentValues.Notifications
1016-
metrics := notifications.NewMetrics(options.PrometheusRegistry)
1017-
helpers := templateHelpers(options)
1018-
1019-
// The enqueuer is responsible for enqueueing notifications to the given store.
1020-
enqueuer, err := notifications.NewStoreEnqueuer(cfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
1021-
if err != nil {
1022-
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
1023-
}
1024-
options.NotificationsEnqueuer = enqueuer
1025-
1026-
// The notification manager is responsible for:
1027-
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
1028-
// - keeping the store updated with status updates
1029-
notificationsManager, err = notifications.NewManager(cfg, options.Database, helpers, metrics, logger.Named("notifications.manager"))
1030-
if err != nil {
1031-
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
1032-
}
1033-
1034-
// nolint:gocritic // TODO: create own role.
1035-
notificationsManager.Run(dbauthz.AsSystemRestricted(ctx))
1036-
1037-
// Run report generator to distribute periodic reports.
1038-
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
1039-
defer notificationReportGenerator.Close()
1040-
}
1041-
10421034
// Wrap the server in middleware that redirects to the access URL if
10431035
// the request is not to a local IP.
10441036
var handler http.Handler = coderAPI.RootHandler
@@ -1158,19 +1150,17 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
11581150
// Cancel any remaining in-flight requests.
11591151
shutdownConns()
11601152

1161-
if notificationsManager != nil {
1162-
// Stop the notification manager, which will cause any buffered updates to the store to be flushed.
1163-
// If the Stop() call times out, messages that were sent but not reflected as such in the store will have
1164-
// their leases expire after a period of time and will be re-queued for sending.
1165-
// See CODER_NOTIFICATIONS_LEASE_PERIOD.
1166-
cliui.Info(inv.Stdout, "Shutting down notifications manager..."+"\n")
1167-
err = shutdownWithTimeout(notificationsManager.Stop, 5*time.Second)
1168-
if err != nil {
1169-
cliui.Warnf(inv.Stderr, "Notifications manager shutdown took longer than 5s, "+
1170-
"this may result in duplicate notifications being sent: %s\n", err)
1171-
} else {
1172-
cliui.Info(inv.Stdout, "Gracefully shut down notifications manager\n")
1173-
}
1153+
// Stop the notification manager, which will cause any buffered updates to the store to be flushed.
1154+
// If the Stop() call times out, messages that were sent but not reflected as such in the store will have
1155+
// their leases expire after a period of time and will be re-queued for sending.
1156+
// See CODER_NOTIFICATIONS_LEASE_PERIOD.
1157+
cliui.Info(inv.Stdout, "Shutting down notifications manager..."+"\n")
1158+
err = shutdownWithTimeout(notificationsManager.Stop, 5*time.Second)
1159+
if err != nil {
1160+
cliui.Warnf(inv.Stderr, "Notifications manager shutdown took longer than 5s, "+
1161+
"this may result in duplicate notifications being sent: %s\n", err)
1162+
} else {
1163+
cliui.Info(inv.Stdout, "Gracefully shut down notifications manager\n")
11741164
}
11751165

11761166
// Shut down provisioners before waiting for WebSockets

coderd/coderd.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@ import (
3737
"tailscale.com/util/singleflight"
3838

3939
"cdr.dev/slog"
40+
"github.com/coder/quartz"
41+
"github.com/coder/serpent"
42+
4043
"github.com/coder/coder/v2/coderd/entitlements"
4144
"github.com/coder/coder/v2/coderd/idpsync"
4245
"github.com/coder/coder/v2/coderd/runtimeconfig"
43-
"github.com/coder/quartz"
44-
"github.com/coder/serpent"
4546

4647
agentproto "github.com/coder/coder/v2/agent/proto"
4748
"github.com/coder/coder/v2/buildinfo"
@@ -1257,10 +1258,7 @@ func New(options *Options) *API {
12571258
})
12581259
})
12591260
r.Route("/notifications", func(r chi.Router) {
1260-
r.Use(
1261-
apiKeyMiddleware,
1262-
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentNotifications),
1263-
)
1261+
r.Use(apiKeyMiddleware)
12641262
r.Get("/settings", api.notificationsSettings)
12651263
r.Put("/settings", api.putNotificationsSettings)
12661264
r.Route("/templates", func(r chi.Router) {

coderd/notifications/manager.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type Manager struct {
5454

5555
runOnce sync.Once
5656
stopOnce sync.Once
57+
doneOnce sync.Once
5758
stop chan any
5859
done chan any
5960

@@ -153,7 +154,9 @@ func (m *Manager) Run(ctx context.Context) {
153154
// events, creating a notifier, and publishing bulk dispatch result updates to the store.
154155
func (m *Manager) loop(ctx context.Context) error {
155156
defer func() {
156-
close(m.done)
157+
m.doneOnce.Do(func() {
158+
close(m.done)
159+
})
157160
m.log.Info(context.Background(), "notification manager stopped")
158161
}()
159162

@@ -364,7 +367,9 @@ func (m *Manager) Stop(ctx context.Context) error {
364367
// If the notifier hasn't been started, we don't need to wait for anything.
365368
// This is only really during testing when we want to enqueue messages only but not deliver them.
366369
if m.notifier == nil {
367-
close(m.done)
370+
m.doneOnce.Do(func() {
371+
close(m.done)
372+
})
368373
} else {
369374
m.notifier.stop()
370375
}

coderd/notifications/notifications_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1187,7 +1187,6 @@ func createOpts(t *testing.T) *coderdtest.Options {
11871187
t.Helper()
11881188

11891189
dt := coderdtest.DeploymentValues(t)
1190-
dt.Experiments = []string{string(codersdk.ExperimentNotifications)}
11911190
return &coderdtest.Options{
11921191
DeploymentValues: dt,
11931192
}

coderd/notifications/reports/generator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func NewReportGenerator(ctx context.Context, logger slog.Logger, db database.Sto
4949
return nil
5050
}
5151

52-
err = reportFailedWorkspaceBuilds(ctx, logger, db, enqueuer, clk)
52+
err = reportFailedWorkspaceBuilds(ctx, logger, tx, enqueuer, clk)
5353
if err != nil {
5454
return xerrors.Errorf("unable to generate reports with failed workspace builds: %w", err)
5555
}

coderd/notifications_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ func createOpts(t *testing.T) *coderdtest.Options {
2020
t.Helper()
2121

2222
dt := coderdtest.DeploymentValues(t)
23-
dt.Experiments = []string{string(codersdk.ExperimentNotifications)}
2423
return &coderdtest.Options{
2524
DeploymentValues: dt,
2625
}

codersdk/deployment.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2901,7 +2901,7 @@ const (
29012901
// users to opt-in to via --experimental='*'.
29022902
// Experiments that are not ready for consumption by all users should
29032903
// not be included here and will be essentially hidden.
2904-
var ExperimentsAll = Experiments{ExperimentNotifications}
2904+
var ExperimentsAll = Experiments{}
29052905

29062906
// Experiments is a list of experiments.
29072907
// Multiple experiments may be enabled at the same time.

enterprise/coderd/coderd.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,6 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
448448
// with the below route, we need to register this route without any mounts or groups to make both work.
449449
r.With(
450450
apiKeyMiddleware,
451-
httpmw.RequireExperiment(api.AGPL.Experiments, codersdk.ExperimentNotifications),
452451
httpmw.ExtractNotificationTemplateParam(options.Database),
453452
).Put("/notifications/templates/{notification_template}/method", api.updateNotificationTemplateMethod)
454453
})

enterprise/coderd/notifications_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ func createOpts(t *testing.T) *coderdenttest.Options {
2323
t.Helper()
2424

2525
dt := coderdtest.DeploymentValues(t)
26-
dt.Experiments = []string{string(codersdk.ExperimentNotifications)}
2726
return &coderdenttest.Options{
2827
Options: &coderdtest.Options{
2928
DeploymentValues: dt,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy