Skip to content

Commit

Permalink
Reworked from Timers.Timer to Threading.Timer
Browse files Browse the repository at this point in the history
  • Loading branch information
claco committed Oct 30, 2008
1 parent 576f06f commit bd00b71
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 41 deletions.
68 changes: 45 additions & 23 deletions Siphon/Monitors/DataMonitor.vb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Imports System.Collections.ObjectModel
Imports System.Threading
Imports System.Timers
Imports log4net

Expand All @@ -15,7 +16,8 @@ Public MustInherit Class DataMonitor
Private _processing As Boolean = False
Private _processor As IDataProcessor = Nothing
Private _schedule As IMonitorSchedule = Nothing
Private WithEvents _timer As System.Timers.Timer
Private _eventWaitHandle As EventWaitHandle = New ManualResetEvent(False)
Private _timer As Threading.Timer = Nothing

''' <summary>
''' Creates a new DataMonitor instance.
Expand Down Expand Up @@ -85,8 +87,7 @@ Public MustInherit Class DataMonitor
Public Overridable Sub Start() Implements IDataMonitor.Start
Log.InfoFormat("Starting Monitor {0}", Me.Name)

Timer.Interval = Me.NextInterval
Timer.Start()
Me.Timer.Change(Me.GetNextInterval, Timeout.Infinite)
End Sub

''' <summary>
Expand All @@ -96,7 +97,7 @@ Public MustInherit Class DataMonitor
Public Overridable Sub Pause() Implements IDataMonitor.Pause
Log.InfoFormat("Pausing Monitor {0}", Me.Name)

Timer.Stop()
Me.Timer.Change(Timeout.Infinite, Timeout.Infinite)
End Sub

''' <summary>
Expand All @@ -106,37 +107,45 @@ Public MustInherit Class DataMonitor
Public Overridable Sub [Resume]() Implements IDataMonitor.Resume
Log.InfoFormat("Resuming Monitor {0}", Me.Name)

Timer.Interval = Me.NextInterval
Timer.Start()
Me.Timer.Change(Me.GetNextInterval, Timeout.Infinite)
End Sub

''' <summary>
''' Stops monitoring for new data.
''' </summary>
''' <remarks></remarks>
Public Overridable Sub [Stop]() Implements IDataMonitor.Stop
If Timer.Enabled Then
Log.InfoFormat("Stopping Monitor {0}", Me.Name)
Log.InfoFormat("Stopping Monitor {0}", Me.Name)

If Me.Processing Then
Log.Debug("Waiting for processor to finish")
End If

Timer.Stop()
If Me.Processing Then
Log.Debug("Waiting for processot to finish")
Me.EventWaitHandle.WaitOne()
Log.Debug("Done waiting for processor to finish")
End If
End Sub

''' <summary>
''' Returns the internal event wait handle used for timer thread sync.
''' </summary>
''' <value></value>
''' <returns>EventWaitHandle</returns>
''' <remarks></remarks>
Protected Overridable ReadOnly Property EventWaitHandle() As EventWaitHandle
Get
Return _eventWaitHandle
End Get
End Property

''' <summary>
''' Returns the internal timer used for the current monitor.
''' </summary>
''' <value></value>
''' <returns>Timer</returns>
''' <remarks></remarks>
Protected Overridable ReadOnly Property Timer() As Timer
Protected Overridable ReadOnly Property Timer() As Threading.Timer
Get
If _timer Is Nothing Then
_timer = New Timer
_timer.AutoReset = False
_timer = New Threading.Timer(New TimerCallback(AddressOf Me.OnTimerElapsed), Me, Timeout.Infinite, Timeout.Infinite)
End If

Return _timer
Expand Down Expand Up @@ -183,11 +192,11 @@ Public MustInherit Class DataMonitor
End Sub

''' <summary>
''' Gets the next event from the schedule and sets the timers interval.
''' Gets the next event from the schedule and returns the next interval in milliseconds to be sent to the timer.
''' </summary>
''' <returns></returns>
''' <returns>Integer. The number of milliseconds to wait until scanning for new data.</returns>
''' <remarks></remarks>
Private Function NextInterval() As Integer
Protected Overridable Function GetNextInterval() As Integer
Dim start As DateTime = DateTime.Now
Dim nextEvent As DateTime = Me.Schedule.NextEvent(start)
Dim interval As Integer = (nextEvent - start).TotalMilliseconds
Expand All @@ -199,23 +208,36 @@ Public MustInherit Class DataMonitor
Return interval
End Function

Private Sub _timer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles _timer.Elapsed
''' <summary>
''' Subroutine called when the timer time has elapsed.
''' </summary>
''' <param name="state"></param>
''' <remarks></remarks>
Protected Overridable Sub OnTimerElapsed(ByVal state As Object)
Log.Debug("Timer Elapsed")
Me.Pause()

