Skip to content

Commit

Permalink
Merge pull request #547 from alrs/util
Browse files Browse the repository at this point in the history
Move zenhack.net/go/util into go-capnp repository
  • Loading branch information
lthibault committed Oct 7, 2023
2 parents 66b5b8e + 2b6900a commit 0a6a8fc
Show file tree
Hide file tree
Showing 30 changed files with 1,118 additions and 79 deletions.
54 changes: 0 additions & 54 deletions README.md

This file was deleted.

4 changes: 2 additions & 2 deletions answer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

"capnproto.org/go/capnp/v3/exc"
"capnproto.org/go/capnp/v3/internal/str"
"zenhack.net/go/util/deferred"
"zenhack.net/go/util/sync/mutex"
"capnproto.org/go/capnp/v3/util/deferred"
"capnproto.org/go/capnp/v3/util/sync/mutex"
)

// A Promise holds the result of an RPC call. Only one of Fulfill
Expand Down
8 changes: 4 additions & 4 deletions capability.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
"capnproto.org/go/capnp/v3/exp/bufferpool"
"capnproto.org/go/capnp/v3/flowcontrol"
"capnproto.org/go/capnp/v3/internal/str"
"zenhack.net/go/util/deferred"
"zenhack.net/go/util/maybe"
"zenhack.net/go/util/rc"
"zenhack.net/go/util/sync/mutex"
"capnproto.org/go/capnp/v3/util/deferred"
"capnproto.org/go/capnp/v3/util/maybe"
"capnproto.org/go/capnp/v3/util/rc"
"capnproto.org/go/capnp/v3/util/sync/mutex"
)

func init() {
Expand Down
2 changes: 1 addition & 1 deletion flowcontrol/internal/test-tool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"capnproto.org/go/capnp/v3/flowcontrol/tracing"
"capnproto.org/go/capnp/v3/internal/syncutil"
"capnproto.org/go/capnp/v3/rpc"
"zenhack.net/go/util"
"capnproto.org/go/capnp/v3/util"
)

var (
Expand Down
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ require (
github.com/kylelemons/godebug v1.1.0
github.com/stretchr/testify v1.8.2
github.com/tinylib/msgp v1.1.5
github.com/tj/assert v0.0.3
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
zenhack.net/go/util v0.0.0-20230414211804-99ae9bf14f02
)

require (
Expand Down
18 changes: 6 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -11,19 +10,22 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/tinylib/msgp v1.1.5 h1:2gXmtWueD2HefZHQe1QOy9HVzmFrLOVvsXwXBQ0ayy0=
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk=
github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
Expand All @@ -44,15 +46,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
zenhack.net/go/util v0.0.0-20230218002511-744d2d6d1739 h1:/QnbZBURrZUFvnxB4wDyRrPsWzh2KWbJ6AjUjohCHJ8=
zenhack.net/go/util v0.0.0-20230218002511-744d2d6d1739/go.mod h1:0lafdGg7tDb7RcXASgmJmRbLFLkAxu328+KGIs7icDE=
zenhack.net/go/util v0.0.0-20230327231740-da8cb323921c h1:L+T38E+u91e956ykUrYKHZaZef9hKMJsnGmTbMVb2cE=
zenhack.net/go/util v0.0.0-20230327231740-da8cb323921c/go.mod h1:0lafdGg7tDb7RcXASgmJmRbLFLkAxu328+KGIs7icDE=
zenhack.net/go/util v0.0.0-20230414204917-531d38494cf5 h1:yksDCGMVzyn3vlyf0GZ3huiF5FFaMGQpQ3UJvR0EoGA=
zenhack.net/go/util v0.0.0-20230414204917-531d38494cf5/go.mod h1:1LtNdPAs8WH+BTcQiZAOo2MIKD/5jyK/u7sZ9ZPe5SE=
zenhack.net/go/util v0.0.0-20230414211804-99ae9bf14f02 h1:0iYx7hqltFcLvxDeCdg84gEJp8BJ6SgGti431U2ztIU=
zenhack.net/go/util v0.0.0-20230414211804-99ae9bf14f02/go.mod h1:1LtNdPAs8WH+BTcQiZAOo2MIKD/5jyK/u7sZ9ZPe5SE=
2 changes: 1 addition & 1 deletion rpc/answer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"capnproto.org/go/capnp/v3/exc"
"capnproto.org/go/capnp/v3/internal/rc"
rpccp "capnproto.org/go/capnp/v3/std/capnp/rpc"
"zenhack.net/go/util/deferred"
"capnproto.org/go/capnp/v3/util/deferred"
)

// An answerID is an index into the answers table.
Expand Down
2 changes: 1 addition & 1 deletion rpc/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"capnproto.org/go/capnp/v3/internal/str"
"capnproto.org/go/capnp/v3/internal/syncutil"
rpccp "capnproto.org/go/capnp/v3/std/capnp/rpc"
"zenhack.net/go/util/deferred"
"capnproto.org/go/capnp/v3/util/deferred"
)

// An exportID is an index into the exports table.
Expand Down
2 changes: 1 addition & 1 deletion rpc/receiveranswer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"capnproto.org/go/capnp/v3"
"capnproto.org/go/capnp/v3/rpc/internal/testcapnp"
"capnproto.org/go/capnp/v3/server"
"zenhack.net/go/util"
"capnproto.org/go/capnp/v3/util"
)

