33using System . Text ;
44using System . Threading . Tasks ;
55using System . Timers ;
6- using Rackspace . Threading ;
76using System . Globalization ;
7+ using System . Threading ;
8+ using Timer = System . Threading . Timer ;
89
910namespace GitHub . Unity
1011{
@@ -14,20 +15,21 @@ class UsageTracker : IUsageTracker
1415 private static IMetricsService metricsService ;
1516
1617 private readonly NPath storePath ;
18+ private readonly ISettings userSettings ;
1719 private readonly string guid ;
1820 private readonly string unityVersion ;
19-
20- private bool firstRun = true ;
2121 private Timer timer ;
2222
23- public UsageTracker ( NPath storePath , string guid , string unityVersion )
23+ public UsageTracker ( ISettings userSettings , NPath storePath , string guid , string unityVersion )
2424 {
25+ this . userSettings = userSettings ;
2526 this . guid = guid ;
2627 this . storePath = storePath ;
2728 this . unityVersion = unityVersion ;
2829
2930 Logger . Trace ( "guid:{0}" , guid ) ;
30- RunTimer ( ) ;
31+ if ( Enabled )
32+ RunTimer ( 3 * 60 ) ;
3133 }
3234
3335 private UsageStore LoadUsage ( )
@@ -88,98 +90,71 @@ private void SaveUsage(UsageStore store)
8890 }
8991 }
9092
91- private void RunTimer ( )
92- {
93- Logger . Trace ( "Scheduling timer for 3 minutes from now" ) ;
94- // The timer first ticks after 3 minutes to allow things to settle down after startup.
95- // This will be changed to 8 hours after the first tick by the TimerTick method.
96- timer = new Timer ( TimeSpan . FromMinutes ( 3 ) . TotalMilliseconds ) ;
97- timer . Elapsed += TimerTick ;
98- timer . Start ( ) ;
99- }
100-
101- private void TimerTick ( object sender , ElapsedEventArgs e )
93+ private void RunTimer ( int seconds )
10294 {
103- TimerTick ( ) . Catch ( ( Action < Task , Exception > ) ( ( task , exception ) => {
104- Logger . Error ( exception , "TimerTicker Error: {0}" , exception . Message ) ;
105- } ) ) . Forget ( ) ;
95+ Logger . Trace ( $ "Scheduling timer for { seconds } seconds from now") ;
96+ timer = new Timer ( async _ =>
97+ {
98+ try
99+ {
100+ timer . Dispose ( ) ;
101+ await SendUsage ( ) ;
102+ }
103+ catch { }
104+ } , null , seconds * 1000 , Timeout . Infinite ) ;
106105 }
107106
108- private async Task TimerTick ( )
109- {
110- Logger . Trace ( "TimerTick" ) ;
111107
112- var usageStore = LoadUsage ( ) ;
108+ private async Task SendUsage ( )
109+ {
110+ Logger . Trace ( "SendUsage" ) ;
113111
114- if ( firstRun )
115- {
116- timer . Interval = TimeSpan . FromHours ( 8 ) . TotalMilliseconds ;
117- firstRun = false ;
118- Logger . Trace ( "Scheduling timer for 8 hours from now" ) ;
119-
120- if ( ! Enabled )
121- {
122- Logger . Warning ( "Metrics Disabled" ) ;
123- return ;
124- }
125- }
112+ var usage = LoadUsage ( ) ;
126113
127114 if ( metricsService == null )
128115 {
129- Logger . Warning ( "MetricsClient is null; stopping timer" ) ;
130- if ( timer != null )
131- {
132- timer . Enabled = false ;
133- timer = null ;
134- }
135- return ;
136- }
137-
138- if ( ! Enabled )
139- {
140- Logger . Warning ( "Metrics Disabled" ) ;
116+ Logger . Warning ( "No service, not sending usage" ) ;
141117 return ;
142118 }
143119
144- if ( usageStore . LastUpdated . Date != DateTimeOffset . UtcNow . Date )
120+ if ( usage . LastUpdated . Date != DateTimeOffset . UtcNow . Date )
145121 {
146- await SendUsage ( usageStore ) ;
147- }
148- }
122+ Logger . Trace ( "Sending Usage" ) ;
149123
150- private async Task SendUsage ( UsageStore usage )
151- {
152- Logger . Trace ( "Sending Usage" ) ;
153-
154- var currentTimeOffset = DateTimeOffset . UtcNow ;
155- var beforeDate = currentTimeOffset . Date ;
124+ var currentTimeOffset = DateTimeOffset . UtcNow ;
125+ var beforeDate = currentTimeOffset . Date ;
156126
157- var success = false ;
158- var extractReports = usage . Model . SelectReports ( beforeDate ) ;
159- if ( ! extractReports . Any ( ) )
160- {
161- Logger . Trace ( "No items to send" ) ;
162- success = true ;
163- }
164- else
165- {
166- try
127+ var success = false ;
128+ var extractReports = usage . Model . SelectReports ( beforeDate ) ;
129+ if ( ! extractReports . Any ( ) )
167130 {
168- await metricsService . PostUsage ( extractReports ) ;
169- success = true ;
131+ Logger . Trace ( "No items to send" ) ;
170132 }
171- catch ( Exception ex )
133+ else
172134 {
173- Logger . Warning ( ex , "Error Sending Usage" ) ;
174- }
135+ if ( ! Enabled )
136+ {
137+ Logger . Trace ( "Metrics disabled" ) ;
138+ return ;
139+ }
175140
176- }
141+ try
142+ {
143+ await metricsService . PostUsage ( extractReports ) ;
144+ success = true ;
145+ }
146+ catch ( Exception ex )
147+ {
148+ Logger . Warning ( ex , "Error Sending Usage" ) ;
149+ }
150+ }
177151
178- if ( success )
179- {
180- usage . Model . RemoveReports ( beforeDate ) ;
181- usage . LastUpdated = currentTimeOffset ;
182- SaveUsage ( usage ) ;
152+ if ( success )
153+ {
154+ usage . Model . RemoveReports ( beforeDate ) ;
155+ usage . LastUpdated = currentTimeOffset ;
156+ SaveUsage ( usage ) ;
157+ }
183158 }
184159 }
185160
@@ -204,6 +179,27 @@ public static void SetMetricsService(IMetricsService instance)
204179 metricsService = instance ;
205180 }
206181
207- public bool Enabled { get ; set ; }
182+ public bool Enabled
183+ {
184+ get
185+ {
186+ return userSettings . Get ( Constants . MetricsKey , true ) ;
187+ }
188+ set
189+ {
190+ if ( value == Enabled )
191+ return ;
192+ userSettings . Set ( Constants . MetricsKey , value ) ;
193+ if ( value )
194+ {
195+ RunTimer ( 5 ) ;
196+ }
197+ else
198+ {
199+ timer . Dispose ( ) ;
200+ timer = null ;
201+ }
202+ }
203+ }
208204 }
209205}
0 commit comments