Skip to content

Commit

Permalink
Recommend new atomic types instead of Uber's atomic package
Browse files Browse the repository at this point in the history
  • Loading branch information
autarch committed Feb 13, 2025
1 parent 213b541 commit 68f4784
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG-MongoDB.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2025-02-10

- First version of this fork.
- Recommend the new atomic types like `atomic.Bool` instead of the `go.uber.org/atomic` package. The
Uber package predates the new types added in Go 1.19. The new stdlib types provide more or less
the same functionality as Uber's package.
2 changes: 1 addition & 1 deletion src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- [Handle Errors Once](error-once.md)
- [Handle Type Assertion Failures](type-assert.md)
- [Don't Panic](panic.md)
- [Use go.uber.org/atomic](atomic.md)
- [Use the New Types in sync/atomic](atomic.md)
- [Avoid Mutable Globals](global-mut.md)
- [Avoid Embedding Types in Public Structs](embed-public.md)
- [Avoid Using Built-In Names](builtin-name.md)
Expand Down
24 changes: 15 additions & 9 deletions src/atomic.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# Use go.uber.org/atomic
# Use the New Types in sync/atomic

Atomic operations with the [sync/atomic] package operate on the raw types
(`int32`, `int64`, etc.) so it is easy to forget to use the atomic operation to
read or modify the variables.
In the past, the [sync/atomic] package was implemented entirely in terms of functions like
`atomic.AddInt64`, which were awkward to use and made it easy to accidentally access the underlying
value non-atomically..

[go.uber.org/atomic] adds type safety to these operations by hiding the
underlying type. Additionally, it includes a convenient `atomic.Bool` type.
Since Go 1.19, the [sync/atomic] package provides atomic types like `atomic.Bool` and
`atomic.Int64`, which provide a much safer API for atomic operations, making it impossible to read
or modify them with a non-atomic operation.

[go.uber.org/atomic]: https://pkg.go.dev/go.uber.org/atomic
[sync/atomic]: https://pkg.go.dev/sync/atomic
<!--
TODO: It'd be nice to have a shared library that provided a typed atomic value instead of having
people use `atomic.Value`. We've written such a thing for Mongosync. See
https://github.com/10gen/mongosync/blob/main/mongo-go/msync/typed_atomic.go for details.
-->

<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
Expand All @@ -17,7 +23,7 @@ underlying type. Additionally, it includes a convenient `atomic.Bool` type.

```go
type foo struct {
running int32 // atomic
running atomic.Int32 // atomic
}

func (f* foo) start() {
Expand Down
24 changes: 16 additions & 8 deletions style.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
- [Handle Errors Once](#handle-errors-once)
- [Handle Type Assertion Failures](#handle-type-assertion-failures)
- [Don't Panic](#dont-panic)
- [Use go.uber.org/atomic](#use-gouberorgatomic)
- [Use the New Types in sync/atomic](#use-the-new-types-in-syncatomic)
- [Avoid Mutable Globals](#avoid-mutable-globals)
- [Avoid Embedding Types in Public Structs](#avoid-embedding-types-in-public-structs)
- [Avoid Using Built-In Names](#avoid-using-built-in-names)
Expand Down Expand Up @@ -1251,23 +1251,31 @@ if err != nil {
</td></tr>
</tbody></table>

### Use go.uber.org/atomic
### Use the New Types in sync/atomic

Atomic operations with the [sync/atomic](https://pkg.go.dev/sync/atomic) package operate on the raw types
(`int32`, `int64`, etc.) so it is easy to forget to use the atomic operation to
read or modify the variables.
In the past, the [sync/atomic] package was implemented entirely in terms of functions like
`atomic.AddInt64`, which were awkward to use and made it easy to accidentally access the underlying
value non-atomically..

[go.uber.org/atomic](https://pkg.go.dev/go.uber.org/atomic) adds type safety to these operations by hiding the
underlying type. Additionally, it includes a convenient `atomic.Bool` type.
Since Go 1.19, the [sync/atomic] package provides atomic types like `atomic.Bool` and
`atomic.Int64`, which provide a much safer API for atomic operations, making it impossible to read
or modify them with a non-atomic operation.

<!--
TODO: It'd be nice to have a shared library that provided a typed atomic value instead of having
people use `atomic.Value`. We've written such a thing for Mongosync. See
https://github.com/10gen/mongosync/blob/main/mongo-go/msync/typed_atomic.go for details.
-->
<table>
<thead><tr><th>Bad</th><th>Good</th></tr></thead>
<tbody>
<tr><td>

```go
type foo struct {
running int32 // atomic
running atomic.Int32 // atomic
}

func (f* foo) start() {
Expand Down

0 comments on commit 68f4784

Please sign in to comment.