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