3
3
using System . Collections . Generic ;
4
4
using System . Threading ;
5
5
using System . Threading . Tasks ;
6
+ using Microsoft . Extensions . Logging ;
6
7
7
8
namespace OmniSharp . Extensions . JsonRpc
8
9
{
9
10
public class ProcessScheduler : IScheduler
10
11
{
11
- private readonly BlockingCollection < ( RequestProcessType type , Func < Task > request ) > _queue ;
12
+ private readonly ILogger < ProcessScheduler > _logger ;
13
+ private readonly BlockingCollection < ( RequestProcessType type , string name , Func < Task > request ) > _queue ;
12
14
private readonly CancellationTokenSource _cancel ;
13
15
private readonly Thread _thread ;
14
16
15
- public ProcessScheduler ( )
17
+ public ProcessScheduler ( ILoggerFactory loggerFactory )
16
18
{
17
- _queue = new BlockingCollection < ( RequestProcessType type , Func < Task > request ) > ( ) ;
19
+ _logger = loggerFactory . CreateLogger < ProcessScheduler > ( ) ;
20
+ _queue = new BlockingCollection < ( RequestProcessType type , string name , Func < Task > request ) > ( ) ;
18
21
_cancel = new CancellationTokenSource ( ) ;
19
22
_thread = new Thread ( ProcessRequestQueue ) { IsBackground = true , Name = "ProcessRequestQueue" } ;
20
23
}
@@ -24,9 +27,9 @@ public void Start()
24
27
_thread . Start ( ) ;
25
28
}
26
29
27
- public void Add ( RequestProcessType type , Func < Task > request )
30
+ public void Add ( RequestProcessType type , string name , Func < Task > request )
28
31
{
29
- _queue . Add ( ( type , request ) ) ;
32
+ _queue . Add ( ( type , name , request ) ) ;
30
33
}
31
34
32
35
private Task Start ( Func < Task > request )
@@ -42,7 +45,7 @@ private List<Task> RemoveCompleteTasks(List<Task> list)
42
45
if ( list . Count == 0 ) return list ;
43
46
44
47
var result = new List < Task > ( ) ;
45
- foreach ( var t in list )
48
+ foreach ( var t in list )
46
49
{
47
50
if ( t . IsFaulted )
48
51
{
@@ -69,20 +72,32 @@ private void ProcessRequestQueue()
69
72
{
70
73
if ( _queue . TryTake ( out var item , Timeout . Infinite , token ) )
71
74
{
72
- var ( type , request ) = item ;
73
- if ( type == RequestProcessType . Serial )
75
+ var ( type , name , request ) = item ;
76
+ try
74
77
{
75
- Task . WaitAll ( waitables . ToArray ( ) , token ) ;
76
- Start ( request ) . Wait ( token ) ;
78
+ if ( type == RequestProcessType . Serial )
79
+ {
80
+ Task . WaitAll ( waitables . ToArray ( ) , token ) ;
81
+ Start ( request ) . Wait ( token ) ;
82
+ }
83
+ else if ( type == RequestProcessType . Parallel )
84
+ {
85
+ waitables . Add ( Start ( request ) ) ;
86
+ }
87
+ else
88
+ throw new NotImplementedException ( "Only Serial and Parallel execution types can be handled currently" ) ;
89
+ waitables = RemoveCompleteTasks ( waitables ) ;
90
+ Interlocked . Exchange ( ref _TestOnly_NonCompleteTaskCount , waitables . Count ) ;
77
91
}
78
- else if ( type == RequestProcessType . Parallel )
92
+ catch ( OperationCanceledException ex ) when ( ex . CancellationToken == token )
79
93
{
80
- waitables . Add ( Start ( request ) ) ;
94
+ throw ;
95
+ }
96
+ catch ( Exception e )
97
+ {
98
+ // TODO: Create proper event ids
99
+ _logger . LogCritical ( Events . UnhandledRequest , e , "Unhandled exception executing request {Name}" , name ) ;
81
100
}
82
- else
83
- throw new NotImplementedException ( "Only Serial and Parallel execution types can be handled currently" ) ;
84
- waitables = RemoveCompleteTasks ( waitables ) ;
85
- Interlocked . Exchange ( ref _TestOnly_NonCompleteTaskCount , waitables . Count ) ;
86
101
}
87
102
}
88
103
}
@@ -112,4 +127,9 @@ public void Dispose()
112
127
_cancel . Dispose ( ) ;
113
128
}
114
129
}
130
+
131
+ static class Events
132
+ {
133
+ public static EventId UnhandledRequest = new EventId ( 1337_100 ) ;
134
+ }
115
135
}
0 commit comments