type capArgsTest struct {
Expand Down
4 changes: 2 additions & 2 deletions rpc/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"time"

"golang.org/x/sync/errgroup"
"zenhack.net/go/util"
"zenhack.net/go/util/deferred"

"capnproto.org/go/capnp/v3"
"capnproto.org/go/capnp/v3/exc"
Expand All @@ -19,6 +17,8 @@ import (
"capnproto.org/go/capnp/v3/internal/syncutil"
"capnproto.org/go/capnp/v3/rpc/transport"
rpccp "capnproto.org/go/capnp/v3/std/capnp/rpc"
"capnproto.org/go/capnp/v3/util"
"capnproto.org/go/capnp/v3/util/deferred"
)

/*
Expand Down
2 changes: 2 additions & 0 deletions util/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This directory contains misc. Go utility packages that Ian Denhardt wrote as he
needed them for other projects.
14 changes: 14 additions & 0 deletions util/chkfatal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package util

// Chkfatal panics if err is not nil
func Chkfatal(err error) {
if err != nil {
panic(err)
}
}

// Must panics if err != nil, otherwise returns value.
func Must[T any](value T, err error) T {
Chkfatal(err)
return value
}
18 changes: 18 additions & 0 deletions util/chkfatal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package util

import (
"errors"
"testing"

"github.com/stretchr/testify/assert"
)

func TestChkfatal(t *testing.T) {
assert.NotPanics(t, func() {
Chkfatal(nil)
}, "Chkfatal does not panic on a nil error.")

assert.Panics(t, func() {
Chkfatal(errors.New("Some error."))
}, "Chkfatal panics on a non-nil error.")
}
13 changes: 13 additions & 0 deletions util/debugging/debugging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Package debugging exports various helpers useful when debugging. In general,
// code from this package should not be included in production builds.
package debugging

import "runtime"

// Wrapper around runtime.Stack, which allocates a buffer and returns the stack
// trace as a string. Stack traces over 1MB will be truncated.
func StackString(all bool) string {
var buf [1e6]byte
n := runtime.Stack(buf[:], all)
return string(buf[:n])
}
41 changes: 41 additions & 0 deletions util/deferred/queue.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Package deferred provides tools for deferring actions
// to be run at a later time. These can be thought of as
// an extension and generalization of the language's built-in
// defer statement.
package deferred

// A Queue is a queue of actions to run at some later time.
// The actions will be run in the order they are added with
// Defer. Note that this is different from the language's
// built-in defer statement, which runs actions in reverse
// order (future versions of this package may add a Stack
// type to support those semantics).
//
// The zero value is an empty queue.
//
// The advantage of this vs. built-in defer is that it needn't
// be tied to the scope of a single function; for example,
// you can write code like:
//
// q := &Queue{}
// defer q.Run()
// f(q) // pass the queue to a subroutine, which may queue
// // up actions to be run after *this* function returns.
type Queue []func()

// Run runs all deferred actions, in the order they were added.
func (q *Queue) Run() {
funcs := *q
for i, f := range funcs {
if f != nil {
f()
funcs[i] = nil
}
}
}

// Defer adds f to the list of functions to call when Run()
// is invoked.
func (q *Queue) Defer(f func()) {
*q = append(*q, f)
}
95 changes: 95 additions & 0 deletions util/exn/exn.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Package exn provides an exception-like mechanism.
//
// It is a bit easier to reason about than standard exceptions, since
// not any code can throw, only code given access to a throw callback.
// See the docs for Try.
package exn

// exn is a wrapper type used to distinguish values this package passes
// to panic() from anything else that might be passed to panic by
// unrelated code.
type exn struct {
err error
}

// An alias for the type of the callback provided by Try.
type Thrower = func(error, ...string)

// Try invokes f, which is a callback with type:
//
// func(throw Thrower) T
//
// Thrower is an alias for func(error, ...string).
//
// If f returns normally, Try returns the value f returned and a nil
// error.
//
// If f invokes throw with a non-nil error, f's execution is
// terminated, and Try returns the zero value for T and the
// error that was passed to throw.
//
// If f invokes throw with a nil argument, throw returns normally
// without terminating f. This is so that error handling code can
// pass errors to throw unconditionally, like:
//
// v, err := foo()
// throw(err)
//
// f must not store throw or otherwise cause it to be invoked after
// Try returns.
//
// Callers may pass additonal string arguments to throw, which will
// wrap the error with additional context, i.e. throw(err, "something")
// is equivalent to throw(Wrap("something", err))
func Try[T any](f func(Thrower) T) (result T, err error) {
throw := func(e error, context ...string) {
if e == nil {
return
}
for i := len(context) - 1; i >= 0; i-- {
e = Wrap(context[i], e)
}
panic(exn{err: e})
}
finishedCall := false
defer func() {
if finishedCall {
return
}

panicVal := recover()
if e, ok := panicVal.(exn); ok {
err = e.err
} else {
panic(panicVal)
}
}()
result = f(throw)
finishedCall = true
return
}

// Try0 is like Try, but f does not return a value, and Try0 only returns
// an error.
func Try0(f func(Thrower)) error {
_, err := Try(func(throw Thrower) struct{} {
f(throw)
return struct{}{}
})
return err
}

// Try2 is like Try, but with two values instead of 1.
func Try2[A, B any](f func(Thrower) (A, B)) (A, B, error) {
r, err := Try(func(throw Thrower) pair[A, B] {
a, b := f(throw)
return pair[A, B]{a: a, b: b}
})
return r.a, r.b, err
}

// TODO: move into its own package.
type pair[A, B any] struct {
a A
b B
}

0 comments on commit 0a6a8fc

Please sign in to comment.