19
19
using System . Collections . Generic ;
20
20
using System . IO ;
21
21
using System . Management . Automation . Language ;
22
+ using System . Threading . Tasks ;
23
+ using System . Threading ;
22
24
using System . Text . Json ;
23
25
24
-
25
-
26
26
namespace Microsoft . Azure . PowerShell . Tools . AzPredictor
27
27
{
28
28
/// <summary>
@@ -32,7 +32,13 @@ sealed class ParameterValuePredictor
32
32
{
33
33
private readonly ConcurrentDictionary < string , string > _localParameterValues = new ConcurrentDictionary < string , string > ( ) ;
34
34
35
- private readonly Dictionary < string , Dictionary < string , string > > _command_param_to_resource_map ;
35
+ private System . Threading . Mutex _mutex = new System . Threading . Mutex ( false , "paramValueHistoryFile_update" ) ;
36
+
37
+ private readonly Dictionary < string , Dictionary < string , string > > _commandParamToResourceMap ;
38
+
39
+ private string _paramValueHistoryFilePath = "" ;
40
+ private CancellationTokenSource _cancellationTokenSource ;
41
+
36
42
37
43
private ITelemetryClient _telemetryClient ;
38
44
@@ -49,17 +55,46 @@ public ParameterValuePredictor(ITelemetryClient telemetryClient)
49
55
50
56
try
51
57
{
52
- _command_param_to_resource_map = JsonSerializer . Deserialize < Dictionary < string , Dictionary < string , string > > > ( File . ReadAllText ( mappingFilePath ) , JsonUtilities . DefaultSerializerOptions ) ;
58
+ _commandParamToResourceMap = JsonSerializer . Deserialize < Dictionary < string , Dictionary < string , string > > > ( File . ReadAllText ( mappingFilePath ) , JsonUtilities . DefaultSerializerOptions ) ;
53
59
}
54
60
catch ( Exception e )
55
61
{
56
62
// We don't want it to crash the module when the file doesn't exist or when it's mal-formatted.
57
63
exception = e ;
58
64
}
59
-
60
65
_telemetryClient . OnLoadParameterMap ( new ParameterMapTelemetryData ( exception ) ) ;
66
+
67
+ String path = Environment . GetFolderPath ( Environment . SpecialFolder . ApplicationData ) ;
68
+ string [ ] paths = new string [ ] { path , "Microsoft" , "Windows" , "PowerShell" , "AzPredictor" , "paramValueHistory.json" } ;
69
+ _paramValueHistoryFilePath = System . IO . Path . Combine ( paths ) ;
70
+ Directory . CreateDirectory ( Path . GetDirectoryName ( _paramValueHistoryFilePath ) ) ;
71
+
72
+ Task . Run ( ( ) =>
73
+ {
74
+ if ( System . IO . File . Exists ( _paramValueHistoryFilePath ) )
75
+ {
76
+ _mutex . WaitOne ( ) ;
77
+ try
78
+ {
79
+ var localParameterValues = JsonSerializer . Deserialize < ConcurrentDictionary < string , string > > ( File . ReadAllText ( _paramValueHistoryFilePath ) , JsonUtilities . DefaultSerializerOptions ) ;
80
+ foreach ( var v in localParameterValues )
81
+ {
82
+ _localParameterValues . AddOrUpdate ( v . Key , key => v . Value , ( key , oldValue ) => oldValue ) ;
83
+ }
84
+ }
85
+ finally
86
+ {
87
+ _mutex . ReleaseMutex ( ) ;
88
+ }
89
+ }
90
+
91
+
92
+ } ) ;
93
+
61
94
}
62
95
96
+
97
+
63
98
/// <summary>
64
99
/// Process the command from history
65
100
/// </summary>
@@ -89,7 +124,7 @@ public string GetParameterValueFromAzCommand(string commandNoun, string paramete
89
124
var key = parameterName ;
90
125
Dictionary < string , string > commandNounMap = null ;
91
126
92
- if ( _command_param_to_resource_map ? . TryGetValue ( commandNoun , out commandNounMap ) == true )
127
+ if ( _commandParamToResourceMap ? . TryGetValue ( commandNoun , out commandNounMap ) == true )
93
128
{
94
129
if ( commandNounMap . TryGetValue ( parameterName , out var parameterNameMappedValue ) )
95
130
{
@@ -146,7 +181,7 @@ private void ExtractLocalParameters(CommandAst command)
146
181
}
147
182
148
183
Dictionary < string , string > commandNounMap = null ;
149
- _command_param_to_resource_map ? . TryGetValue ( commandNoun , out commandNounMap ) ;
184
+ _commandParamToResourceMap ? . TryGetValue ( commandNoun , out commandNounMap ) ;
150
185
151
186
for ( int i = 1 ; i < command . CommandElements . Count ; )
152
187
{
@@ -189,8 +224,26 @@ private void ExtractLocalParameters(CommandAst command)
189
224
parameterKey = mappedValue ;
190
225
}
191
226
}
192
-
193
- _localParameterValues . AddOrUpdate ( parameterKey , parameterValue , ( k , v ) => parameterValue ) ;
227
+ _cancellationTokenSource ? . Cancel ( ) ;
228
+ _cancellationTokenSource = new CancellationTokenSource ( ) ;
229
+ Task . Run ( ( ) =>
230
+ {
231
+ this . _localParameterValues . AddOrUpdate ( parameterKey , parameterValue , ( k , v ) => parameterValue ) ;
232
+ if ( _cancellationTokenSource . IsCancellationRequested )
233
+ {
234
+ throw new OperationCanceledException ( ) ;
235
+ }
236
+ String localParameterValuesJson = JsonSerializer . Serialize < ConcurrentDictionary < string , string > > ( _localParameterValues , JsonUtilities . DefaultSerializerOptions ) ;
237
+ _mutex . WaitOne ( ) ;
238
+ try
239
+ {
240
+ System . IO . File . WriteAllText ( _paramValueHistoryFilePath , localParameterValuesJson ) ;
241
+ }
242
+ finally
243
+ {
244
+ _mutex . ReleaseMutex ( ) ;
245
+ }
246
+ } ) ;
194
247
}
195
248
}
196
249
}
0 commit comments