Skip to content

Commit 41100b7

Browse files
authored
[Feature Flags] Admin panel improvements (#6895)
Does the following improvements to the feature flags admin panel: * Adds more debugging information * Refreshes the gallery's feature flags immediately after saving the flags Depends on NuGet/ServerCommon#275
1 parent 6647fe1 commit 41100b7

5 files changed

Lines changed: 71 additions & 12 deletions

File tree

src/NuGetGallery.Core/NuGetGallery.Core.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,19 +221,19 @@
221221
</ItemGroup>
222222
<ItemGroup>
223223
<PackageReference Include="NuGet.Services.Entities">
224-
<Version>2.42.0</Version>
224+
<Version>2.43.0</Version>
225225
</PackageReference>
226226
<PackageReference Include="NuGet.Services.FeatureFlags">
227-
<Version>2.42.0</Version>
227+
<Version>2.43.0</Version>
228228
</PackageReference>
229229
<PackageReference Include="NuGet.Services.Messaging.Email">
230-
<Version>2.42.0</Version>
230+
<Version>2.43.0</Version>
231231
</PackageReference>
232232
<PackageReference Include="NuGet.Services.Validation">
233-
<Version>2.42.0</Version>
233+
<Version>2.43.0</Version>
234234
</PackageReference>
235235
<PackageReference Include="NuGet.Services.Validation.Issues">
236-
<Version>2.42.0</Version>
236+
<Version>2.43.0</Version>
237237
</PackageReference>
238238
<PackageReference Include="NuGet.StrongName.AnglicanGeek.MarkdownMailer">
239239
<Version>1.2.0</Version>

src/NuGetGallery/Areas/Admin/Controllers/FeaturesController.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,45 @@
44
using System;
55
using System.Threading.Tasks;
66
using System.Web.Mvc;
7+
using NuGet.Services.FeatureFlags;
78
using NuGetGallery.Areas.Admin.ViewModels;
9+
using NuGetGallery.Configuration;
810
using NuGetGallery.Features;
911

1012
namespace NuGetGallery.Areas.Admin.Controllers
1113
{
1214
public class FeaturesController : AdminControllerBase
1315
{
1416
private readonly IEditableFeatureFlagStorageService _storage;
17+
private readonly IFeatureFlagCacheService _cache;
18+
private readonly IAppConfiguration _config;
1519

16-
public FeaturesController(IEditableFeatureFlagStorageService storage)
20+
public FeaturesController(
21+
IEditableFeatureFlagStorageService storage,
22+
IFeatureFlagCacheService cache,
23+
IAppConfiguration config)
1724
{
1825
_storage = storage ?? throw new ArgumentNullException(nameof(storage));
26+
_cache = cache ?? throw new ArgumentNullException(nameof(cache));
27+
_config = config ?? throw new ArgumentNullException(nameof(config));
1928
}
2029

2130
[HttpGet]
2231
public async virtual Task<ActionResult> Index()
2332
{
2433
var reference = await _storage.GetReferenceAsync();
34+
var lastUpdated = _cache.GetRefreshTimeOrNull();
35+
36+
TimeSpan? timeSinceLastRefresh = null;
37+
if (lastUpdated.HasValue)
38+
{
39+
timeSinceLastRefresh = DateTimeOffset.UtcNow.Subtract(lastUpdated.Value);
40+
}
2541

2642
return View(new FeatureFlagsViewModel
2743
{
44+
TimeSinceLastRefresh = timeSinceLastRefresh,
45+
RefreshInterval = _config.FeatureFlagsRefreshInterval,
2846
Flags = reference.FlagsJson,
2947
ContentId = reference.ContentId
3048
});
@@ -41,7 +59,12 @@ public async Task<ActionResult> Index(FeatureFlagsViewModel model)
4159
switch (result.Type)
4260
{
4361
case FeatureFlagSaveResultType.Ok:
44-
TempData["Message"] = "Your feature flags have been saved!";
62+
// The flags have been persisted. Refresh this instance's cache immediately.
63+
await _cache.RefreshAsync();
64+
65+
var refreshSeconds = _config.FeatureFlagsRefreshInterval.TotalSeconds;
66+
67+
TempData["Message"] = $"Your feature flags have been saved! It may take up to {refreshSeconds} seconds for this change to propagate everywhere.";
4568
return Redirect(Url.Action(actionName: "Index", controllerName: "Features"));
4669

4770
case FeatureFlagSaveResultType.Conflict:

src/NuGetGallery/Areas/Admin/ViewModels/FeatureFlagsViewModel.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System;
45
using System.ComponentModel.DataAnnotations;
56

67
namespace NuGetGallery.Areas.Admin.ViewModels
78
{
89
public class FeatureFlagsViewModel
910
{
11+
public TimeSpan RefreshInterval { get; set; }
12+
13+
public TimeSpan? TimeSinceLastRefresh { get; set; }
14+
15+
public bool IsOutdated
16+
{
17+
// Ideally, the feature flags refresh instantly at the refresh interval.
18+
// To account for random delays, we'll allow for up to a minute of drift before
19+
// showing a warning.
20+
get => TimeSinceLastRefresh > RefreshInterval.Add(TimeSpan.FromMinutes(1));
21+
}
22+
1023
[Required]
1124
public string Flags { get; set; }
1225

src/NuGetGallery/Areas/Admin/Views/Features/Index.cshtml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@
77
<section role="main" class="container main-container page-revalidation">
88
<h1>Feature flags</h1>
99

10+
@if (!Model.TimeSinceLastRefresh.HasValue)
11+
{
12+
@ViewHelpers.AlertWarning(
13+
@<text>
14+
The feature flags haven't loaded yet. Check the logs for errors.
15+
</text>)
16+
}
17+
else if (Model.IsOutdated)
18+
{
19+
@ViewHelpers.AlertWarning(
20+
@<text>
21+
The feature flags were last cached @Math.Round(Model.TimeSinceLastRefresh.Value.TotalSeconds) seconds ago
22+
but should refresh every @Model.RefreshInterval.TotalSeconds seconds. Check the logs for errors.
23+
</text>)
24+
}
25+
else
26+
{
27+
<p>
28+
The feature flags were last cached @Math.Round(Model.TimeSinceLastRefresh.Value.TotalSeconds) seconds ago
29+
and refresh every @Model.RefreshInterval.TotalSeconds seconds.
30+
</p>
31+
}
32+
1033
<div class="form-group danger-zone">
1134
<text>
1235
@using (Html.BeginForm("Index", "Features", FormMethod.Post))

src/NuGetGallery/NuGetGallery.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,7 @@
20922092
<Version>0.15.4</Version>
20932093
</PackageReference>
20942094
<PackageReference Include="NuGet.Services.Licenses">
2095-
<Version>2.42.0</Version>
2095+
<Version>2.43.0</Version>
20962096
</PackageReference>
20972097
<PackageReference Include="NuGet.StrongName.AnglicanGeek.MarkdownMailer">
20982098
<Version>1.2.0</Version>
@@ -2316,16 +2316,16 @@
23162316
<Version>5.0.0-preview1.5665</Version>
23172317
</PackageReference>
23182318
<PackageReference Include="NuGet.Services.KeyVault">
2319-
<Version>2.42.0</Version>
2319+
<Version>2.43.0</Version>
23202320
</PackageReference>
23212321
<PackageReference Include="NuGet.Services.Logging">
2322-
<Version>2.42.0</Version>
2322+
<Version>2.43.0</Version>
23232323
</PackageReference>
23242324
<PackageReference Include="NuGet.Services.Owin">
2325-
<Version>2.42.0</Version>
2325+
<Version>2.43.0</Version>
23262326
</PackageReference>
23272327
<PackageReference Include="NuGet.Services.Sql">
2328-
<Version>2.42.0</Version>
2328+
<Version>2.43.0</Version>
23292329
</PackageReference>
23302330
<PackageReference Include="Owin">
23312331
<Version>1.0.0</Version>

0 commit comments

Comments
 (0)