1- using System ;
1+ using System ;
22using System . Linq ;
33using System . Threading . Tasks ;
44using Newtonsoft . Json . Linq ;
1111using Microsoft . Extensions . Logging ;
1212
1313namespace WebAssembly . Net . Debugging {
14- internal class SessionId {
15- public string sessionId ;
14+ internal struct SessionId {
15+ public readonly string sessionId ;
16+
17+ public SessionId ( string sessionId )
18+ {
19+ this . sessionId = sessionId ;
20+ }
21+
22+ public override int GetHashCode ( )
23+ => sessionId ? . GetHashCode ( ) ?? 0 ;
24+
25+ public override bool Equals ( object obj )
26+ => ( obj is SessionId ) ? ( ( SessionId ) obj ) . sessionId == sessionId : false ;
27+
28+ public override string ToString ( )
29+ => $ "session-{ sessionId } ";
1630 }
1731
18- internal class MessageId : SessionId {
19- public int id ;
32+ internal struct MessageId {
33+ public readonly string sessionId ;
34+ public readonly int id ;
35+
36+ public MessageId ( string sessionId , int id )
37+ {
38+ this . sessionId = sessionId ;
39+ this . id = id ;
40+ }
41+
42+ public static implicit operator SessionId ( MessageId id )
43+ => new SessionId ( id . sessionId ) ;
44+
45+ public override string ToString ( )
46+ => $ "msg-{ sessionId } :::{ id } ";
47+
48+ public override int GetHashCode ( )
49+ => ( sessionId ? . GetHashCode ( ) ?? 0 ) ^ id . GetHashCode ( ) ;
50+
51+ public override bool Equals ( object obj )
52+ => ( obj is MessageId ) ? ( ( MessageId ) obj ) . sessionId == sessionId && ( ( MessageId ) obj ) . id == id : false ;
2053 }
2154
2255 internal struct Result {
@@ -28,17 +61,17 @@ internal struct Result {
2861
2962 Result ( JObject result , JObject error )
3063 {
31- if ( result != null && error != null )
32- throw new ArgumentException ( $ "Both { nameof ( result ) } and { nameof ( error ) } arguments cannot be non-null.") ;
33-
34- bool resultHasError = String . Compare ( ( result ? [ "result" ] as JObject ) ? [ "subtype" ] ? . Value < string > ( ) , "error" ) == 0 ;
35- if ( result != null && resultHasError ) {
36- this . Value = null ;
37- this . Error = result ;
38- } else {
39- this . Value = result ;
40- this . Error = error ;
41- }
64+ if ( result != null && error != null )
65+ throw new ArgumentException ( $ "Both { nameof ( result ) } and { nameof ( error ) } arguments cannot be non-null.") ;
66+
67+ bool resultHasError = String . Compare ( ( result ? [ "result" ] as JObject ) ? [ "subtype" ] ? . Value < string > ( ) , "error" ) == 0 ;
68+ if ( result != null && resultHasError ) {
69+ this . Value = null ;
70+ this . Error = result ;
71+ } else {
72+ this . Value = result ;
73+ this . Error = error ;
74+ }
4275 }
4376
4477 public static Result FromJson ( JObject obj )
@@ -120,12 +153,13 @@ public Task Pump (CancellationToken token)
120153 internal class DevToolsProxy {
121154 TaskCompletionSource < bool > side_exception = new TaskCompletionSource < bool > ( ) ;
122155 TaskCompletionSource < bool > client_initiated_close = new TaskCompletionSource < bool > ( ) ;
123- List < ( MessageId , TaskCompletionSource < Result > ) > pending_cmds = new List < ( MessageId , TaskCompletionSource < Result > ) > ( ) ;
156+ Dictionary < MessageId , TaskCompletionSource < Result > > pending_cmds = new Dictionary < MessageId , TaskCompletionSource < Result > > ( ) ;
124157 ClientWebSocket browser ;
125158 WebSocket ide ;
126159 int next_cmd_id ;
127160 List < Task > pending_ops = new List < Task > ( ) ;
128161 List < DevToolsQueue > queues = new List < DevToolsQueue > ( ) ;
162+
129163 protected readonly ILogger logger ;
130164
131165 public DevToolsProxy ( ILoggerFactory loggerFactory )
@@ -219,11 +253,11 @@ void OnResponse (MessageId id, Result result)
219253 {
220254 //logger.LogTrace ("got id {0} res {1}", id, result);
221255 // Fixme
222- var idx = pending_cmds . FindIndex ( e => e . Item1 . id == id . id && e . Item1 . sessionId == id . sessionId ) ;
223- var item = pending_cmds [ idx ] ;
224- pending_cmds . RemoveAt ( idx ) ;
225-
226- item . Item2 . SetResult ( result ) ;
256+ if ( pending_cmds . Remove ( id , out var task ) ) {
257+ task . SetResult ( result ) ;
258+ return ;
259+ }
260+ logger . LogError ( "Cannot respond to command: {id} with result: {result} - command is not pending" , id , result ) ;
227261 }
228262
229263 void ProcessBrowserMessage ( string msg , CancellationToken token )
@@ -232,17 +266,20 @@ void ProcessBrowserMessage (string msg, CancellationToken token)
232266 var res = JObject . Parse ( msg ) ;
233267
234268 if ( res [ "id" ] == null )
235- pending_ops . Add ( OnEvent ( new SessionId { sessionId = res [ "sessionId" ] ? . Value < string > ( ) } , res [ "method" ] . Value < string > ( ) , res [ "params" ] as JObject , token ) ) ;
269+ pending_ops . Add ( OnEvent ( new SessionId ( res [ "sessionId" ] ? . Value < string > ( ) ) , res [ "method" ] . Value < string > ( ) , res [ "params" ] as JObject , token ) ) ;
236270 else
237- OnResponse ( new MessageId { id = res [ "id" ] . Value < int > ( ) , sessionId = res [ "sessionId" ] ? . Value < string > ( ) } , Result . FromJson ( res ) ) ;
271+ OnResponse ( new MessageId ( res [ "sessionId" ] ? . Value < string > ( ) , res [ "id" ] . Value < int > ( ) ) , Result . FromJson ( res ) ) ;
238272 }
239273
240274 void ProcessIdeMessage ( string msg , CancellationToken token )
241275 {
242276 Log ( "protocol" , $ "ide: { msg } ") ;
243277 if ( ! string . IsNullOrEmpty ( msg ) ) {
244278 var res = JObject . Parse ( msg ) ;
245- pending_ops . Add ( OnCommand ( new MessageId { id = res [ "id" ] . Value < int > ( ) , sessionId = res [ "sessionId" ] ? . Value < string > ( ) } , res [ "method" ] . Value < string > ( ) , res [ "params" ] as JObject , token ) ) ;
279+ pending_ops . Add ( OnCommand (
280+ new MessageId ( res [ "sessionId" ] ? . Value < string > ( ) , res [ "id" ] . Value < int > ( ) ) ,
281+ res [ "method" ] . Value < string > ( ) ,
282+ res [ "params" ] as JObject , token ) ) ;
246283 }
247284 }
248285
@@ -263,9 +300,9 @@ Task<Result> SendCommandInternal (SessionId sessionId, string method, JObject ar
263300 } ) ;
264301 var tcs = new TaskCompletionSource < Result > ( ) ;
265302
266- var msgId = new MessageId { id = id , sessionId = sessionId . sessionId } ;
303+ var msgId = new MessageId ( sessionId . sessionId , id ) ;
267304 //Log ("verbose", $"add cmd id {sessionId}-{id}");
268- pending_cmds . Add ( ( msgId , tcs ) ) ;
305+ pending_cmds [ msgId ] = tcs ;
269306
270307 Send ( this . browser , o , token ) ;
271308 return tcs . Task ;
0 commit comments