44 *--------------------------------------------------------------------------------------------*/
55'use strict' ;
66
7- import winjs = require ( 'vs/base/common/winjs.base' ) ;
8- import marshalling = require ( 'vs/base/common/marshalling' ) ;
9- import errors = require ( 'vs/base/common/errors' ) ;
7+ import { TPromise } from 'vs/base/common/winjs.base' ;
8+ import * as marshalling from 'vs/base/common/marshalling' ;
9+ import * as errors from 'vs/base/common/errors' ;
1010import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc' ;
1111import { LazyPromise } from "vs/workbench/services/extensions/node/lazyPromise" ;
1212
13- let lastMessageId = 0 ;
14- const pendingRPCReplies : { [ msgId : string ] : LazyPromise ; } = { } ;
15-
16- class MessageFactory {
17- public static cancel ( req : string ) : string {
18- return `{"cancel":"${ req } "}` ;
19- }
20-
21- public static request ( req : string , rpcId : string , method : string , args : any [ ] ) : string {
22- return `{"req":"${ req } ","rpcId":"${ rpcId } ","method":"${ method } ","args":${ marshalling . stringify ( args ) } }` ;
23- }
24-
25- public static replyOK ( req : string , res : any ) : string {
26- if ( typeof res === 'undefined' ) {
27- return `{"seq":"${ req } "}` ;
28- }
29- return `{"seq":"${ req } ","res":${ marshalling . stringify ( res ) } }` ;
30- }
31-
32- public static replyErr ( req : string , err : any ) : string {
33- if ( typeof err === 'undefined' ) {
34- return `{"seq":"${ req } ","err":null}` ;
35- }
36- return `{"seq":"${ req } ","err":${ marshalling . stringify ( errors . transformErrorForSerialization ( err ) ) } }` ;
37- }
38- }
39-
4013export interface IManyHandler {
4114 handle ( rpcId : string , method : string , args : any [ ] ) : any ;
4215}
4316
4417export interface IRemoteCom {
45- callOnRemote ( proxyId : string , path : string , args : any [ ] ) : winjs . TPromise < any > ;
18+ callOnRemote ( proxyId : string , path : string , args : any [ ] ) : TPromise < any > ;
4619 setManyHandler ( handler : IManyHandler ) : void ;
4720}
4821
49- /**
50- * Sends/Receives multiple messages in one go:
51- * - multiple messages to be sent from one stack get sent in bulk at `process.nextTick`.
52- * - each incoming message is handled in a separate `process.nextTick`.
53- */
54- class RPCMultiplexer {
55-
56- private readonly _protocol : IMessagePassingProtocol ;
57- private readonly _onMessage : ( msg : string ) => void ;
58- private readonly _receiveOneMessageBound : ( ) => void ;
59- private readonly _sendAccumulatedBound : ( ) => void ;
60-
61- private _messagesToSend : string [ ] ;
62- private _messagesToReceive : string [ ] ;
63-
64- constructor ( protocol : IMessagePassingProtocol , onMessage : ( msg : string ) => void ) {
65- this . _protocol = protocol ;
66- this . _onMessage = onMessage ;
67- this . _receiveOneMessageBound = this . _receiveOneMessage . bind ( this ) ;
68- this . _sendAccumulatedBound = this . _sendAccumulated . bind ( this ) ;
69-
70- this . _messagesToSend = [ ] ;
71- this . _messagesToReceive = [ ] ;
72-
73- this . _protocol . onMessage ( data => {
74- // console.log('RECEIVED ' + rawmsg.length + ' MESSAGES.');
75- if ( this . _messagesToReceive . length === 0 ) {
76- process . nextTick ( this . _receiveOneMessageBound ) ;
77- }
78-
79- this . _messagesToReceive = this . _messagesToReceive . concat ( data ) ;
80- } ) ;
81- }
82-
83- private _receiveOneMessage ( ) : void {
84- const rawmsg = this . _messagesToReceive . shift ( ) ;
85-
86- if ( this . _messagesToReceive . length > 0 ) {
87- process . nextTick ( this . _receiveOneMessageBound ) ;
88- }
89-
90- this . _onMessage ( rawmsg ) ;
91- }
92-
93- private _sendAccumulated ( ) : void {
94- const tmp = this . _messagesToSend ;
95- this . _messagesToSend = [ ] ;
96- this . _protocol . send ( tmp ) ;
97- }
98-
99- public send ( msg : string ) : void {
100- if ( this . _messagesToSend . length === 0 ) {
101- process . nextTick ( this . _sendAccumulatedBound ) ;
102- }
103- this . _messagesToSend . push ( msg ) ;
104- }
22+ export function createProxyProtocol ( protocol : IMessagePassingProtocol ) : IRemoteCom {
23+ return new RPCManager ( protocol ) ;
10524}
10625
10726export class RPCManager implements IRemoteCom {
10827
10928 private _bigHandler : IManyHandler ;
110- private readonly _invokedHandlers : { [ req : string ] : winjs . TPromise < any > ; } ;
29+ private _lastMessageId : number ;
30+ private readonly _invokedHandlers : { [ req : string ] : TPromise < any > ; } ;
31+ private readonly _pendingRPCReplies : { [ msgId : string ] : LazyPromise ; } ;
11132 private readonly _multiplexor : RPCMultiplexer ;
11233
11334 constructor ( protocol : IMessagePassingProtocol ) {
11435 this . _bigHandler = null ;
36+ this . _lastMessageId = 0 ;
11537 this . _invokedHandlers = Object . create ( null ) ;
38+ this . _pendingRPCReplies = { } ;
11639 this . _multiplexor = new RPCMultiplexer ( protocol , ( msg ) => this . _receiveOneMessage ( msg ) ) ;
11740 }
11841
11942 private _receiveOneMessage ( rawmsg : string ) : void {
12043 let msg = marshalling . parse ( rawmsg ) ;
12144
12245 if ( msg . seq ) {
123- if ( ! pendingRPCReplies . hasOwnProperty ( msg . seq ) ) {
46+ if ( ! this . _pendingRPCReplies . hasOwnProperty ( msg . seq ) ) {
12447 console . warn ( 'Got reply to unknown seq' ) ;
12548 return ;
12649 }
127- let reply = pendingRPCReplies [ msg . seq ] ;
128- delete pendingRPCReplies [ msg . seq ] ;
50+ let reply = this . _pendingRPCReplies [ msg . seq ] ;
51+ delete this . _pendingRPCReplies [ msg . seq ] ;
12952
13053 if ( msg . err ) {
13154 let err = msg . err ;
@@ -174,21 +97,21 @@ export class RPCManager implements IRemoteCom {
17497 } ) ;
17598 }
17699
177- private _invokeHandler ( rpcId : string , method : string , args : any [ ] ) : winjs . TPromise < any > {
100+ private _invokeHandler ( rpcId : string , method : string , args : any [ ] ) : TPromise < any > {
178101 try {
179- return winjs . TPromise . as ( this . _bigHandler . handle ( rpcId , method , args ) ) ;
102+ return TPromise . as ( this . _bigHandler . handle ( rpcId , method , args ) ) ;
180103 } catch ( err ) {
181- return winjs . TPromise . wrapError ( err ) ;
104+ return TPromise . wrapError ( err ) ;
182105 }
183106 }
184107
185- public callOnRemote ( proxyId : string , path : string , args : any [ ] ) : winjs . TPromise < any > {
186- let req = String ( ++ lastMessageId ) ;
108+ public callOnRemote ( proxyId : string , path : string , args : any [ ] ) : TPromise < any > {
109+ let req = String ( ++ this . _lastMessageId ) ;
187110 let result = new LazyPromise ( ( ) => {
188111 this . _multiplexor . send ( MessageFactory . cancel ( req ) ) ;
189112 } ) ;
190113
191- pendingRPCReplies [ req ] = result ;
114+ this . _pendingRPCReplies [ req ] = result ;
192115
193116 this . _multiplexor . send ( MessageFactory . request ( req , proxyId , path , args ) ) ;
194117
@@ -200,6 +123,84 @@ export class RPCManager implements IRemoteCom {
200123 }
201124}
202125
203- export function createProxyProtocol ( protocol : IMessagePassingProtocol ) : IRemoteCom {
204- return new RPCManager ( protocol ) ;
126+ /**
127+ * Sends/Receives multiple messages in one go:
128+ * - multiple messages to be sent from one stack get sent in bulk at `process.nextTick`.
129+ * - each incoming message is handled in a separate `process.nextTick`.
130+ */
131+ class RPCMultiplexer {
132+
133+ private readonly _protocol : IMessagePassingProtocol ;
134+ private readonly _onMessage : ( msg : string ) => void ;
135+ private readonly _receiveOneMessageBound : ( ) => void ;
136+ private readonly _sendAccumulatedBound : ( ) => void ;
137+
138+ private _messagesToSend : string [ ] ;
139+ private _messagesToReceive : string [ ] ;
140+
141+ constructor ( protocol : IMessagePassingProtocol , onMessage : ( msg : string ) => void ) {
142+ this . _protocol = protocol ;
143+ this . _onMessage = onMessage ;
144+ this . _receiveOneMessageBound = this . _receiveOneMessage . bind ( this ) ;
145+ this . _sendAccumulatedBound = this . _sendAccumulated . bind ( this ) ;
146+
147+ this . _messagesToSend = [ ] ;
148+ this . _messagesToReceive = [ ] ;
149+
150+ this . _protocol . onMessage ( data => {
151+ // console.log('RECEIVED ' + rawmsg.length + ' MESSAGES.');
152+ if ( this . _messagesToReceive . length === 0 ) {
153+ process . nextTick ( this . _receiveOneMessageBound ) ;
154+ }
155+
156+ this . _messagesToReceive = this . _messagesToReceive . concat ( data ) ;
157+ } ) ;
158+ }
159+
160+ private _receiveOneMessage ( ) : void {
161+ const rawmsg = this . _messagesToReceive . shift ( ) ;
162+
163+ if ( this . _messagesToReceive . length > 0 ) {
164+ process . nextTick ( this . _receiveOneMessageBound ) ;
165+ }
166+
167+ this . _onMessage ( rawmsg ) ;
168+ }
169+
170+ private _sendAccumulated ( ) : void {
171+ const tmp = this . _messagesToSend ;
172+ this . _messagesToSend = [ ] ;
173+ this . _protocol . send ( tmp ) ;
174+ }
175+
176+ public send ( msg : string ) : void {
177+ if ( this . _messagesToSend . length === 0 ) {
178+ process . nextTick ( this . _sendAccumulatedBound ) ;
179+ }
180+ this . _messagesToSend . push ( msg ) ;
181+ }
182+ }
183+
184+ class MessageFactory {
185+ public static cancel ( req : string ) : string {
186+ return `{"cancel":"${ req } "}` ;
187+ }
188+
189+ public static request ( req : string , rpcId : string , method : string , args : any [ ] ) : string {
190+ return `{"req":"${ req } ","rpcId":"${ rpcId } ","method":"${ method } ","args":${ marshalling . stringify ( args ) } }` ;
191+ }
192+
193+ public static replyOK ( req : string , res : any ) : string {
194+ if ( typeof res === 'undefined' ) {
195+ return `{"seq":"${ req } "}` ;
196+ }
197+ return `{"seq":"${ req } ","res":${ marshalling . stringify ( res ) } }` ;
198+ }
199+
200+ public static replyErr ( req : string , err : any ) : string {
201+ if ( typeof err === 'undefined' ) {
202+ return `{"seq":"${ req } ","err":null}` ;
203+ }
204+ return `{"seq":"${ req } ","err":${ marshalling . stringify ( errors . transformErrorForSerialization ( err ) ) } }` ;
205+ }
205206}
0 commit comments