go.mway.dev/chrono@v0.6.1-0.20240126030049-189c5aef20d2/README.md (about) 1 [![GoDoc][doc-img]][doc-link] [![Build Status][ci-img]][ci-link] [![Coverage Status][cov-img]][cov-link] [![Report Card][report-img]][report-link] 2 3 [doc-img]: https://pkg.go.dev/badge/go.mway.dev/chrono 4 [doc-link]: https://pkg.go.dev/go.mway.dev/chrono 5 [ci-img]: https://github.com/mway/chrono-go/actions/workflows/go.yml/badge.svg 6 [ci-link]: https://github.com/mway/chrono-go/actions/workflows/go.yml 7 [cov-img]: https://codecov.io/gh/mway/chrono-go/branch/main/graph/badge.svg 8 [cov-link]: https://codecov.io/gh/mway/chrono-go 9 [report-img]: https://goreportcard.com/badge/go.mway.dev/chrono 10 [report-link]: https://goreportcard.com/report/go.mway.dev/chrono 11 12 # go.mway.dev/chrono 13 14 `chrono` is a small collection of useful time-based types and helpers. It 15 provides: 16 17 - **go.mway.dev/chrono** 18 - An exported [`Nanotime`][nanotime-doc] function, which provides access to 19 the underlying system clock (via [`runtime.nanotime`][nanotime-stdlib]) 20 - **go.mway.dev/chrono/clock** 21 - A common [`Clock`][clock-doc] interface shared by all clocks 22 - Monotonic and wall `Clock`s 23 - A [`ThrottledClock`][throttled-clock-doc] to provide configurable time 24 memoization to reduce time-based syscalls 25 - A [`FakeClock`][fake-clock-doc] implementation, to support mocking time 26 - A lightweight [`Stopwatch`][stopwatch-doc] for trivially (and continuously) 27 measuring elapsed time 28 - **go.mway.dev/periodic** 29 - A [`Handle`][periodic-handler-doc] to manage functions that are run 30 periodically via [`Start`][periodic-start-doc] 31 - **go.mway.dev/chrono/rate** 32 - A [`Recorder`][recorder-doc] that performs simple, empirical rate 33 calculation, optionally against a custom clock 34 - A lightweight [`Rate`][rate-doc] type that provides simple translation of 35 an absolute rate into different denominations 36 37 These packages are intended for general use, and as a replacement for the 38 long-archived [github.com/andres-erbsen/clock][erbsen-clock-repo] package. 39 40 ## Getting Started 41 42 To start using a [`Clock`][clock-doc], first determine whether the goal is to 43 *tell* time, or to *measure* time: 44 45 - When *telling* time, wall clocks are necessary. Use [NewWallClock][new-wall-clock-doc]. 46 - When *measuring* time, monotonic clocks are preferable, though in most cases 47 a wall clock can be used as well. Use [NewMonotonicClock][new-monotonic-clock-doc]. 48 49 The only difference between a wall clock and a monotonic clock is the time 50 source being used, which in this implementation is either a [`TimeFunc`][timefunc-doc] 51 or a [`NanotimeFunc`][nanotimefunc-doc]. 52 53 After selecting a type of clock, simply construct and use it: 54 55 ```go 56 package main 57 58 import ( 59 "time" 60 61 "go.mway.dev/chrono/clock" 62 ) 63 64 func main() { 65 var ( 66 clk = clock.NewWallClock() 67 now = clk.Now() // time.Time 68 nanos = clk.Nanotime() // int64 69 stopwatch = clk.NewStopwatch() 70 ticker = clk.NewTicker(time.Second) 71 timer = clk.NewTimer(3*time.Second) 72 ) 73 74 fmt.Printf("It is now: %s (~%d)\n", now, nanos) 75 76 func() { 77 for { 78 select { 79 case <-ticker.C: 80 fmt.Println("Tick!") 81 case <-timer.C: 82 fmt.Println("Done!") 83 return 84 } 85 } 86 }() 87 88 fmt.Println("Ticker/timer took", stopwatch.Elapsed()) 89 90 // etc. 91 } 92 ``` 93 94 The goal of [`Clock`][clock-doc] is to be comparable to using the standard 95 library [`time`][time-pkg-doc], i.e. any common `time`-related functions should 96 be provided as part of the `Clock` API. 97 98 ### Examples 99 100 TODO 101 102 ### Throttling 103 104 In some cases, it may be desirable to limit the number of underlying time-based 105 syscalls being made, for example when needing to attribute time within a tight 106 loop. Rather than needing to throttle or debounce such calls themselves, users 107 can use a [`ThrottledClock`][throttled-clock-doc], which does this at a 108 configurable resolution: 109 110 ```go 111 // Use monotonic time that only updates once per second 112 clk := clock.NewThrottledMonotonicClock(time.Second) 113 defer clk.Stop() // free resources 114 115 // Issue an arbitrary number of time-based calls 116 for i := 0; i < 1_000_000; i++ { 117 clk.Nanotime() 118 } 119 ``` 120 121 A background routine updates the clock's time from the configured source at 122 the specified interval, and time-based calls on a `ThrottledClock` use the 123 internally cached time. 124 125 ## Contributions & Feedback 126 127 Pull requests are welcome, and all feedback is appreciated! 128 129 [time-pkg-doc]: https://pkg.go.dev/time 130 [time-doc]: https://pkg.go.dev/time#Time 131 [nanotime-doc]: https://pkg.go.dev/go.mway.dev/chrono#Nanotime 132 [nanotime-stdlib]: https://cs.opensource.google/go/go/+/refs/tags/go1.20.1:src/runtime/time_nofake.go;l=18-20 133 [clock-doc]: https://pkg.go.dev/go.mway.dev/chrono/clock#Clock 134 [throttled-clock-doc]: https://pkg.go.dev/go.mway.dev/chrono/clock#ThrottledClock 135 [periodic-handle-doc]: https://pkg.go.dev/go.mway.dev/chrono/periodic#Handle 136 [periodic-start-doc]: https://pkg.go.dev/go.mway.dev/chrono/periodic#Start 137 [fake-clock-doc]: https://pkg.go.dev/go.mway.dev/chrono/clock#FakeClock 138 [stopwatch-doc]: https://pkg.go.dev/go.mway.dev/chrono/clock#Stopwatch 139 [recorder-doc]: https://pkg.go.dev/go.mway.dev/chrono/rate#Recorder 140 [rate-doc]: https://pkg.go.dev/go.mway.dev/chrono/rate#Rate 141 [erbsen-clock-repo]: https://github.com/andres-erbsen/clock 142 [new-wall-clock-doc]:https://pkg.go.dev/go.mway.dev/chrono/clock#NewWallClock 143 [new-monotonic-clock-doc]:https://pkg.go.dev/go.mway.dev/chrono/clock#NewMonotonicClock 144 [timefunc-doc]:https://pkg.go.dev/go.mway.dev/chrono/clock#TimeFunc 145 [nanotimefunc-doc]:https://pkg.go.dev/go.mway.dev/chrono/clock#NanotimeFunc