Skip to content

Commit e6d99a3

Browse files
authored
[dotnet] [bidi] Deserialize message fast instead of defer it (#16403)
1 parent 4bd87aa commit e6d99a3

File tree

3 files changed

+20
-52
lines changed

3 files changed

+20
-52
lines changed

dotnet/src/webdriver/BiDi/Communication/Broker.cs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public sealed class Broker : IAsyncDisposable
3838
private readonly ITransport _transport;
3939

4040
private readonly ConcurrentDictionary<long, CommandInfo> _pendingCommands = new();
41-
private readonly BlockingCollection<MessageEvent> _pendingEvents = [];
41+
private readonly BlockingCollection<(string Method, EventArgs Params)> _pendingEvents = [];
4242
private readonly Dictionary<string, JsonTypeInfo> _eventTypesMap = [];
4343

4444
private readonly ConcurrentDictionary<string, List<EventHandler>> _eventHandlers = new();
@@ -143,20 +143,20 @@ public async Task<TResult> ExecuteCommandAsync<TCommand, TResult>(TCommand comma
143143
where TResult : EmptyResult
144144
{
145145
command.Id = Interlocked.Increment(ref _currentCommandId);
146-
var tcs = new TaskCompletionSource<JsonElement>(TaskCreationOptions.RunContinuationsAsynchronously);
146+
var tcs = new TaskCompletionSource<EmptyResult>(TaskCreationOptions.RunContinuationsAsynchronously);
147147
var timeout = options?.Timeout ?? TimeSpan.FromSeconds(30);
148148
using var cts = new CancellationTokenSource(timeout);
149149
cts.Token.Register(() => tcs.TrySetCanceled(cts.Token));
150-
var commandInfo = new CommandInfo(command.Id, command.ResultType, tcs);
150+
var commandInfo = new CommandInfo(command.Id, tcs, jsonResultTypeInfo);
151151
_pendingCommands[command.Id] = commandInfo;
152152
var data = JsonSerializer.SerializeToUtf8Bytes(command, jsonCommandTypeInfo);
153153

154154
await _transport.SendAsync(data, cts.Token).ConfigureAwait(false);
155-
var resultJson = await tcs.Task.ConfigureAwait(false);
156-
return JsonSerializer.Deserialize(resultJson, jsonResultTypeInfo)!;
155+
156+
return (TResult)await tcs.Task.ConfigureAwait(false);
157157
}
158158

159-
public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Action<TEventArgs> action, SubscriptionOptions? options, JsonTypeInfo jsonTypeInfo)
159+
public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Action<TEventArgs> action, SubscriptionOptions? options, JsonTypeInfo<TEventArgs> jsonTypeInfo)
160160
where TEventArgs : EventArgs
161161
{
162162
_eventTypesMap[eventName] = jsonTypeInfo;
@@ -185,7 +185,7 @@ public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Act
185185
}
186186
}
187187

188-
public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Func<TEventArgs, Task> func, SubscriptionOptions? options, JsonTypeInfo jsonTypeInfo)
188+
public async Task<Subscription> SubscribeAsync<TEventArgs>(string eventName, Func<TEventArgs, Task> func, SubscriptionOptions? options, JsonTypeInfo<TEventArgs> jsonTypeInfo)
189189
where TEventArgs : EventArgs
190190
{
191191
_eventTypesMap[eventName] = jsonTypeInfo;
@@ -301,7 +301,7 @@ private void ProcessReceivedMessage(byte[]? data)
301301

302302
if (_pendingCommands.TryGetValue(id.Value, out var successCommand))
303303
{
304-
successCommand.TaskCompletionSource.SetResult(JsonElement.ParseValue(ref resultReader));
304+
successCommand.TaskCompletionSource.SetResult((EmptyResult)JsonSerializer.Deserialize(ref resultReader, successCommand.JsonResultTypeInfo)!);
305305
_pendingCommands.TryRemove(id.Value, out _);
306306
}
307307
else
@@ -318,7 +318,7 @@ private void ProcessReceivedMessage(byte[]? data)
318318
{
319319
var eventArgs = (EventArgs)JsonSerializer.Deserialize(ref paramsReader, eventInfo)!;
320320

321-
var messageEvent = new MessageEvent(method, eventArgs);
321+
var messageEvent = (method, eventArgs);
322322
_pendingEvents.Add(messageEvent);
323323
}
324324
else
@@ -345,10 +345,12 @@ private void ProcessReceivedMessage(byte[]? data)
345345
}
346346
}
347347

348-
class CommandInfo(long id, Type resultType, TaskCompletionSource<JsonElement> taskCompletionSource)
348+
class CommandInfo(long id, TaskCompletionSource<EmptyResult> taskCompletionSource, JsonTypeInfo jsonResultTypeInfo)
349349
{
350350
public long Id { get; } = id;
351351

352-
public TaskCompletionSource<JsonElement> TaskCompletionSource { get; } = taskCompletionSource;
352+
public TaskCompletionSource<EmptyResult> TaskCompletionSource { get; } = taskCompletionSource;
353+
354+
public JsonTypeInfo JsonResultTypeInfo { get; } = jsonResultTypeInfo;
353355
};
354356
}

dotnet/src/webdriver/BiDi/Communication/EventHandler.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,32 +23,32 @@
2323

2424
namespace OpenQA.Selenium.BiDi.Communication;
2525

26-
public abstract class EventHandler(string eventName, Type eventArgsType, IEnumerable<BrowsingContext.BrowsingContext>? contexts = null)
26+
public abstract class EventHandler(string eventName, IEnumerable<BrowsingContext.BrowsingContext>? contexts = null)
2727
{
2828
public string EventName { get; } = eventName;
29-
public Type EventArgsType { get; set; } = eventArgsType;
29+
3030
public IEnumerable<BrowsingContext.BrowsingContext>? Contexts { get; } = contexts;
3131

32-
public abstract ValueTask InvokeAsync(object args);
32+
public abstract ValueTask InvokeAsync(EventArgs args);
3333
}
3434

3535
internal class AsyncEventHandler<TEventArgs>(string eventName, Func<TEventArgs, Task> func, IEnumerable<BrowsingContext.BrowsingContext>? contexts = null)
36-
: EventHandler(eventName, typeof(TEventArgs), contexts) where TEventArgs : EventArgs
36+
: EventHandler(eventName, contexts) where TEventArgs : EventArgs
3737
{
3838
private readonly Func<TEventArgs, Task> _func = func;
3939

40-
public override async ValueTask InvokeAsync(object args)
40+
public override async ValueTask InvokeAsync(EventArgs args)
4141
{
4242
await _func((TEventArgs)args).ConfigureAwait(false);
4343
}
4444
}
4545

4646
internal class SyncEventHandler<TEventArgs>(string eventName, Action<TEventArgs> action, IEnumerable<BrowsingContext.BrowsingContext>? contexts = null)
47-
: EventHandler(eventName, typeof(TEventArgs), contexts) where TEventArgs : EventArgs
47+
: EventHandler(eventName, contexts) where TEventArgs : EventArgs
4848
{
4949
private readonly Action<TEventArgs> _action = action;
5050

51-
public override ValueTask InvokeAsync(object args)
51+
public override ValueTask InvokeAsync(EventArgs args)
5252
{
5353
_action((TEventArgs)args);
5454

dotnet/src/webdriver/BiDi/Communication/Message.cs

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)