@@ -6,14 +6,21 @@ import { parseHeader } from "./header.ts";
66import { deserializeMessage , Message , serializeMessage } from "./message.ts" ;
77
88type Socket = Deno . Reader & Deno . Writer ;
9+ interface CommandTask {
10+ requestId : number ;
11+ db : string ;
12+ body : Document ;
13+ }
914
1015let nextRequestId = 0 ;
1116
1217export class WireProtocol {
1318 #socket: Socket ;
14- #pending = false ;
15- #pendingOps: Map < number , Deferred < Message > > = new Map ( ) ;
19+ #isPendingResponse = false ;
20+ #isPendingRequest = false ;
21+ #pendingResponses: Map < number , Deferred < Message > > = new Map ( ) ;
1622 #reader: BufReader ;
23+ #commandQueue: CommandTask [ ] = [ ] ;
1724
1825 #connectionId: number = 0 ;
1926
@@ -38,26 +45,18 @@ export class WireProtocol {
3845
3946 async command < T = Document > ( db : string , body : Document ) : Promise < T [ ] > {
4047 const requestId = nextRequestId ++ ;
41- const chunks = serializeMessage ( {
48+ const commandTask = {
4249 requestId,
43- responseTo : 0 ,
44- sections : [
45- {
46- document : {
47- ...body ,
48- $db : db ,
49- } ,
50- } ,
51- ] ,
52- } ) ;
50+ db,
51+ body,
52+ } ;
5353
54- for ( const chunk of chunks ) {
55- await Deno . writeAll ( this . #socket, chunk ) ;
56- }
54+ this . #commandQueue. push ( commandTask ) ;
55+ this . send ( ) ;
5756
58- this . #pendingOps . set ( requestId , deferred ( ) ) ;
57+ this . #pendingResponses . set ( requestId , deferred ( ) ) ;
5958 this . receive ( ) ;
60- const message = await this . #pendingOps . get ( requestId ) ;
59+ const message = await this . #pendingResponses . get ( requestId ) ;
6160
6261 let documents : T [ ] = [ ] ;
6362
@@ -72,10 +71,35 @@ export class WireProtocol {
7271 return documents ;
7372 }
7473
74+ private async send ( ) {
75+ if ( this . #isPendingRequest) return ;
76+ this . #isPendingRequest = true ;
77+ while ( this . #commandQueue. length > 0 ) {
78+ const task = this . #commandQueue. shift ( ) ! ;
79+ const chunks = serializeMessage ( {
80+ requestId : task . requestId ,
81+ responseTo : 0 ,
82+ sections : [
83+ {
84+ document : {
85+ ...task . body ,
86+ $db : task . db ,
87+ } ,
88+ } ,
89+ ] ,
90+ } ) ;
91+
92+ for ( const chunk of chunks ) {
93+ await Deno . writeAll ( this . #socket, chunk ) ;
94+ }
95+ }
96+ this . #isPendingRequest = false ;
97+ }
98+
7599 private async receive ( ) {
76- if ( this . #pending ) return ;
77- this . #pending = true ;
78- while ( this . #pendingOps . size > 0 ) {
100+ if ( this . #isPendingResponse ) return ;
101+ this . #isPendingResponse = true ;
102+ while ( this . #pendingResponses . size > 0 ) {
79103 const headerBuffer = await this . #reader. readFull ( new Uint8Array ( 16 ) ) ;
80104 assert ( headerBuffer ) ;
81105 const header = parseHeader ( headerBuffer ! ) ;
@@ -84,10 +108,10 @@ export class WireProtocol {
84108 ) ;
85109 assert ( bodyBuffer ) ;
86110 const reply = deserializeMessage ( header , bodyBuffer ! ) ;
87- const pendingMessage = this . #pendingOps . get ( header . responseTo ) ;
88- this . #pendingOps . delete ( header . responseTo ) ;
111+ const pendingMessage = this . #pendingResponses . get ( header . responseTo ) ;
112+ this . #pendingResponses . delete ( header . responseTo ) ;
89113 pendingMessage ?. resolve ( reply ) ;
90114 }
91- this . #pending = false ;
115+ this . #isPendingResponse = false ;
92116 }
93117}
0 commit comments