Skip to content

Commit a940c87

Browse files
Adds the latency plugin. Closes #321 (#327)
1 parent 339307d commit a940c87

File tree

4 files changed

+57
-5
lines changed

4 files changed

+57
-5
lines changed

m365-developer-proxy-abstractions/PluginEvents.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ public void RaiseOptionsLoaded(OptionsLoadedArgs args) {
186186
OptionsLoaded?.Invoke(this, args);
187187
}
188188

189-
public void RaiseProxyBeforeRequest(ProxyRequestArgs args) {
190-
BeforeRequest?.Invoke(this, args);
189+
public async Task RaiseProxyBeforeRequest(ProxyRequestArgs args) {
190+
await BeforeRequest?.InvokeAsync(this, args, null);
191191
}
192192

193193
public async Task RaiseProxyBeforeResponse(ProxyResponseArgs args) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.Extensions.Configuration;
5+
using Microsoft365.DeveloperProxy.Abstractions;
6+
7+
namespace Microsoft365.DeveloperProxy.Plugins.RandomErrors;
8+
9+
public class LatencyConfiguration {
10+
public int MinMs { get; set; } = 0;
11+
public int MaxMs { get; set; } = 5000;
12+
}
13+
14+
public class LatencyPlugin : BaseProxyPlugin {
15+
private readonly LatencyConfiguration _configuration = new();
16+
17+
public override string Name => nameof(LatencyPlugin);
18+
private readonly Random _random;
19+
20+
public LatencyPlugin() {
21+
_random = new Random();
22+
}
23+
24+
public override void Register(IPluginEvents pluginEvents,
25+
IProxyContext context,
26+
ISet<UrlToWatch> urlsToWatch,
27+
IConfigurationSection? configSection = null) {
28+
base.Register(pluginEvents, context, urlsToWatch, configSection);
29+
30+
configSection?.Bind(_configuration);
31+
pluginEvents.BeforeRequest += OnRequest;
32+
}
33+
34+
private async Task OnRequest(object? sender, ProxyRequestArgs e) {
35+
if (_urlsToWatch is not null
36+
&& e.ShouldExecute(_urlsToWatch)) {
37+
var delay = _random.Next(_configuration.MinMs, _configuration.MaxMs);
38+
_logger?.LogRequest(new[] { $"Delaying request for {delay}ms" }, MessageType.Chaos, new LoggingContext(e.Session));
39+
await Task.Delay(delay);
40+
}
41+
}
42+
}

m365-developer-proxy/ProxyEngine.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,13 @@ async Task OnRequest(object sender, SessionEventArgs e) {
356356

357357
e.UserData = e.HttpClient.Request;
358358
_logger.LogRequest(new[] { $"{e.HttpClient.Request.Method} {e.HttpClient.Request.Url}" }, MessageType.InterceptedRequest, new LoggingContext(e));
359-
HandleRequest(e);
359+
await HandleRequest(e);
360360
}
361361
}
362362

363-
private void HandleRequest(SessionEventArgs e) {
363+
private async Task HandleRequest(SessionEventArgs e) {
364364
ResponseState responseState = new ResponseState();
365-
_pluginEvents.RaiseProxyBeforeRequest(new ProxyRequestArgs(e, _throttledRequests, responseState));
365+
await _pluginEvents.RaiseProxyBeforeRequest(new ProxyRequestArgs(e, _throttledRequests, responseState));
366366

367367
// We only need to set the proxy header if the proxy has not set a response and the request is going to be sent to the target.
368368
if (!responseState.HasBeenSet) {

m365-developer-proxy/m365proxyrc.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
{
22
"plugins": [
3+
{
4+
"name": "LatencyPlugin",
5+
"enabled": false,
6+
"pluginPath": "plugins\\m365-developer-proxy-plugins.dll",
7+
"configSection": "latencyPlugin"
8+
},
39
{
410
"name": "RetryAfterPlugin",
511
"enabled": true,
@@ -137,6 +143,10 @@
137143
"cachingGuidance": {
138144
"cacheThresholdSeconds": 5
139145
},
146+
"latencyPlugin": {
147+
"minMs": 200,
148+
"maxMs": 10000
149+
},
140150
"rate": 50,
141151
"labelMode": "text",
142152
"logLevel": "info"

0 commit comments

Comments
 (0)