Skip to content

Commit 3e08289

Browse files
Im5tukblok
authored andcommitted
Alternative approach to fixing KeyAlreadyAddedException (#937)
1 parent 83fdffc commit 3e08289

File tree

2 files changed

+17
-29
lines changed

2 files changed

+17
-29
lines changed

lib/PuppeteerSharp/Helpers/MultiMap.cs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,18 @@ internal class MultiMap<TKey, TValue>
88
{
99
private readonly ConcurrentDictionary<TKey, List<TValue>> _map = new ConcurrentDictionary<TKey, List<TValue>>();
1010

11-
internal void Add(TKey key, TValue value)
12-
{
13-
if (_map.TryGetValue(key, out var set))
14-
{
15-
set.Add(value);
16-
}
17-
else
18-
{
19-
set = new List<TValue> { value };
20-
_map.TryAdd(key, set);
21-
}
22-
}
23-
11+
internal void Add(TKey key, TValue value)
12+
=> _map.GetOrAdd(key, k => new List<TValue>()).Add(value);
13+
2414
internal List<TValue> Get(TKey key)
2515
=> _map.TryGetValue(key, out var set) ? set : new List<TValue>();
2616

2717
internal bool Has(TKey key, TValue value)
2818
=> _map.TryGetValue(key, out var set) && set.Contains(value);
2919

30-
internal bool Delete(TKey key, TValue value)
20+
internal bool Delete(TKey key, TValue value)
3121
=> _map.TryGetValue(key, out var set) && set.Remove(value);
32-
22+
3323
internal TValue FirstValue(TKey key)
3424
=> _map.TryGetValue(key, out var set) ? set.FirstOrDefault() : default;
3525
}

lib/PuppeteerSharp/NetworkManager.cs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ internal class NetworkManager
1414
#region Private members
1515

1616
private readonly CDPSession _client;
17-
private readonly IDictionary<string, Request> _requestIdToRequest = new ConcurrentDictionary<string, Request>();
18-
private readonly IDictionary<string, RequestWillBeSentPayload> _requestIdToRequestWillBeSentEvent =
17+
private readonly ConcurrentDictionary<string, Request> _requestIdToRequest = new ConcurrentDictionary<string, Request>();
18+
private readonly ConcurrentDictionary<string, RequestWillBeSentPayload> _requestIdToRequestWillBeSentEvent =
1919
new ConcurrentDictionary<string, RequestWillBeSentPayload>();
2020
private readonly MultiMap<string, string> _requestHashToRequestIds = new MultiMap<string, string>();
2121
private readonly MultiMap<string, string> _requestHashToInterceptionIds = new MultiMap<string, string>();
@@ -142,14 +142,14 @@ private void OnLoadingFailed(LoadingFailedResponse e)
142142
{
143143
request.Failure = e.ErrorText;
144144
request.Response?.BodyLoadedTaskWrapper.TrySetResult(true);
145-
_requestIdToRequest.Remove(request.RequestId);
145+
_requestIdToRequest.TryRemove(request.RequestId, out _);
146146

147147
if (request.InterceptionId != null)
148148
{
149149
_attemptedAuthentications.Remove(request.InterceptionId);
150150
}
151151

152-
RequestFailed(this, new RequestEventArgs
152+
RequestFailed?.Invoke(this, new RequestEventArgs
153153
{
154154
Request = request
155155
});
@@ -163,7 +163,7 @@ private void OnLoadingFinished(LoadingFinishedResponse e)
163163
if (_requestIdToRequest.TryGetValue(e.RequestId, out var request))
164164
{
165165
request.Response?.BodyLoadedTaskWrapper.TrySetResult(true);
166-
_requestIdToRequest.Remove(request.RequestId);
166+
_requestIdToRequest.TryRemove(request.RequestId, out _);
167167

168168
if (request.InterceptionId != null)
169169
{
@@ -249,13 +249,10 @@ private async Task OnRequestInterceptedAsync(RequestInterceptedResponse e)
249249
var requestId = _requestHashToRequestIds.FirstValue(requestHash);
250250
if (requestId != null)
251251
{
252-
_requestIdToRequestWillBeSentEvent.TryGetValue(requestId, out var requestWillBeSentEvent);
253-
254-
if (requestWillBeSentEvent != null)
252+
if (_requestIdToRequestWillBeSentEvent.TryRemove(requestId, out var requestWillBeSentEvent))
255253
{
256254
await OnRequestAsync(requestWillBeSentEvent, e.InterceptionId);
257255
_requestHashToRequestIds.Delete(requestHash, requestId);
258-
_requestIdToRequestWillBeSentEvent.Remove(requestId);
259256
}
260257
}
261258
else
@@ -293,7 +290,7 @@ private async Task OnRequestAsync(RequestWillBeSentPayload e, string interceptio
293290

294291
_requestIdToRequest[e.RequestId] = request;
295292

296-
Request(this, new RequestEventArgs
293+
Request?.Invoke(this, new RequestEventArgs
297294
{
298295
Request = request
299296
});
@@ -322,20 +319,20 @@ private void HandleRequestRedirect(Request request, ResponsePayload responseMess
322319

323320
if (request.RequestId != null)
324321
{
325-
_requestIdToRequest.Remove(request.RequestId);
322+
_requestIdToRequest.TryRemove(request.RequestId, out _);
326323
}
327324

328325
if (request.InterceptionId != null)
329326
{
330327
_attemptedAuthentications.Remove(request.InterceptionId);
331328
}
332329

333-
Response(this, new ResponseCreatedEventArgs
330+
Response?.Invoke(this, new ResponseCreatedEventArgs
334331
{
335332
Response = response
336333
});
337334

338-
RequestFinished(this, new RequestEventArgs
335+
RequestFinished?.Invoke(this, new RequestEventArgs
339336
{
340337
Request = request
341338
});
@@ -356,7 +353,8 @@ private async Task OnRequestWillBeSentAsync(RequestWillBeSentPayload e)
356353
else
357354
{
358355
_requestHashToRequestIds.Add(requestHash, e.RequestId);
359-
_requestIdToRequestWillBeSentEvent.Add(e.RequestId, e);
356+
// Under load, we may get to this section more than once
357+
_requestIdToRequestWillBeSentEvent.TryAdd(e.RequestId, e);
360358
}
361359
return;
362360
}

0 commit comments

Comments
 (0)