Skip to content

Go Language

Troubleshooting: Different Valid Tracing ID are Mingled Together

Last week, users have reported a weird issue because they found:

  • Server has received 10+ same requests to the same API in a single trace, and it's impossible.
  • Server made another RPC call when serving, the egress logging interceptor reports 2 different tracing ID. The first one is set to the context logger after parsing the trace id from client, and the second one is retrieved from the context. They should be the same.
  • The data put inside the context(will be propagated by underlying SDK when RPC) cannot be propagated to the server.

This issue is complicated due to the involved components and the cross services. It takes me a lot of time to troubleshoot and finally I found the root cause successfully. The issue happened because user used gin.Context as context.Context directly inside a spawned go routine, however, gin tries to reuse the gin.Context for another request. As a result, the go routine spawned by previous request will be affected by the new request, and the request id mingles.

gotypesalias=1 does not seem to get used correctly for deps on Go 1.23

Recently, I have help to troubleshooting the Go type alias issue inside packages.Load, which relates x/tools, go list and cmd/compile. My original CL is correct, but I got confused when I found the exportdata contains all aliases regardless gotypealias setting. Then, tim has shepherded my CL by another CL to fix it.

Feel a bit frustrated when I saw the email when I got up. But it helps me a lot to learn how go toolchain and cmd/compile works. Think twice before you act!

Domain gopkg.in has a different V2 convention

Typically, a v2 go module path looks like github.com/xieyuschen/yaml/v3, however the gopkg.in has its own convention which is gopkg.in/yaml.v3.

Since gopkg.in shares the same version suffix methodology as Go modules, the Go command accepts the .v2 in gopkg.in/yaml.v2 as a valid major version suffix. This is a special case for compatibility with gopkg.in: modules hosted at other domains need a slash suffix like /v2.

Mapping Values by a Combination of Two Keys

The topic was found during optimization. When the combination of 2 string type keys maps to a value, how do you maintain the mapping from keys to the value? Generally we can come up with 3 approaches listed below, which one is better?

type Result string

// 1d map, you need to concatenate 2 strings
var d1M map[string]Result

// 1d map and use struct as key
type Key struct {
    S1, S2 string
}
var d1MS map[Key]Result

// 2d map
var d2M map[string]map[string]Result

How Go Finds Std Libs

Usually, the go standard library is located under $GOROOT and it's go compiler's scope to find the std libs, so most of the users needn't care about how the standard library is found by compiler.

When we want to combine 2 services into a single process, we need to solve the collision of global states between 2 services in the standard library. By duplicating it with another name(and all underlying dependent packages) under GOROOT, we can segregate the global states well even though they refer to the same package before combining. However, this requires to investigate how go compiler finds the std lib to ensure the approach won't break.