1
1
using System ;
2
- using System . Collections . Concurrent ;
3
- using System . Collections . Generic ;
4
2
using System . IO ;
5
3
using System . Linq ;
6
- using System . Text ;
7
4
using System . Threading ;
8
5
using System . Threading . Tasks ;
9
- using JsonRpc . Server ;
10
6
using JsonRpc . Server . Messages ;
11
7
using Newtonsoft . Json . Linq ;
12
8
@@ -27,9 +23,7 @@ public class InputHandler : IInputHandler
27
23
private Thread _inputThread ;
28
24
private readonly IRequestRouter _requestRouter ;
29
25
private readonly IResponseRouter _responseRouter ;
30
- private readonly BlockingCollection < ( RequestProcessType type , Func < Task > request ) > _queue ;
31
- private readonly CancellationTokenSource _cancelQueue ;
32
- private Thread _queueThread ;
26
+ private readonly ProcessScheduler _scheduler ;
33
27
34
28
public InputHandler (
35
29
TextReader input ,
@@ -46,19 +40,16 @@ IResponseRouter responseRouter
46
40
_requestProcessIdentifier = requestProcessIdentifier ;
47
41
_requestRouter = requestRouter ;
48
42
_responseRouter = responseRouter ;
49
- _queue = new BlockingCollection < ( RequestProcessType type , Func < Task > request ) > ( ) ;
50
- _cancelQueue = new CancellationTokenSource ( ) ;
51
43
44
+ _scheduler = new ProcessScheduler ( ) ;
52
45
_inputThread = new Thread ( ProcessInputStream ) { IsBackground = true } ;
53
-
54
- _queueThread = new Thread ( ProcessRequestQueue ) { IsBackground = true } ;
55
46
}
56
47
57
48
public void Start ( )
58
49
{
59
50
_outputHandler . Start ( ) ;
60
51
_inputThread . Start ( ) ;
61
- _queueThread . Start ( ) ;
52
+ _scheduler . Start ( ) ;
62
53
}
63
54
64
55
private async void ProcessInputStream ( )
@@ -145,24 +136,24 @@ private void HandleRequest(string request)
145
136
{
146
137
if ( item . IsRequest )
147
138
{
148
- _queue . Add ( (
139
+ _scheduler . Add (
149
140
type ,
150
141
async ( ) => {
151
142
var result = await _requestRouter . RouteRequest ( item . Request ) ;
152
143
153
144
_outputHandler . Send ( result . Value ) ;
154
145
}
155
- ) ) ;
146
+ ) ;
156
147
}
157
148
else if ( item . IsNotification )
158
149
{
159
- _queue . Add ( (
150
+ _scheduler . Add (
160
151
type ,
161
152
( ) => {
162
153
_requestRouter . RouteNotification ( item . Notification ) ;
163
154
return Task . CompletedTask ;
164
155
}
165
- ) ) ;
156
+ ) ;
166
157
}
167
158
else if ( item . IsError )
168
159
{
@@ -172,46 +163,12 @@ private void HandleRequest(string request)
172
163
}
173
164
}
174
165
175
- private Task Start ( Func < Task > request )
176
- {
177
- var t = request ( ) ;
178
- t . Start ( ) ;
179
- return t ;
180
- }
181
-
182
- private async void ProcessRequestQueue ( )
183
- {
184
- // see https://github.com/OmniSharp/csharp-language-server-protocol/issues/4
185
- var token = _cancelQueue . Token ;
186
- var waitables = new List < Task > ( ) ;
187
- while ( true )
188
- {
189
- if ( _queueThread == null ) return ;
190
- if ( _queue . TryTake ( out var item , Timeout . Infinite , token ) )
191
- {
192
- var ( type , request ) = item ;
193
- if ( type == RequestProcessType . Serial )
194
- {
195
- await Task . WhenAll ( waitables ) ;
196
- waitables . Clear ( ) ;
197
- await Start ( request ) ;
198
- }
199
- else if ( type == RequestProcessType . Parallel )
200
- {
201
- waitables . Add ( Start ( request ) ) ;
202
- }
203
- else
204
- throw new NotImplementedException ( "Only Serial and Parallel execution types can be handled currently" ) ;
205
- }
206
- }
207
- }
208
166
209
167
public void Dispose ( )
210
168
{
211
169
_outputHandler . Dispose ( ) ;
212
170
_inputThread = null ;
213
- _queueThread = null ;
214
- _cancelQueue . Cancel ( ) ;
171
+ _scheduler ? . Dispose ( ) ;
215
172
}
216
173
}
217
174
}
0 commit comments