[go-nuts] Does building with an older golang use package sources from that older version?
Say I install golang 1.20.12 and go clean -cache and go clean -modcache. Then I build. Will that executable be using crypto/tls and other packages "as they were in 1.20.12"? Or is golang fetching the newest available compatible sources, and therefore I may be spinning my wheels trying to see if there is a bug in the latest crypto/tls? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/597a23f1-e212-455a-b621-e64108281da8n%40googlegroups.com.
[go-nuts] Re: TLS negotiation bug in go1.21.4?
I tried go1.21.6 and see the same behavior. I'm going to try to backport the project to go1.18 to see what happens. On Wednesday, January 10, 2024 at 3:51:16 PM UTC-8 Andrew Athan wrote: > As you can see in the below output from pprof, the golang TLS > implementation seems to be in some kind of tight loop in > crypto/internal/bigmod.addMulVVW2048 causing CPU starvation, wherein the > net.HTTP server stops calling my request handler. Eventually the TLS > handshakes fail, and the connections are dropped before my handler ever > sees them. I guess I'll look for an even newer version of golang, but > wanted to post this here to see if you have any feedback. It seems unlikely > to me that go's TLS package would exhibit this type of regression. > > $ go tool pprof /tmp/cpu.prof2 > File: sgs-server-dev > Type: cpu > Time: Jan 10, 2024 at 10:10pm (UTC) > Duration: 180.20s, Total samples = 892.25s (495.14%) > Entering interactive mode (type "help" for commands, "o" for options) > (pprof) top 10 > Showing nodes accounting for 840.73s, 94.23% of 892.25s total > Dropped 1278 nodes (cum <= 4.46s) > Showing top 10 nodes out of 52 > flat flat% sum%cum cum% >595.80s 66.78% 66.78%595.80s 66.78% > crypto/internal/bigmod.addMulVVW2048 > 83.10s 9.31% 76.09%772.62s 86.59% > crypto/internal/bigmod.(*Nat).montgomeryMul > 53.66s 6.01% 82.10% 53.86s 6.04% > crypto/internal/bigmod.(*Nat).assign (inline) > 42.83s 4.80% 86.90% 42.93s 4.81% > crypto/internal/bigmod.addMulVVW (inline) > 23.23s 2.60% 89.51% 25.10s 2.81% > crypto/internal/bigmod.(*Nat).shiftIn > 14.93s 1.67% 91.18% 14.93s 1.67% > crypto/internal/bigmod.(*Nat).sub (inline) > 7.75s 0.87% 92.05% 7.75s 0.87% runtime.memmove > 7.33s 0.82% 92.87% 7.33s 0.82% runtime.duffzero > 7.12s 0.8% 93.67% 7.12s 0.8% > runtime/internal/syscall.Syscall6 > 4.98s 0.56% 94.23% 4.98s 0.56% crypto/sha256.block > > I am building an executable on this box: > > $ lsb_release -a > No LSB modules are available. > Distributor ID: Ubuntu > Description: Ubuntu 23.04 > Release: 23.04 > Codename: lunar > > $ uname -a > Linux AASalad 6.2.0-36-generic #37-Ubuntu SMP PREEMPT_DYNAMIC Wed Oct 4 > 10:14:28 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux > > $ go version > go version go1.21.4 linux/amd64 > > Using this command: > > GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o a.out -buildvcs=true -a > -ldflags '-extldflags "-static"' > > This executable is then deployed to a Debian 11 host: > > # lsb_release -a > No LSB modules are available. > Distributor ID: Debian > Description: Debian GNU/Linux 11 (bullseye) > Release: 11 > Codename: bullseye > > # uname -a > Linux sgs-dandelion 5.10.0-26-amd64 #1 SMP Debian 5.10.197-1 (2023-09-29) > x86_64 GNU/Linux > > This was done because without the -static build, the right glibc so's are > not found on the target system. When running the executable under high > incoming TLS connection load, I observe that the net.HTTP handler is > eventually not called and lots of these errors are logged: > > http: TLS handshake error from ... > > with this stacktrace: > log.(*Logger).output > /usr/local/go/src/log/log.go:245 > log.(*Logger).Printf > /usr/local/go/src/log/log.go:268 > net/http.(*Server).logf > /usr/local/go/src/net/http/server.go:3212 > net/http.(*conn).serve > /usr/local/go/src/net/http/server.go:1900 > > This exe handles high load and lots of incoming TLS connections. I have > exhaustively looked for a source of CPU starvation such as excessive > numbers of goroutines started by my code, or tight loops, etc. and have not > found evidence for that. > > > Here is the output of pprof tree: > > (pprof) tree > Showing nodes accounting for 853.85s, 95.70% of 892.25s total > Dropped 1278 nodes (cum <= 4.46s) > --+- > flat flat% sum%cum cum% calls calls% + context > --+- >595.80s 100% | > crypto/internal/bigmod.(*Nat).montgomeryMul >595.80s 66.78% 66.78%595.80s 66.78%| > crypto/internal/bigmod.addMulVVW2048 > --+- >718.77s 93.03% | > crypto/internal/bigmod.(*Nat).Exp > 47.75s 6.18% | > crypto/internal/bigmod.(*Nat).ExpShort >
[go-nuts] TLS negotiation bug in go1.21.4?
As you can see in the below output from pprof, the golang TLS implementation seems to be in some kind of tight loop in crypto/internal/bigmod.addMulVVW2048 causing CPU starvation, wherein the net.HTTP server stops calling my request handler. Eventually the TLS handshakes fail, and the connections are dropped before my handler ever sees them. I guess I'll look for an even newer version of golang, but wanted to post this here to see if you have any feedback. It seems unlikely to me that go's TLS package would exhibit this type of regression. $ go tool pprof /tmp/cpu.prof2 File: sgs-server-dev Type: cpu Time: Jan 10, 2024 at 10:10pm (UTC) Duration: 180.20s, Total samples = 892.25s (495.14%) Entering interactive mode (type "help" for commands, "o" for options) (pprof) top 10 Showing nodes accounting for 840.73s, 94.23% of 892.25s total Dropped 1278 nodes (cum <= 4.46s) Showing top 10 nodes out of 52 flat flat% sum%cum cum% 595.80s 66.78% 66.78%595.80s 66.78% crypto/internal/bigmod.addMulVVW2048 83.10s 9.31% 76.09%772.62s 86.59% crypto/internal/bigmod.(*Nat).montgomeryMul 53.66s 6.01% 82.10% 53.86s 6.04% crypto/internal/bigmod.(*Nat).assign (inline) 42.83s 4.80% 86.90% 42.93s 4.81% crypto/internal/bigmod.addMulVVW (inline) 23.23s 2.60% 89.51% 25.10s 2.81% crypto/internal/bigmod.(*Nat).shiftIn 14.93s 1.67% 91.18% 14.93s 1.67% crypto/internal/bigmod.(*Nat).sub (inline) 7.75s 0.87% 92.05% 7.75s 0.87% runtime.memmove 7.33s 0.82% 92.87% 7.33s 0.82% runtime.duffzero 7.12s 0.8% 93.67% 7.12s 0.8% runtime/internal/syscall.Syscall6 4.98s 0.56% 94.23% 4.98s 0.56% crypto/sha256.block I am building an executable on this box: $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 23.04 Release: 23.04 Codename: lunar $ uname -a Linux AASalad 6.2.0-36-generic #37-Ubuntu SMP PREEMPT_DYNAMIC Wed Oct 4 10:14:28 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux $ go version go version go1.21.4 linux/amd64 Using this command: GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o a.out -buildvcs=true -a -ldflags '-extldflags "-static"' This executable is then deployed to a Debian 11 host: # lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 11 (bullseye) Release: 11 Codename: bullseye # uname -a Linux sgs-dandelion 5.10.0-26-amd64 #1 SMP Debian 5.10.197-1 (2023-09-29) x86_64 GNU/Linux This was done because without the -static build, the right glibc so's are not found on the target system. When running the executable under high incoming TLS connection load, I observe that the net.HTTP handler is eventually not called and lots of these errors are logged: http: TLS handshake error from ... with this stacktrace: log.(*Logger).output /usr/local/go/src/log/log.go:245 log.(*Logger).Printf /usr/local/go/src/log/log.go:268 net/http.(*Server).logf /usr/local/go/src/net/http/server.go:3212 net/http.(*conn).serve /usr/local/go/src/net/http/server.go:1900 This exe handles high load and lots of incoming TLS connections. I have exhaustively looked for a source of CPU starvation such as excessive numbers of goroutines started by my code, or tight loops, etc. and have not found evidence for that. Here is the output of pprof tree: (pprof) tree Showing nodes accounting for 853.85s, 95.70% of 892.25s total Dropped 1278 nodes (cum <= 4.46s) --+- flat flat% sum%cum cum% calls calls% + context --+- 595.80s 100% | crypto/internal/bigmod.(*Nat).montgomeryMul 595.80s 66.78% 66.78%595.80s 66.78%| crypto/internal/bigmod.addMulVVW2048 --+- 718.77s 93.03% | crypto/internal/bigmod.(*Nat).Exp 47.75s 6.18% | crypto/internal/bigmod.(*Nat).ExpShort 4.76s 0.62% | crypto/internal/bigmod.(*Nat).montgomeryRepresentation 1.34s 0.17% | crypto/rsa.decrypt 83.10s 9.31% 76.09%772.62s 86.59%| crypto/internal/bigmod.(*Nat).montgomeryMul 595.80s 77.11% | crypto/internal/bigmod.addMulVVW2048 42.93s 5.56% | crypto/internal/bigmod.addMulVVW (inline) 36.25s 4.69% | crypto/internal/bigmod.(*Nat).maybeSubtractModulus 6.19s 0.8% | crypto/internal/bigmod.(*Nat).reset (inline) 4.19s 0.54% |
Re: [go-nuts] interpreting runtime.Stack()
This stack trace was indeed a contexts with very deep parenthood. On Friday, May 12, 2023 at 8:34:40 AM UTC-7 Andrew Athan wrote: > Alex: > > I’ll see how/if this can happen. Among other strangeness in this stack is > that Err() doesn’t take a param but I guess it may be displaying the > implicit “this”? > > btw this is not from a panic, but from a call to runtime.Stack(). The > program experiences unbounded growth in cpu utilization as it runs so > either these stacks are a recursion bc there is a context “pointing” to > itself as parent or a very deep reference stack. > > I’m going to guess there is a captured continuation variable somewhere > that is incorrectly updated to a new value ctx with each new connection > made or inside some loop instead of using the oroginal basr ctx. > > I looked for that originally but didn’t find it, but I’ll look again. I’m > concerned that net.Conn’s or tls.Conn’s setRead/WriteDeadline() calls are > at fault somehow. > > A. > > > > On May 12, 2023, at 12:38 AM, Axel Wagner > wrote: > > > > Ouh, I bet I know what's happening: You are using a concrete Context > implementation that defines its methods on a value receiver, but pass it in > as a nil-pointer: https://go.dev/play/p/JH9MxwvmTw7 > That way, the panic happens in autogenerated code (the implicit promoted > method from the value-type to the pointer-type) which then panics due to a > nil-pointer dereference. The panic message should then actually tell you > exactly that, though. > > On Fri, May 12, 2023 at 9:32 AM Axel Wagner > wrote: > >> What does the panic say? If it says "stack overflow", then yes, that's >> likely an infinite recursion. If not, then, no. My guess is, that it says >> "nil-pointer dereference". >> >> The `` part probably means this is due to embedding. That >> is, the `Err` method on `valueCtx` is promoted from an embedded Context: >> https://cs.opensource.google/go/go/+/refs/tags/go1.20.4:src/context/context.go;l=599 >> If that context was `nil` or otherwise invalid, that would explain why >> the panic happens. Though I'm not sure how that would happen, unless you >> use `unsafe` somewhere. >> >> On Fri, May 12, 2023 at 5:03 AM Andrew Athan wrote: >> >>> goroutine 1299607 [runnable]: >>> context.(*valueCtx).Err(0xc00a52c3c0?) >>> :1 +0x3e >>> context.(*valueCtx).Err(0x48860a?) >>> :1 +0x2a >>> ... repeats many many many times ... >>> ...additional frames elided... >>> created by >>> one_of_my_functions() >>> somefile.go:2092 +0x4a5 >>> >>> >>> What is going on here? is this likely to be an infinite recursion or >>> similar within the context implementation or is this a normal thing to see? >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to golang-nuts...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/golang-nuts/095c81e9-15c2-4c27-b913-f85a16ee4968n%40googlegroups.com >>> >>> <https://groups.google.com/d/msgid/golang-nuts/095c81e9-15c2-4c27-b913-f85a16ee4968n%40googlegroups.com?utm_medium=email_source=footer> >>> . >>> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/20f8fdd6-d42b-4ab8-8024-61f9c7471b46n%40googlegroups.com.
Re: [go-nuts] interpreting runtime.Stack()
Alex:I’ll see how/if this can happen. Among other strangeness in this stack is that Err() doesn’t take a param but I guess it may be displaying the implicit “this”?btw this is not from a panic, but from a call to runtime.Stack(). The program experiences unbounded growth in cpu utilization as it runs so either these stacks are a recursion bc there is a context “pointing” to itself as parent or a very deep reference stack.I’m going to guess there is a captured continuation variable somewhere that is incorrectly updated to a new value ctx with each new connection made or inside some loop instead of using the oroginal basr ctx.I looked for that originally but didn’t find it, but I’ll look again. I’m concerned that net.Conn’s or tls.Conn’s setRead/WriteDeadline() calls are at fault somehow.A.On May 12, 2023, at 12:38 AM, Axel Wagner wrote:Ouh, I bet I know what's happening: You are using a concrete Context implementation that defines its methods on a value receiver, but pass it in as a nil-pointer: https://go.dev/play/p/JH9MxwvmTw7That way, the panic happens in autogenerated code (the implicit promoted method from the value-type to the pointer-type) which then panics due to a nil-pointer dereference. The panic message should then actually tell you exactly that, though.On Fri, May 12, 2023 at 9:32 AM Axel Wagner <axel.wagner...@googlemail.com> wrote:What does the panic say? If it says "stack overflow", then yes, that's likely an infinite recursion. If not, then, no. My guess is, that it says "nil-pointer dereference".The `` part probably means this is due to embedding. That is, the `Err` method on `valueCtx` is promoted from an embedded Context: https://cs.opensource.google/go/go/+/refs/tags/go1.20.4:src/context/context.go;l=599If that context was `nil` or otherwise invalid, that would explain why the panic happens. Though I'm not sure how that would happen, unless you use `unsafe` somewhere.On Fri, May 12, 2023 at 5:03 AM Andrew Athan <andrew...@gmail.com> wrote:goroutine 1299607 [runnable]:context.(*valueCtx).Err(0xc00a52c3c0?) :1 +0x3econtext.(*valueCtx).Err(0x48860a?) :1 +0x2a... repeats many many many times ..additional frames elided...created byone_of_my_functions() somefile.go:2092 +0x4a5What is going on here? is this likely to be an infinite recursion or similar within the context implementation or is this a normal thing to see? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/095c81e9-15c2-4c27-b913-f85a16ee4968n%40googlegroups.com. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/BBBF1FFC-FFCF-4FA7-B636-BC8B5B4911C1%40gmail.com.
[go-nuts] interpreting runtime.Stack()
goroutine 1299607 [runnable]: context.(*valueCtx).Err(0xc00a52c3c0?) :1 +0x3e context.(*valueCtx).Err(0x48860a?) :1 +0x2a ... repeats many many many times ... ...additional frames elided... created by one_of_my_functions() somefile.go:2092 +0x4a5 What is going on here? is this likely to be an infinite recursion or similar within the context implementation or is this a normal thing to see? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/095c81e9-15c2-4c27-b913-f85a16ee4968n%40googlegroups.com.
[go-nuts] http.Server ConnState behavior question
I could go read the source code so thanks in advance for saving me that step. Part of the reason I"m writing here is to also understand the recommended pattern... Does StateActive imply the handler function will definitely be called, or can this state occur without the Handler ever being called? If definite, I think the comments/docs could use some clarification. I need to definitively count net.Conn's that have been dropped prior to entering a handler function. ConnState provides a StateActive, but the docs imply this may be called after just 1 byte is read on the connection, which to my mind implies it may be called before the conn in question will ever result in a call to Handler. Here we can assume the net.Conn will not ever be idled or handle more than one request. I imagine if there is an error, the Handler will never be called and ConnState will get called again with StateClosed What I really want is to get a notification immediately prior to the handler function being called, so that I can get my hands on the net.Conn. Otherwise, I need to mark the net.Conn as having entered the handler function at the top of the handler function, which does not have direct access to the net.Conn because http.Request does not provide it. The workaround would be to stash the net.Conn as a value in the request.Context() via ConnContext, but holy crap. Why make me jump through so many hoops golang?! -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ed1fd75d-8a14-4b1c-b84f-d84490db084dn%40googlegroups.com.
[go-nuts] Re: tls panic inside /usr/local/go/src/crypto/tls/conn.go
go func() { select { case <-handshakeCtx.Done(): // Close the connection, discarding the error _ = c.conn.Close() interruptRes <- handshakeCtx.Err() case <-done: interruptRes <- nil } }() I believe the problem may be that this should have said: conn := c.conn if conn!= nil { conn.Close() } ??? I'll install golang 1.20 and see if the code has been improved and/or will submit a PR On Friday, February 10, 2023 at 2:25:53 PM UTC-8 Andrew Athan wrote: > Sorry, I meant to mention this is go 1.19 > > On Friday, February 10, 2023 at 2:24:39 PM UTC-8 Andrew Athan wrote: > >> panic: runtime error: invalid memory address or nil pointer dereference >> [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5d073c] >> goroutine 4133611 [running]: >> crypto/tls.(*Conn).handshakeContext.func2() >> /usr/local/go/src/crypto/tls/conn.go:1441 +0xbc >> created by crypto/tls.(*Conn).handshakeContext >> /usr/local/go/src/crypto/tls/conn.go:1437 +0x205 >> Main process exited, code=exited, status=2/INVALIDARGUMENT >> Failed with result 'exit-code'. >> >> I'm still evaluating this panic in a high load server app, probably >> related to using a custom dial func + specifying a handshake timeout. I'm >> guessing this is not a very oft-used feature of the stack, so I thought I'd >> post this while I go read the tls/conn.go code. Google did not immediately >> come up with other reports of this problem but given the location, and that >> my code doesn't mess with any conn internals beyond specifying the timeout, >> I'm thinking (probably incorrectly, lol) that this bug may not be mine. >> >> var internalTransport *http.Transport = { >> DialContext: func(ctx context.Context, network, addr string) (ret >> net.Conn, err error) { >>return transportDialFunc(ctx, network, addr, myStuff) >> }, >> TLSHandshakeTimeout: TLS_HANDSHAKE_TIMEOUT, >> } >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/7fe0c551-f2ea-4bc9-aaac-7ec9324309e3n%40googlegroups.com.
[go-nuts] Re: tls panic inside /usr/local/go/src/crypto/tls/conn.go
Sorry, I meant to mention this is go 1.19 On Friday, February 10, 2023 at 2:24:39 PM UTC-8 Andrew Athan wrote: > panic: runtime error: invalid memory address or nil pointer dereference > [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5d073c] > goroutine 4133611 [running]: > crypto/tls.(*Conn).handshakeContext.func2() > /usr/local/go/src/crypto/tls/conn.go:1441 +0xbc > created by crypto/tls.(*Conn).handshakeContext > /usr/local/go/src/crypto/tls/conn.go:1437 +0x205 > Main process exited, code=exited, status=2/INVALIDARGUMENT > Failed with result 'exit-code'. > > I'm still evaluating this panic in a high load server app, probably > related to using a custom dial func + specifying a handshake timeout. I'm > guessing this is not a very oft-used feature of the stack, so I thought I'd > post this while I go read the tls/conn.go code. Google did not immediately > come up with other reports of this problem but given the location, and that > my code doesn't mess with any conn internals beyond specifying the timeout, > I'm thinking (probably incorrectly, lol) that this bug may not be mine. > > var internalTransport *http.Transport = { > DialContext: func(ctx context.Context, network, addr string) (ret > net.Conn, err error) { >return transportDialFunc(ctx, network, addr, myStuff) > }, > TLSHandshakeTimeout: TLS_HANDSHAKE_TIMEOUT, > } > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ab19cff5-cc84-496f-bd40-3fc747565b1an%40googlegroups.com.
[go-nuts] tls panic inside /usr/local/go/src/crypto/tls/conn.go
panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5d073c] goroutine 4133611 [running]: crypto/tls.(*Conn).handshakeContext.func2() /usr/local/go/src/crypto/tls/conn.go:1441 +0xbc created by crypto/tls.(*Conn).handshakeContext /usr/local/go/src/crypto/tls/conn.go:1437 +0x205 Main process exited, code=exited, status=2/INVALIDARGUMENT Failed with result 'exit-code'. I'm still evaluating this panic in a high load server app, probably related to using a custom dial func + specifying a handshake timeout. I'm guessing this is not a very oft-used feature of the stack, so I thought I'd post this while I go read the tls/conn.go code. Google did not immediately come up with other reports of this problem but given the location, and that my code doesn't mess with any conn internals beyond specifying the timeout, I'm thinking (probably incorrectly, lol) that this bug may not be mine. var internalTransport *http.Transport = { DialContext: func(ctx context.Context, network, addr string) (ret net.Conn, err error) { return transportDialFunc(ctx, network, addr, myStuff) }, TLSHandshakeTimeout: TLS_HANDSHAKE_TIMEOUT, } -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/6b9d7ac0-cba3-434c-ade5-c25d4be506aan%40googlegroups.com.
Re: [go-nuts] %v display of nil map
I should have RTFMed, but even there, the nil display issue is not highlighted :) Thanks. It seemed odd that there wasn't already a way. It might be good to highlight this feature in the right places. I'm not sure if golangdocs.com is the official easy on-ramp for golang but if so, at https://golangdocs.com/string-formatting-in-golang 's section 1.5 the wording "print the Go-representation of the struct." could read "... the struct, and explicitly show valued slices and maps."; and the example could show this case. The same applies to the official documentation for the fmt package, which states (in the comments of one example): " // The %#v form (the # is called a "flag" in this context) shows the map in // the Go source format. Maps are printed in a consistent order, sorted" without reference to how nils are treated. In addition, I would argue that the unadorned %v documentation should mention that nil values are folded into the "empty" representation. Anyway, as time allows I'll find the doc source and submit PRs implementing the above suggestions. Thank you for pointing this solution out. Andrew On Wed, Jan 25, 2023 at 12:05 PM 'Dan Kortschak' via golang-nuts < golang-nuts@googlegroups.com> wrote: > On Wed, 2023-01-25 at 07:21 -0800, Andrew Athan wrote: > > I'm sure I'm not the first to say this, but here's my +1: > > > > It seems wrong to me that golang displays nil-valued reference types > > as an empty instance of the type with no indication that the > > reference is nil. > > > > E.g. > > ``` > > var m map[string]string > > fmt.Printf("%+v",m) > > ``` > > > > displays as "map[]" > > > > I think it would be better to display something like "map[]", > > don't you? > > > > Motivation: While the nil map does act like a map[] for reads, it > > does not act like one for writes, and debugging via prints can > > therefore be confusing for new users. > > > > For debugging, use %#v. https://go.dev/play/p/UlvaFg5Z_lB > > -- > You received this message because you are subscribed to a topic in the > Google Groups "golang-nuts" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/golang-nuts/6qKpr5_SXYA/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > golang-nuts+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/6e278c5a183432315bb86e19b4c4f7794c9b56ab.camel%40kortschak.io > . > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CACUDngDFuV%3DP5XXTKW2OEqxr0Q72iDECWxbGsX5HktRg4XiQLA%40mail.gmail.com.
[go-nuts] %v display of nil map
I'm sure I'm not the first to say this, but here's my +1: It seems wrong to me that golang displays nil-valued reference types as an empty instance of the type with no indication that the reference is nil. E.g. ``` var m map[string]string fmt.Printf("%+v",m) ``` displays as "map[]" I think it would be better to display something like "map[]", don't you? Motivation: While the nil map does act like a map[] for reads, it does not act like one for writes, and debugging via prints can therefore be confusing for new users. A. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/2935bec1-9123-4966-9872-0309f657da34n%40googlegroups.com.
Re: [go-nuts] Go 1.19 comparison of variables of generic type
Ian: Thanks. The example I posted is a silly uber short simplification of my usecase. In fact, have a complex struct with a large set of methods and only one of the methods requires comparable types; it'd be nice to not have to constrain to comparable at the struct level, and only have actual uses of the one method that does need comparables fail to compile if it's called on a non-comparable instantiation, or, fall back at runtime to some acceptable behavior ... anyway: Thanks for the docs pointer. I'll read. On Wednesday, January 18, 2023 at 7:01:51 PM UTC-8 Ian Lance Taylor wrote: > On Wed, Jan 18, 2023 at 6:58 PM Christian Stewart > wrote: > > > > On Wed, Jan 18, 2023 at 6:56 PM Ian Lance Taylor > wrote: > > > > // IsEmpty checks if the interface is equal to nil. > > > > func IsEmpty[T Block](blk T) bool { > > > > var empty T > > > > return empty == blk > > > > } > > > > > > > > (I had blk Block before, instead of blk T). > > > > > > > > Comparing with empty is something I've needed to do a bunch of times > > > > and have been unable to do. > > > > > > The type argument to a function like IsEmpty is rarely an interface > > > type. So the comparison in the instantiation IsEmpty is not comparing > > > values of interface type. It's comparing values of whatever type > > > IsEmpty is instantiated with. And it is possible to instantiate > > > IsEmpty with types that can't be compared, even with their zero value, > > > such as [1][]byte. > > > > This makes sense, however, is there any way to compare against empty > > in this context? I was wondering how to go about doing that. > > You can use a constraint of "comparable". A function that uses such a > constraint can only be instantiated with type arguments that are > comparable. > > Or, don't bother to use generics, and just write > reflect.ValueOf(x).IsZero(). > > Ian > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/d900d93e-c5c0-4806-a0ec-bb4bf4c1afb4n%40googlegroups.com.
Re: [go-nuts] Go 1.19 comparison of variables of generic type
By the way, what is the idiomatic way to assert that a variable that is type constrained as "any" in the generic declaration, is in fact comparable (if there is a way)? I.e., in my example "Foo" function, is there a way for me to further constrain (or rather, assert that) v's type is comparable, so that I can in fact do the comparison? Constraining to comparable for a single function is typically not a hardship, but if you have a struct with a bunch of interface functions, most of which don't need comparable, but only one of which does, it'd be nice not to jump through declarative hoops to make that happen. A. On Wednesday, January 18, 2023 at 4:59:51 PM UTC-8 bse...@computer.org wrote: > On Wed, Jan 18, 2023 at 5:52 PM Andrew Athan wrote: > >> (Possibly related to issues such as those discussed in >> https://groups.google.com/g/golang-nuts/c/pO2sclKEoQs/m/5JYjveKgCQAJ ?) >> >> If I do: >> >> ``` >> func Foo[V any](v V)bool { >> return v==v >> } >> ``` >> >> golang 1.19 reports: >> >> ``` >> invalid operation: v == v (incomparable types in type set) >> ``` >> >> There are two issues with this in my mind: (1) It is ambiguous in that I >> cannot be sure, as a new user, whether what's being indicated is an >> incompatibility between the actual types on either side of the equality >> test or between the set of possible types that COULD be on either side of >> the equality test due to V's any type constraing in either the case where >> the left and right side are same or different types (2) In this case, the >> type V appears to be determinable at compile time and yet it is claimed >> this equality test is in some way problematic. >> >> I'm sure I'm misunderstanding something about golang generics. >> >> Can someone comment on this? >> >> Thanks in advance :) >> > > > The problem here is that a type constraint is different from a type, but > the same identifier is overloaded in the language so "any" as a type > constraint means something else from "any" as a type. > > The error is there, because without that Foo([]string{}) would satisfy the > constraint but it is still a compile error. Foo[V comparable)(v V) bool is > the correct declaration. > > >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/7134400e-ed5e-4c9f-bacd-4b739daf0e0bn%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/7134400e-ed5e-4c9f-bacd-4b739daf0e0bn%40googlegroups.com?utm_medium=email_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/414ec7ec-33af-492c-b4c6-ed3b807fbc7dn%40googlegroups.com.
Re: [go-nuts] Go 1.19 comparison of variables of generic type
Thank you for the practical tip on how to avoid the error. The wording of the error could be improved, IMHO, and there is a remaining issue I raised which is not addressed by the suggestion to use the "comparable" constraint (btw, the documentation I've so far been served up by duckduckgo when looking for info on generics is way too introductory, and makes no mention of things like 'comparable'). The remaining issue is that, irrespective of the "wideness" of the "any" type constraint, which apparently includes non-comparable types, the resolution of v's type is to a comparable type, yet the error is still emitted. By the way, this is a classic case of seeing what you want to see ... my near vision is worsening and I read "comparable" in the error message as "compatible," which is at least in part why I found the error message so confusing. v==v, after all, involves two variables of the exact same type by definition :) A. On Wednesday, January 18, 2023 at 4:59:51 PM UTC-8 bse...@computer.org wrote: > On Wed, Jan 18, 2023 at 5:52 PM Andrew Athan wrote: > >> (Possibly related to issues such as those discussed in >> https://groups.google.com/g/golang-nuts/c/pO2sclKEoQs/m/5JYjveKgCQAJ ?) >> >> If I do: >> >> ``` >> func Foo[V any](v V)bool { >> return v==v >> } >> ``` >> >> golang 1.19 reports: >> >> ``` >> invalid operation: v == v (incomparable types in type set) >> ``` >> >> There are two issues with this in my mind: (1) It is ambiguous in that I >> cannot be sure, as a new user, whether what's being indicated is an >> incompatibility between the actual types on either side of the equality >> test or between the set of possible types that COULD be on either side of >> the equality test due to V's any type constraing in either the case where >> the left and right side are same or different types (2) In this case, the >> type V appears to be determinable at compile time and yet it is claimed >> this equality test is in some way problematic. >> >> I'm sure I'm misunderstanding something about golang generics. >> >> Can someone comment on this? >> >> Thanks in advance :) >> > > > The problem here is that a type constraint is different from a type, but > the same identifier is overloaded in the language so "any" as a type > constraint means something else from "any" as a type. > > The error is there, because without that Foo([]string{}) would satisfy the > constraint but it is still a compile error. Foo[V comparable)(v V) bool is > the correct declaration. > > >> >> -- >> You received this message because you are subscribed to the Google Groups >> "golang-nuts" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to golang-nuts...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/golang-nuts/7134400e-ed5e-4c9f-bacd-4b739daf0e0bn%40googlegroups.com >> >> <https://groups.google.com/d/msgid/golang-nuts/7134400e-ed5e-4c9f-bacd-4b739daf0e0bn%40googlegroups.com?utm_medium=email_source=footer> >> . >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/9067ad89-957c-4445-87b9-de9517f83052n%40googlegroups.com.
[go-nuts] Go 1.19 comparison of variables of generic type
(Possibly related to issues such as those discussed in https://groups.google.com/g/golang-nuts/c/pO2sclKEoQs/m/5JYjveKgCQAJ ?) If I do: ``` func Foo[V any](v V)bool { return v==v } ``` golang 1.19 reports: ``` invalid operation: v == v (incomparable types in type set) ``` There are two issues with this in my mind: (1) It is ambiguous in that I cannot be sure, as a new user, whether what's being indicated is an incompatibility between the actual types on either side of the equality test or between the set of possible types that COULD be on either side of the equality test due to V's any type constraing in either the case where the left and right side are same or different types (2) In this case, the type V appears to be determinable at compile time and yet it is claimed this equality test is in some way problematic. I'm sure I'm misunderstanding something about golang generics. Can someone comment on this? Thanks in advance :) -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/7134400e-ed5e-4c9f-bacd-4b739daf0e0bn%40googlegroups.com.
Re: [go-nuts] Golang 1.19+ preemption model on a preemptive linux kernel?
In brief then, in the presence of os threads running on a kernel that can preempt threads, it is incorrect to assume that any two statements within a goroutine will run atomically (both run, or not at all), irrespective of the simplicity of those statements, or whether any function calls involved are inlined, etc... On Monday, December 5, 2022 at 3:18:09 PM UTC-8 Andrew Athan wrote: > The statement I made is actually a bit stronger than the one you > confirmed: Even if the goroutines are using atomic load/store, the > preemtive nature of the os threads could easily interrupt one goroutine > between an atomic load and its use of that value, giving another goroutine > the opportunity to change the stored value at the atomic load location, > potentially leading to a data race -- particularly when the loader is > storing to a related but different location and/or without a CAS on the > original loaded value. > > To answer your question, no ... within the go runtime, I DO NOT claim to > have found instances of that kind of load/check/store as separate > operations within a function such that those operations are assumed to run > atomically. > > However, I've run into a couple of such instances in public repos. Thus, I > wanted to confirm my thinking. For example, I initiated a discussion about > same here: > > https://github.com/alphadose/haxmap/issues/26 > > (I ran across haxmap while reviewing issues in the golang repo relative to > sync.Map) > > On Monday, December 5, 2022 at 10:45:10 AM UTC-8 Ian Lance Taylor wrote: > >> On Mon, Dec 5, 2022 at 10:03 AM Andrew Athan wrote: >> > >> > I'm having trouble finding definitive information about golang's >> preemption model when running with GOMAXPROCS>1 on a multi-core Intel with >> preemtive linux kernel. >> > >> > As I understand it, in such a scenario, two goroutines may be scheduled >> by the go runtime onto two separate system threads on two separate CPUs. >> > >> > Isn't it true then, that irrespective of whether the two goroutines are >> scheduled onto separate CPUs, the OS may preemptively interrupt either of >> those goroutines to let the other run? Also, that if they are indeed >> scheduled onto separate CPUs, that the memory accesses made by those >> goroutines are interleaved even if no individual goroutine is "preempted"? >> > >> > I'm asking because in reviewing the code of some "lock free" concurrent >> data structures written in go, it appears the authors have made certain >> assumptions about race conditions (e.g., the code of on goroutine assumes >> that another goroutine won't perform a load/store between two function >> calls the first goroutine makes to check a boolean and store a value). >> > >> > Given that goroutines are mappes onto system threads, and that in a >> preemptive kernel those threads may be preempted and/or irrespective of the >> preemptive kernel issue may run on separate cores, no assumptions should be >> made about the "atomicity" of multiple statements in a goroutine relative >> to other goroutines. Right? >> > >> > Where can I get the most current and accurate information about this >> topic? >> >> I'm not aware of any detailed documentation of the issues you are >> looking at. So the most current and accurate information is the >> source code. Or this mailing list. >> >> You are correct that non-atomic memory operations made by different >> goroutines can be freely interleaved. If there is any code in the >> runtime that assumes otherwise, that code is badly broken. If you can >> point to the specific code that you are concerned about, perhaps we >> can allay your concerns, or perhaps we can fix the bug. Thanks. >> >> Ian >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/0b44c5d7-7c45-4392-9046-eb56f8830a52n%40googlegroups.com.
Re: [go-nuts] Golang 1.19+ preemption model on a preemptive linux kernel?
The statement I made is actually a bit stronger than the one you confirmed: Even if the goroutines are using atomic load/store, the preemtive nature of the os threads could easily interrupt one goroutine between an atomic load and its use of that value, giving another goroutine the opportunity to change the stored value at the atomic load location, potentially leading to a data race -- particularly when the loader is storing to a related but different location and/or without a CAS on the original loaded value. To answer your question, no ... within the go runtime, I DO NOT claim to have found instances of that kind of load/check/store as separate operations within a function such that those operations are assumed to run atomically. However, I've run into a couple of such instances in public repos. Thus, I wanted to confirm my thinking. For example, I initiated a discussion about same here: https://github.com/alphadose/haxmap/issues/26 (I ran across haxmap while reviewing issues in the golang repo relative to sync.Map) On Monday, December 5, 2022 at 10:45:10 AM UTC-8 Ian Lance Taylor wrote: > On Mon, Dec 5, 2022 at 10:03 AM Andrew Athan wrote: > > > > I'm having trouble finding definitive information about golang's > preemption model when running with GOMAXPROCS>1 on a multi-core Intel with > preemtive linux kernel. > > > > As I understand it, in such a scenario, two goroutines may be scheduled > by the go runtime onto two separate system threads on two separate CPUs. > > > > Isn't it true then, that irrespective of whether the two goroutines are > scheduled onto separate CPUs, the OS may preemptively interrupt either of > those goroutines to let the other run? Also, that if they are indeed > scheduled onto separate CPUs, that the memory accesses made by those > goroutines are interleaved even if no individual goroutine is "preempted"? > > > > I'm asking because in reviewing the code of some "lock free" concurrent > data structures written in go, it appears the authors have made certain > assumptions about race conditions (e.g., the code of on goroutine assumes > that another goroutine won't perform a load/store between two function > calls the first goroutine makes to check a boolean and store a value). > > > > Given that goroutines are mappes onto system threads, and that in a > preemptive kernel those threads may be preempted and/or irrespective of the > preemptive kernel issue may run on separate cores, no assumptions should be > made about the "atomicity" of multiple statements in a goroutine relative > to other goroutines. Right? > > > > Where can I get the most current and accurate information about this > topic? > > I'm not aware of any detailed documentation of the issues you are > looking at. So the most current and accurate information is the > source code. Or this mailing list. > > You are correct that non-atomic memory operations made by different > goroutines can be freely interleaved. If there is any code in the > runtime that assumes otherwise, that code is badly broken. If you can > point to the specific code that you are concerned about, perhaps we > can allay your concerns, or perhaps we can fix the bug. Thanks. > > Ian > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/998087d0-642a-4bad-ba9a-87c6a369496dn%40googlegroups.com.
[go-nuts] Golang 1.19+ preemption model on a preemptive linux kernel?
I'm having trouble finding definitive information about golang's preemption model when running with GOMAXPROCS>1 on a multi-core Intel with preemtive linux kernel. As I understand it, in such a scenario, two goroutines may be scheduled by the go runtime onto two separate system threads on two separate CPUs. Isn't it true then, that irrespective of whether the two goroutines are scheduled onto separate CPUs, the OS may preemptively interrupt either of those goroutines to let the other run? Also, that if they are indeed scheduled onto separate CPUs, that the memory accesses made by those goroutines are interleaved even if no individual goroutine is "preempted"? I'm asking because in reviewing the code of some "lock free" concurrent data structures written in go, it appears the authors have made certain assumptions about race conditions (e.g., the code of on goroutine assumes that another goroutine won't perform a load/store between two function calls the first goroutine makes to check a boolean and store a value). Given that goroutines are mappes onto system threads, and that in a preemptive kernel those threads may be preempted and/or irrespective of the preemptive kernel issue may run on separate cores, no assumptions should be made about the "atomicity" of multiple statements in a goroutine relative to other goroutines. Right? Where can I get the most current and accurate information about this topic? A. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/0912663b-d4cb-41ee-a335-466c74b00d8cn%40googlegroups.com.
Re: [go-nuts] vendors and modules
Thanks Ian ... so a couple of comments & clarifications (1) I see various other questions popping up in the list regarding go mod, go work, vendoring etc, and yes I certainly did review https://go.dev/blog/using-go-modules before posting my original question here. Point being, I think the documentation as currently presented is way too dense, leaves many degrees of freedom open, and thus it remains generally hard to quickly get to a basic understanding of the best practice of common usecases. I think the docs would greatly benefit from a list of those use cases that present a very brief outline of the commands that would be used to implement each, perhaps with some abridged contents of the go.mod's etc that result. (2) With respect to my original question the answer for me was (as you mentioned) go get github.com/dustinxie/lockfree ... add the import to appropriate places in the source go mod tidy go mod vendor My original mistake was to run go mod tidy too early, such that it (silently) removed the lockfree package from go.mod because it did not appear anywhere in the source code. Yes, I acknowledge that go mod tidy is documented to clean up go.mod in that manner, but for whatever reason, I missed that, and it is silent in its cleanup. I was motivate to try go mod tidy because I noticed the the original go get dropped the module into go.mod as an indirect reference, and I wasn't sure that was correct I might suggest that the -v option be made the default, and that a -q "silent" option be provided instead? Where can I make that suggestion to the golang maintainers? (3) Now, imagine I wan't to make modifications to lockfree in such a way that those modifications can be submitted to my company's private repo, so that other developers can build the overall project successfully, and the modifications to lockfree can eventually be PR'ed to the original lockfree project. If I only fork lockfree to a new github repo, and I try to work with the go get/etc commands I will run into problems because in that new github repo, the lockfree/go.mod will contain the "wrong" reference for the module (it will point to the original github repo instead of the forked one). To overcome this issue, in the repo that wants to use the modified lockfree I create a directory to contain all my git submodules and in there I do: cd ~/my-go-project mkdir submodules cd submodules git submodule add --depth=1 g...@github.com:my-company/lockfree.git within that new clone I can then do the necessary feature additions to lockfree. Now, to resolve the issues with go's module system I then either: (3a) add a `replace github.com/dustinxie/lockfree => ./submodules/lockfree` in the project's go.mod OR (3b) yes, I verified this works ok even in the project dir that contains its go.mod: cd ~/my-go/project go work init got work add . go work add ./submodules/lockfree (4) Note: My understanding of the intent for `go mod vendor` is to snapshot the "external" sources used to build a project. Reasonably: I might expect the contents of the vendor'ed lockfree project to reflect what was actually being used to build the project in the context that go mod vendor executed in. Empirically: `go mod vendor` instead deposits a copy of lockfree from the original project source, not the source referenced in my go.work file. Should this difference be reported for consideration as a bug? If so, where should I do that? Thanks in advance for your responses. A. On Thursday, December 1, 2022 at 3:53:13 PM UTC-8 Ian Lance Taylor wrote: > On Thu, Dec 1, 2022 at 3:23 PM Andrew Athan wrote: > > > > I am new to go devops (but not to the language). First, I must say, the > go module documentation is thorough but absolutely inscrutable for new > users. Googling for things like "golang add github module vendor" brings up > what appear to be either outdated or incorrect cookbooks. I've already > wasted 1 hour trying to figure out "the right way" to a module provided by > a github repo to an existing vendor'ed golang project. > > > > In short: HLP! > > > > All I want to do is use `github.com/dustinxie/lockfree.git` > <http://github.com/dustinxie/lockfree.git> in the project, which *does* > commit the vendor directory to its git repo. I cannot seem to find any > semver defined in the lockfree project so I have no idea what to specify by > hand to go.mod, and there is a bewildering set possible commands to use ... > from `go get` to `go install` to `govendor` to `godep` (the latter appear > to be old news?) > > > > I would be eternally grateful for a few simple examples added to the > golang reference and/or tutorials for how to do this. > > First make sure that you have a go.mod file, typically by running "go > mod init my-package-path".
[go-nuts] vendors and modules
I am new to go devops (but not to the language). First, I must say, the go module documentation is thorough but absolutely inscrutable for new users. Googling for things like "golang add github module vendor" brings up what appear to be either outdated or incorrect cookbooks. I've already wasted 1 hour trying to figure out "the right way" to a module provided by a github repo to an existing vendor'ed golang project. In short: HLP! All I want to do is use `github.com/dustinxie/lockfree.git` in the project, which *does* commit the vendor directory to its git repo. I cannot seem to find any semver defined in the lockfree project so I have no idea what to specify by hand to go.mod, and there is a bewildering set possible commands to use ... from `go get` to `go install` to `govendor` to `godep` (the latter appear to be old news?) I would be eternally grateful for a few simple examples added to the golang reference and/or tutorials for how to do this. Thanks in advance for your guidance. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/9d6c72d8-ad7f-444b-9593-07056c0151e8n%40googlegroups.com.