Skip to content

Commit fa171fb

Browse files
authored
Remove target interceptors in favor of session events (#2397)
* Remove target interceptors in favor of session events * remove urlprefix from command line * remove extra call * event fixes * some tweaks * refactor some code * Maybe firefox needs more time
1 parent ddbc713 commit fa171fb

File tree

14 files changed

+85
-144
lines changed

14 files changed

+85
-144
lines changed

.github/workflows/on-push-do-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
- name: Run MarkdownSnippets
1010
run: |
1111
dotnet tool install --global MarkdownSnippets.Tool
12-
mdsnippets ${GITHUB_WORKSPACE} --url-prefix https://github.com/hardkoded/puppeteer-sharp/blob/master
12+
mdsnippets ${GITHUB_WORKSPACE}
1313
shell: bash
1414
- name: Push changes
1515
run: |

lib/PuppeteerSharp.Tests/test.runsettings

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
<RunSettings>
33
<!-- Configurations that affect the Test Framework -->
44
<RunConfiguration>
5-
<TestSessionTimeout>2700000</TestSessionTimeout>
5+
<TestSessionTimeout>3600000</TestSessionTimeout>
66
</RunConfiguration>
77
</RunSettings>

lib/PuppeteerSharp/Browser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ private async void OnAttachedToTargetAsync(object sender, TargetChangedArgs e)
392392
{
393393
try
394394
{
395-
if ((await e.Target.InitializedTask.ConfigureAwait(false)) == InitializationStatus.Success)
395+
if (await e.Target.InitializedTask.ConfigureAwait(false) == InitializationStatus.Success)
396396
{
397397
var args = new TargetChangedArgs { Target = e.Target };
398398
TargetCreated?.Invoke(this, args);

lib/PuppeteerSharp/BrowserData/Firefox.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace PuppeteerSharp.BrowserData
1111
public static class Firefox
1212
{
1313
/// <summary>
14-
/// Default firefoxbuild.
14+
/// Default firefox build.
1515
/// </summary>
1616
public const string DefaultBuildId = "FIREFOX_NIGHTLY";
1717

@@ -24,9 +24,9 @@ internal static string ResolveDownloadUrl(Platform platform, string buildId, str
2424

2525
internal static async Task<string> ResolveBuildIdAsync(string channel)
2626
{
27-
if (_cachedBuildIds.ContainsKey(channel))
27+
if (_cachedBuildIds.TryGetValue(channel, out var build))
2828
{
29-
return _cachedBuildIds[channel];
29+
return build;
3030
}
3131

3232
var version = await JsonUtils.GetAsync<Dictionary<string, string>>("https://product-details.mozilla.org/1.0/firefox_versions.json").ConfigureAwait(false);
@@ -40,7 +40,7 @@ internal static async Task<string> ResolveBuildIdAsync(string channel)
4040
return version[channel];
4141
}
4242

43-
internal static string RelativeExecutablePath(Platform platform, string builId)
43+
internal static string RelativeExecutablePath(Platform platform, string buildId)
4444
=> platform switch
4545
{
4646
Platform.MacOS or Platform.MacOSArm64 => Path.Combine(

lib/PuppeteerSharp/CDPSession.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ internal CDPSession(Connection connection, TargetType targetType, string session
3434
/// <inheritdoc/>
3535
public event EventHandler<SessionEventArgs> SessionDetached;
3636

37+
internal event EventHandler<SessionEventArgs> Ready;
38+
3739
/// <inheritdoc/>
3840
public TargetType TargetType { get; }
3941

@@ -49,9 +51,10 @@ internal CDPSession(Connection connection, TargetType targetType, string session
4951
/// <inheritdoc/>
5052
public ILoggerFactory LoggerFactory => Connection.LoggerFactory;
5153

52-
/// <inheritdoc cref="Connection"/>
5354
internal Connection Connection { get; private set; }
5455

56+
internal Target Target { get; set; }
57+
5558
/// <inheritdoc/>
5659
public async Task<T> SendAsync<T>(string method, object args = null)
5760
{
@@ -117,6 +120,8 @@ public Task DetachAsync()
117120

118121
internal bool HasPendingCallbacks() => !_callbacks.IsEmpty;
119122

123+
internal void OnSessionReady(CDPSession session) => Ready?.Invoke(this, new SessionEventArgs(session));
124+
120125
internal void OnMessage(ConnectionResponse obj)
121126
{
122127
var id = obj.Id;
@@ -159,11 +164,11 @@ internal void Close(string closeReason)
159164
}
160165

161166
internal void OnSessionAttached(CDPSession session)
162-
=> SessionAttached?.Invoke(this, new SessionEventArgs { Session = session });
167+
=> SessionAttached?.Invoke(this, new SessionEventArgs(session));
163168

164169
internal void OnSessionDetached(CDPSession session)
165-
=> SessionDetached?.Invoke(this, new SessionEventArgs { Session = session });
170+
=> SessionDetached?.Invoke(this, new SessionEventArgs(session));
166171

167-
internal ICollection<MessageTask> GetPendingMessages() => _callbacks.Values;
172+
internal IEnumerable<MessageTask> GetPendingMessages() => _callbacks.Values;
168173
}
169174
}

lib/PuppeteerSharp/ChromeTargetManager.cs

Lines changed: 30 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ internal class ChromeTargetManager : ITargetManager
1919
private readonly AsyncDictionaryHelper<string, Target> _attachedTargetsByTargetId = new("Target {0} not found");
2020
private readonly ConcurrentDictionary<string, Target> _attachedTargetsBySessionId = new();
2121
private readonly ConcurrentDictionary<string, TargetInfo> _discoveredTargetsByTargetId = new();
22-
private readonly ConcurrentDictionary<ICDPConnection, List<TargetInterceptor>> _targetInterceptors = new();
23-
private readonly List<string> _targetsIdsForInit = new();
22+
private readonly List<string> _targetsIdsForInit = [];
2423
private readonly TaskCompletionSource<bool> _initializeCompletionSource = new();
2524

2625
// Needed for .NET only to prevent race conditions between StoreExistingTargetsForInit and OnAttachedToTarget
@@ -100,18 +99,6 @@ public async Task InitializeAsync()
10099
await _initializeCompletionSource.Task.ConfigureAwait(false);
101100
}
102101

103-
public void AddTargetInterceptor(CDPSession session, TargetInterceptor interceptor)
104-
{
105-
var interceptors = _targetInterceptors.GetOrAdd(session, static _ => new());
106-
interceptors.Add(interceptor);
107-
}
108-
109-
public void RemoveTargetInterceptor(CDPSession session, TargetInterceptor interceptor)
110-
{
111-
_targetInterceptors.TryGetValue(session, out var interceptors);
112-
interceptors?.Remove(interceptor);
113-
}
114-
115102
private void StoreExistingTargetsForInit()
116103
{
117104
foreach (var kv in _discoveredTargetsByTargetId)
@@ -179,7 +166,6 @@ private void OnMessageReceived(object sender, MessageEventArgs e)
179166
private void Connection_SessionDetached(object sender, SessionEventArgs e)
180167
{
181168
e.Session.MessageReceived -= OnMessageReceived;
182-
_targetInterceptors.TryRemove(e.Session, out var _);
183169
}
184170

185171
private void OnTargetCreated(TargetCreatedResponse e)
@@ -247,35 +233,17 @@ private void OnTargetInfoChanged(TargetCreatedResponse e)
247233

248234
private async Task OnAttachedToTargetAsync(object sender, TargetAttachedToTargetResponse e)
249235
{
250-
var parent = sender as ICDPConnection;
236+
var parentSession = sender as ICDPConnection;
237+
251238
var targetInfo = e.TargetInfo;
252239
var session = _connection.GetSession(e.SessionId) ?? throw new PuppeteerException($"Session {e.SessionId} was not created.");
253240

254-
async Task SilentDetach()
255-
{
256-
try
257-
{
258-
await session.SendAsync("Runtime.runIfWaitingForDebugger").ConfigureAwait(false);
259-
await parent.SendAsync(
260-
"Target.detachFromTarget",
261-
new TargetDetachFromTargetRequest
262-
{
263-
SessionId = session.Id,
264-
}).ConfigureAwait(false);
265-
}
266-
catch (Exception ex)
267-
{
268-
_logger.LogError(ex, "silentDetach failed.");
269-
}
270-
}
271-
272241
if (!_connection.IsAutoAttached(targetInfo.TargetId))
273242
{
274243
return;
275244
}
276245

277-
if (targetInfo.Type == TargetType.ServiceWorker &&
278-
_connection.IsAutoAttached(targetInfo.TargetId))
246+
if (targetInfo.Type == TargetType.ServiceWorker)
279247
{
280248
await EnsureTargetsIdsForInitAsync().ConfigureAwait(false);
281249
FinishInitializationIfReady(targetInfo.TargetId);
@@ -292,8 +260,8 @@ await parent.SendAsync(
292260
return;
293261
}
294262

295-
var existingTarget = _attachedTargetsByTargetId.TryGetValue(targetInfo.TargetId, out var target);
296-
if (!existingTarget)
263+
var isExistingTarget = _attachedTargetsByTargetId.TryGetValue(targetInfo.TargetId, out var target);
264+
if (!isExistingTarget)
297265
{
298266
target = _targetFactoryFunc(targetInfo, session);
299267
}
@@ -309,8 +277,9 @@ await parent.SendAsync(
309277

310278
session.MessageReceived += OnMessageReceived;
311279

312-
if (existingTarget)
280+
if (isExistingTarget)
313281
{
282+
session.Target = target;
314283
_attachedTargetsBySessionId.TryAdd(session.Id, target);
315284
}
316285
else
@@ -321,24 +290,12 @@ await parent.SendAsync(
321290
_attachedTargetsBySessionId.TryAdd(session.Id, target);
322291
}
323292

324-
if (_targetInterceptors.TryGetValue(parent, out var interceptors))
325-
{
326-
foreach (var interceptor in interceptors)
327-
{
328-
Target parentTarget = null;
329-
if (parent is CDPSession parentSession && !_attachedTargetsBySessionId.TryGetValue(parentSession.Id, out parentTarget))
330-
{
331-
throw new PuppeteerException("Parent session not found in attached targets");
332-
}
333-
334-
interceptor(target, parentTarget);
335-
}
336-
}
293+
(parentSession as CDPSession)?.OnSessionReady(session);
337294

338295
await EnsureTargetsIdsForInitAsync().ConfigureAwait(false);
339296
_targetsIdsForInit.Remove(target.TargetId);
340297

341-
if (!existingTarget)
298+
if (!isExistingTarget)
342299
{
343300
TargetAvailable?.Invoke(this, new TargetChangedArgs { Target = target });
344301
}
@@ -360,6 +317,26 @@ await Task.WhenAll(
360317
{
361318
_logger.LogError(ex, "Failed to call setAutoAttach and runIfWaitingForDebugger");
362319
}
320+
321+
return;
322+
323+
async Task SilentDetach()
324+
{
325+
try
326+
{
327+
await session.SendAsync("Runtime.runIfWaitingForDebugger").ConfigureAwait(false);
328+
await parentSession!.SendAsync(
329+
"Target.detachFromTarget",
330+
new TargetDetachFromTargetRequest
331+
{
332+
SessionId = session.Id,
333+
}).ConfigureAwait(false);
334+
}
335+
catch (Exception ex)
336+
{
337+
_logger.LogError(ex, "silentDetach failed.");
338+
}
339+
}
363340
}
364341

365342
private async Task OnAttachedToTargetHandlingExceptionsAsync(object sender, string messageId, TargetAttachedToTargetResponse e)

lib/PuppeteerSharp/Connection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ private void ProcessIncomingMessage(ConnectionResponse obj)
306306
var session = new CDPSession(this, param.TargetInfo.Type, sessionId);
307307
_sessions.AddItem(sessionId, session);
308308

309-
SessionAttached?.Invoke(this, new SessionEventArgs { Session = session });
309+
SessionAttached?.Invoke(this, new SessionEventArgs(session));
310310

311311
if (obj.SessionId != null && _sessions.TryGetValue(obj.SessionId, out var parentSession))
312312
{
@@ -319,7 +319,7 @@ private void ProcessIncomingMessage(ConnectionResponse obj)
319319
if (_sessions.TryRemove(sessionId, out var session) && !session.IsClosed)
320320
{
321321
session.Close("Target.detachedFromTarget");
322-
SessionDetached?.Invoke(this, new SessionEventArgs() { Session = session });
322+
SessionDetached?.Invoke(this, new SessionEventArgs(session));
323323

324324
if (_sessions.TryGetValue(sessionId, out var parentSession))
325325
{

lib/PuppeteerSharp/FirefoxTargetManager.cs

Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,11 @@ internal class FirefoxTargetManager : ITargetManager
1616
private readonly Func<TargetInfo, CDPSession, Target> _targetFactoryFunc;
1717
private readonly Func<Target, bool> _targetFilterFunc;
1818
private readonly ILogger<FirefoxTargetManager> _logger;
19-
private readonly ConcurrentDictionary<ICDPConnection, List<TargetInterceptor>> _targetInterceptors = new();
2019
private readonly AsyncDictionaryHelper<string, Target> _availableTargetsByTargetId = new("Target {0} not found");
2120
private readonly ConcurrentDictionary<string, Target> _availableTargetsBySessionId = new();
2221
private readonly ConcurrentDictionary<string, TargetInfo> _discoveredTargetsByTargetId = new();
2322
private readonly TaskCompletionSource<bool> _initializeCompletionSource = new();
24-
private readonly List<string> _ignoredTargets = new();
25-
private List<string> _targetsIdsForInit = new();
23+
private List<string> _targetsIdsForInit = [];
2624

2725
public FirefoxTargetManager(
2826
Connection connection,
@@ -45,19 +43,6 @@ public FirefoxTargetManager(
4543

4644
public event EventHandler<TargetChangedArgs> TargetDiscovered;
4745

48-
public void AddTargetInterceptor(CDPSession session, TargetInterceptor interceptor)
49-
{
50-
var interceptors = _targetInterceptors.GetOrAdd(session, static _ => new());
51-
interceptors.Add(interceptor);
52-
}
53-
54-
public void RemoveTargetInterceptor(CDPSession session, TargetInterceptor interceptor)
55-
{
56-
_targetInterceptors.TryGetValue(session, out var interceptors);
57-
58-
interceptors?.Remove(interceptor);
59-
}
60-
6146
public async Task InitializeAsync()
6247
{
6348
await _connection.SendAsync("Target.setDiscoverTargets", new TargetSetDiscoverTargetsRequest
@@ -69,7 +54,7 @@ public async Task InitializeAsync()
6954
},
7055
}).ConfigureAwait(false);
7156

72-
_targetsIdsForInit = new List<string>(_discoveredTargetsByTargetId.Keys);
57+
_targetsIdsForInit = [.._discoveredTargetsByTargetId.Keys];
7358
await _initializeCompletionSource.Task.ConfigureAwait(false);
7459
}
7560

@@ -102,10 +87,7 @@ private void OnMessageReceived(object sender, MessageEventArgs e)
10287
}
10388

10489
private void Connection_SessionDetached(object sender, SessionEventArgs e)
105-
{
106-
e.Session.MessageReceived -= OnMessageReceived;
107-
_targetInterceptors.TryRemove(e.Session, out var _);
108-
}
90+
=> e.Session.MessageReceived -= OnMessageReceived;
10991

11092
private void OnTargetCreated(TargetCreatedResponse e)
11193
{
@@ -125,7 +107,6 @@ private void OnTargetCreated(TargetCreatedResponse e)
125107
var target = _targetFactoryFunc(e.TargetInfo, null);
126108
if (_targetFilterFunc != null && !_targetFilterFunc(target))
127109
{
128-
_ignoredTargets.Add(e.TargetInfo.TargetId);
129110
FinishInitializationIfReady(e.TargetInfo.TargetId);
130111
return;
131112
}
@@ -155,27 +136,15 @@ private void OnTargetDestroyed(TargetDestroyedResponse e)
155136

156137
private void OnAttachedToTarget(object sender, TargetAttachedToTargetResponse e)
157138
{
158-
var parent = sender as ICDPConnection;
139+
var parentSession = sender as CDPSession;
159140
var targetInfo = e.TargetInfo;
160141
var session = _connection.GetSession(e.SessionId) ?? throw new PuppeteerException($"Session {e.SessionId} was not created.");
161-
var existingTarget = _availableTargetsByTargetId.TryGetValue(targetInfo.TargetId, out var target);
142+
_availableTargetsByTargetId.TryGetValue(targetInfo.TargetId, out var target);
162143
session.MessageReceived += OnMessageReceived;
163-
144+
session.Target = target;
164145
_availableTargetsBySessionId.TryAdd(session.Id, target);
165146

166-
if (_targetInterceptors.TryGetValue(parent, out var interceptors))
167-
{
168-
foreach (var interceptor in interceptors)
169-
{
170-
Target parentTarget = null;
171-
if (parent is CDPSession parentSession && !_availableTargetsBySessionId.TryGetValue(parentSession.Id, out parentTarget))
172-
{
173-
throw new PuppeteerException("Parent session not found in attached targets");
174-
}
175-
176-
interceptor(target, parentTarget);
177-
}
178-
}
147+
parentSession?.OnSessionReady(session);
179148
}
180149

181150
private void FinishInitializationIfReady(string targetId = null)

lib/PuppeteerSharp/ICDPSession.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Threading.Tasks;
33
using Microsoft.Extensions.Logging;
4-
using Newtonsoft.Json.Linq;
54

65
namespace PuppeteerSharp
76
{

0 commit comments

Comments
 (0)