Try
Dim items As Collection(Of Object) = Me.Scan
Log.DebugFormat("Scan returned {0} items", items.Count)

If items.Count > 0 Then
Log.DebugFormat("Pre Process Processing {0}", _processing)

_processing = True
Log.DebugFormat("{0} {1}", Me.Name, _processing)

For Each item As Object In items
Me.Processor.Process(item)
Next
Log.Debug("POST Process")

_processing = False

Log.DebugFormat("Post Process Processing {0}", _processing)
End If
Catch ex As Exception
'Log.Debug("BOOM", ex)
Log.Error("Exception", ex)
Finally
_eventWaitHandle.Set()
End Try

Me.Resume()
Expand Down
22 changes: 8 additions & 14 deletions SiphonTests/MonitorTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ Public Class MonitorTests
End Using
End Using
End Using

tempdir.Delete(True)
End Sub

<Test(Description:="Test directory monitor with processor failure")> _
Expand All @@ -48,8 +46,6 @@ Public Class MonitorTests
End Using
End Using
End Using

tempdir.Delete(True)
End Sub

<Test(Description:="Test directory monitor with processor exception")> _
Expand All @@ -68,8 +64,6 @@ Public Class MonitorTests
End Using
End Using
End Using

tempdir.Delete(True)
End Sub

<Test(Description:="Test directory monitor create missing root directory")> _
Expand All @@ -89,8 +83,6 @@ Public Class MonitorTests
End Using
End Using
End Using

Directory.Delete(tempdir, True)
End Sub

<Test(Description:="Test directory monitor with filter")> _
Expand All @@ -112,8 +104,6 @@ Public Class MonitorTests
End Using
End Using
End Using

tempdir.Delete(True)
End Sub


Expand All @@ -122,20 +112,24 @@ Public Class MonitorTests
Dim tempdir As DirectoryInfo = Directory.CreateDirectory(Path.Combine(Path.GetTempPath, Path.GetRandomFileName))
File.Create(Path.Combine(tempdir.FullName, "SUCCESS"))

Using schedule = New DailySchedule(DateTime.Now.AddSeconds(2).TimeOfDay)
'Using schedule = New DailySchedule(DateTime.Now.AddSeconds(2).TimeOfDay)
Using schedule = New IntervalSchedule(2)
Using processor = New MockProcessor
Using monitor As IDataMonitor = New LocalDirectoryMonitor("LocalMonitor", tempdir.FullName, schedule, processor)
Using monitor As LocalDirectoryMonitor = New LocalDirectoryMonitor("LocalMonitor", tempdir.FullName, schedule, processor)
processor.DelayProcess = 10
monitor.Start()
Threading.Thread.Sleep(3000)

Assert.IsTrue(monitor.Processing, "Processing is true when a worker processor is still running")
Dim pre As DateTime = DateTime.Now
monitor.Stop()
Dim post As DateTime = DateTime.Now

Assert.AreEqual(1, processor.Count, "Has processed 1 files")
Assert.GreaterOrEqual((post - pre).TotalSeconds, 5, "Waited for still running process to finish")
End Using
End Using
End Using

tempdir.Delete(True)
End Sub
#End Region

Expand Down
6 changes: 3 additions & 3 deletions SiphonTests/Processors/MockProcessor.vb
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ Public Class MockProcessor

Dim info As FileInfo = New FileInfo(data)

Log.DebugFormat("Delay process {0}", Me.DelayProcess)

Log.DebugFormat("Delay process {0}", Me.DelayProcess)
Log.DebugFormat("MockProccessor Process Start Delay {0}", Me.DelayProcess)
Threading.Thread.Sleep(Me.DelayProcess * 1000)
Log.DebugFormat("MockProccessor Process Finished Delay {0}", Me.DelayProcess)

Select Case info.Name.ToUpper
Case "SUCCESS"
Expand Down
2 changes: 1 addition & 1 deletion SiphonTests/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<log4net>
<appender name="TraceAppender" type="log4net.Appender.TraceAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level - [%thread] - %message%newline" />
<conversionPattern value="%date %-5level - [%thread] - %message%newline" />
</layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
Expand Down

0 comments on commit bd00b71

Please sign in to comment.