Skip to content

Commit 8078328

Browse files
authored
Merge pull request #34 from strvmarv/CoreUpdates
SF-6804: StackifyLib: Frequent Calls to GetEC2InstanceId
2 parents 609dae4 + 724627e commit 8078328

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

Src/StackifyLib/Config.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,16 @@ public static void LoadSettings()
7474
{
7575
ErrorSessionGoodKeys = CaptureErrorSessionWhitelist.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
7676
}
77-
77+
78+
// SF-6804: Frequent Calls to GetEC2InstanceId
79+
var captureEc2InstanceMetadataUpdateThresholdMinutes = Get("Stackify.Ec2InstanceMetadataUpdateThresholdMinutes", "");
80+
if (string.IsNullOrWhiteSpace(captureEc2InstanceMetadataUpdateThresholdMinutes) == false)
81+
{
82+
if (int.TryParse(captureEc2InstanceMetadataUpdateThresholdMinutes, out int minutes) && minutes > 0)
83+
{
84+
Ec2InstanceMetadataUpdateThresholdMinutes = minutes;
85+
}
86+
}
7887
}
7988
catch (Exception ex)
8089
{
@@ -109,6 +118,8 @@ public static void LoadSettings()
109118

110119
public static string CaptureErrorCookiesBlacklist { get; set; } = ".ASPXAUTH";
111120

121+
public static int Ec2InstanceMetadataUpdateThresholdMinutes { get; set; } = 60;
122+
112123

113124
/// <summary>
114125
/// Attempts to fetch a setting value given the key.

Src/StackifyLib/Models/EnvironmentDetail.cs

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,33 @@ private void GetAzureInfo()
100100
}
101101

102102
// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#d0e30002
103-
const string EC2InstanceIdUrl = "http://169.254.169.254/latest/meta-data/instance-id";
103+
private const string EC2InstanceIdUrl = "http://169.254.169.254/latest/meta-data/instance-id";
104+
public static readonly object ec2InstanceLock = new object();
105+
private static DateTimeOffset? ec2InstanceIdLastUpdate = null;
106+
private static string ec2InstanceId = null;
104107

105108
/// <summary>
106109
/// Get the EC2 Instance name if it exists else null
107110
/// </summary>
108111
#if NET451 || NET45 || NET40
109112
public static string GetEC2InstanceId()
110113
{
114+
string r = null;
115+
116+
// SF-6804: Frequent Calls to GetEC2InstanceId
117+
bool skipEc2InstanceIdUpdate = false;
118+
var threshold = TimeSpan.FromMinutes(Config.Ec2InstanceMetadataUpdateThresholdMinutes);
119+
lock (ec2InstanceLock)
120+
{
121+
skipEc2InstanceIdUpdate = ec2InstanceIdLastUpdate != null && ec2InstanceIdLastUpdate < DateTimeOffset.UtcNow.Subtract(threshold);
122+
r = string.IsNullOrWhiteSpace(ec2InstanceId) ? null : ec2InstanceId;
123+
}
124+
125+
if (skipEc2InstanceIdUpdate)
126+
{
127+
return r;
128+
}
129+
111130
try
112131
{
113132
var request = (HttpWebRequest)WebRequest.Create(EC2InstanceIdUrl);
@@ -123,22 +142,44 @@ public static string GetEC2InstanceId()
123142
using (var reader = new StreamReader(responseStream, encoding))
124143
{
125144
var id = reader.ReadToEnd();
126-
return string.IsNullOrWhiteSpace(id) ? null : id;
145+
r = string.IsNullOrWhiteSpace(id) ? null : id;
127146
}
128147
}
129148
}
130-
return null;
131149
}
132150
}
133151
catch // if not in aws this will timeout
134152
{
135-
return null;
153+
r = null;
136154
}
137155

156+
lock (ec2InstanceLock)
157+
{
158+
ec2InstanceId = r;
159+
ec2InstanceIdLastUpdate = DateTimeOffset.UtcNow;
160+
}
161+
162+
return r;
138163
}
139164
#else
140165
public static async Task<string> GetEC2InstanceId()
141166
{
167+
string r = null;
168+
169+
// SF-6804: Frequent Calls to GetEC2InstanceId
170+
bool skipEc2InstanceIdUpdate = false;
171+
var threshold = TimeSpan.FromMinutes(Config.Ec2InstanceMetadataUpdateThresholdMinutes);
172+
lock (ec2InstanceLock)
173+
{
174+
skipEc2InstanceIdUpdate = ec2InstanceIdLastUpdate != null && ec2InstanceIdLastUpdate < DateTimeOffset.UtcNow.Subtract(threshold);
175+
r = string.IsNullOrWhiteSpace(ec2InstanceId) ? null : ec2InstanceId;
176+
}
177+
178+
if (skipEc2InstanceIdUpdate)
179+
{
180+
return r;
181+
}
182+
142183
try
143184
{
144185

@@ -152,17 +193,23 @@ public static async Task<string> GetEC2InstanceId()
152193
if (statusCode >= 200 && statusCode < 300)
153194
{
154195
string id = await content.Content.ReadAsStringAsync();
155-
return string.IsNullOrWhiteSpace(id) ? null : id;
196+
r = string.IsNullOrWhiteSpace(id) ? null : id;
156197
}
157198
}
158199

159200
}
160201
catch // if not in aws this will timeout
161202
{
162-
return null;
203+
r = null;
163204
}
164205

165-
return null;
206+
lock (ec2InstanceLock)
207+
{
208+
ec2InstanceId = r;
209+
ec2InstanceIdLastUpdate = DateTimeOffset.UtcNow;
210+
}
211+
212+
return r;
166213
}
167214
#endif
168215
/// <summary>
@@ -269,7 +316,7 @@ public EnvironmentDetail(bool loadDetails)
269316
this.IsAzureWorkerRole = false;
270317

271318
//Logger global properties would override everything
272-
319+
273320
if (!string.IsNullOrEmpty(Config.AppName))
274321
{
275322
ConfiguredAppName = Config.AppName;

0 commit comments

Comments
 (0)