Browse Source

Use time.Timer instead of time.After

memory is allocated every time time.After is called and is not freed
until the timer expires. This could create a memory "leak" of sorts if
the user of cron calls snapshots or adds new entries frequently.

using time.Timer allows for explicitly stopping and cleaning up the
timer on each iteration of the for-loop. So when a snapshot or new entry
is added, we can cleanup the timer.

see https://groups.google.com/forum/#!topic/golang-nuts/cCdm0Ixwi9A for
more details.
Cameron Sparr 9 years ago
parent
commit
f0a137d298
1 changed files with 4 additions and 1 deletions
  1. 4 1
      cron.go

+ 4 - 1
cron.go

@@ -165,8 +165,9 @@ func (c *Cron) run() {
 			effective = c.entries[0].Next
 		}
 
+		timer := time.NewTimer(effective.Sub(now))
 		select {
-		case now = <-time.After(effective.Sub(now)):
+		case now = <-timer.C:
 			// Run every entry whose next time was this effective time.
 			for _, e := range c.entries {
 				if e.Next != effective {
@@ -186,11 +187,13 @@ func (c *Cron) run() {
 			c.snapshot <- c.entrySnapshot()
 
 		case <-c.stop:
+			timer.Stop()
 			return
 		}
 
 		// 'now' should be updated after newEntry and snapshot cases.
 		now = time.Now().Local()
+		timer.Stop()
 	}
 }