Hi @cshipley_6136 ,
Unfortunately we're really at a loss for how to troubleshoot the SQL Server further, and it's happening at the driver level. I'm not trying to "pass the buck" here, but it's most definitely NOT a ProGet issue (as in, code that we wrote and have control over).
This must be happening at a lower-level (like the sql server driver, dns resolution, kubernetes, front-end caching, etc).
Most likely, the /
vs /health
is related to caching an error, or some "deep internal" behavior of the SQL server driver (or bug on Linux?) that we're not aware of.
From here, it's going to make sense to bring in Microsoft, who will know how to troubleshoot/diagnose this further. The "TCP Provider, error: 40" is so generic, and means the same thing as Chrome's "name not resolved". Aside from the obvious, we have no idea what could cause such an error, nor do we know how to troubleshoot.
They may have some "secret flags" in the connection string that you can enable, etc.
I tried to search for help, but there are like one thousand results that are all over the place, from clearing DNS caching to rebooting, etc.
On our end, our code doesn't deal with any of these things... we just use the driver to invoke SQL Server commands. Here is the entirety of the /health
code:
private static readonly LazyCached<IList<Feed>> feeds = new(() => DB.Feeds_GetFeeds(false).Select(f => Feed.GetFeed(f)).ToList());
protected override async Task ProcessRequestAsync(AhHttpContext context)
{
context.Response.ContentType = "application/json";
using var writer = new JsonTextWriter(new StreamWriter(context.Response.OutputStream, InedoLib.UTF8Encoding)) { Formatting = Formatting.Indented };
// added for specific customer and not documented (EDO-9257)
if (string.Equals(context.Request.QueryString["dbcache"], "false", StringComparison.InvariantCultureIgnoreCase))
feeds.Invalidate();
writer.WriteStartObject();
writer.WritePropertyName("applicationName");
writer.WriteValue("ProGet");
try
{
var _ = feeds.Value;
writer.WritePropertyName("databaseStatus");
writer.WriteValue("OK");
writer.WritePropertyName("databaseStatusDetails");
writer.WriteNull();
}
catch (Exception ex)
{
writer.WritePropertyName("databaseStatus");
writer.WriteValue("Error");
writer.WritePropertyName("databaseStatusDetails");
writer.WriteValue(ex.Message);
}
writer.WritePropertyName("extensionsInstalled");
writer.WriteStartObject();
foreach (var e in ExtensionsManager.GetExtensions())
{
writer.WritePropertyName(e.Name);
writer.WriteValue(e.Version.ToString());
}
writer.WriteEndObject();
var license = LicensingInformation.Current;
writer.WritePropertyName("licenseStatus");
if (!license.IsValid)
{
writer.WriteValue("Error");
writer.WritePropertyName("licenseStatusDetail");
writer.WriteValue(license.LicenseKeyStatusDescription);
}
else
{
writer.WriteValue("OK");
writer.WritePropertyName("licenseStatusDetail");
writer.WriteNull();
}
writer.WritePropertyName("versionNumber");
writer.WriteValue(versionNumber.Value);
writer.WritePropertyName("releaseNumber");
writer.WriteValue(releaseNumber.Value);
var serviceStatus = await ProGetServiceMessenger.GetStatusAsync();
writer.WritePropertyName("serviceStatus");
writer.WriteValue(serviceStatus.Status == ExtendedServiceStatus.Running ? "OK" : "Error");
writer.WritePropertyName("serviceStatusDetail");
writer.WriteValue(serviceStatus.Status != ExtendedServiceStatus.Running ? serviceStatus.ErrorText : null);
var r = replicationStatus.Value;
writer.WritePropertyName("replicationStatus");
if (r != null)
{
writer.WriteRawValue(JsonConvert.SerializeObject(r, Formatting.Indented));
}
else
{
writer.WriteNull();
}
writer.WriteEndObject();
}
To "translate" what's happening, the stored procedure Feeds_GetFeeds
is invoked to test database connectivity. It's invoked following all of Microsoft's guidance for using the SQL Server driver.