Skip to content

Commit

Permalink
Merge pull request #101 from gofiber/fix-69
Browse files Browse the repository at this point in the history
🔥 feat: Add support for stopping timestamp updater
  • Loading branch information
ReneWerner87 authored Dec 16, 2024
2 parents 92e6848 + 373ac79 commit 2777190
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 8 deletions.
29 changes: 23 additions & 6 deletions time.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
var (
timestampTimer sync.Once
timestamp uint32
stopChan chan struct{}
)

// Timestamp returns the current time.
Expand All @@ -21,16 +22,32 @@ func Timestamp() uint32 {
// which is much better for performance than determining it at runtime each time
func StartTimeStampUpdater() {
timestampTimer.Do(func() {
// set initial value
atomic.StoreUint32(&timestamp, uint32(time.Now().Unix()))
go func(sleep time.Duration) {

c := make(chan struct{})
stopChan = c

go func(localChan chan struct{}, sleep time.Duration) {
ticker := time.NewTicker(sleep)
defer ticker.Stop()

for t := range ticker.C {
// update timestamp
atomic.StoreUint32(&timestamp, uint32(t.Unix()))
for {
select {
case t := <-ticker.C:
atomic.StoreUint32(&timestamp, uint32(t.Unix()))
case <-localChan:
return
}
}
}(1 * time.Second) // duration
}(c, 1*time.Second)
})
}

// StopTimeStampUpdater stops the timestamp updater
// WARNING: Make sure to call this function before the program exits, otherwise it will leak goroutines
func StopTimeStampUpdater() {
if stopChan != nil {
close(stopChan)
stopChan = nil
}
}
18 changes: 16 additions & 2 deletions time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ func checkTimeStamp(tb testing.TB, expectedCurrent, actualCurrent uint32) {
}

func Test_TimeStampUpdater(t *testing.T) {
t.Parallel()

StartTimeStampUpdater()

now := uint32(time.Now().Unix())
Expand All @@ -30,6 +28,22 @@ func Test_TimeStampUpdater(t *testing.T) {
checkTimeStamp(t, now+2, Timestamp())
}

func Test_StopTimeStampUpdater(t *testing.T) {
// Start the timestamp updater
StartTimeStampUpdater()

// Stop the updater
StopTimeStampUpdater()

// Capture the timestamp after stopping
stoppedTime := Timestamp()

// Wait before checking the timestamp
time.Sleep(5 * time.Second)
// It should not have changed since we've stopped the updater
require.Equal(t, stoppedTime, Timestamp(), "timestamp should not change after stopping updater")
}

func Benchmark_CalculateTimestamp(b *testing.B) {
var res uint32
StartTimeStampUpdater()
Expand Down

0 comments on commit 2777190

Please sign in to comment.