fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

rpc: use old module name when registering gob values (#408)

When rolling out the module rename everything worked unless your zoekt
cluster was out of sync with the sourcegraph cluster. Then in that case
we couldn't match up names in gob decoding, leading to the RPC wire
protocol breaking. The error showing up one sourcegraph.com was like:

error during decoding: ...

Test Plan: printed the names it generates and inspected it. Additionally
I will do more testing with sourcegraph and mismatched versions to
ensure everything continues to work.

+77 -18
+77 -18
rpc/rpc.go
··· 6 6 "encoding/gob" 7 7 "fmt" 8 8 "net/http" 9 + "reflect" 10 + "strings" 9 11 "sync" 10 12 "time" 11 13 14 + "github.com/keegancsmith/rpc" 12 15 "github.com/sourcegraph/zoekt" 13 16 "github.com/sourcegraph/zoekt/query" 14 17 "github.com/sourcegraph/zoekt/rpc/internal/srv" 15 - "github.com/keegancsmith/rpc" 16 18 ) 17 19 18 20 // DefaultRPCPath is the rpc path used by zoekt-webserver ··· 128 130 // once, because calls to gob.Register are protected by a sync.Once. 129 131 func RegisterGob() { 130 132 once.Do(func() { 131 - gob.Register(&query.And{}) 132 - gob.Register(&query.BranchRepos{}) 133 - gob.Register(&query.BranchesRepos{}) 134 - gob.Register(&query.Branch{}) 135 - gob.Register(&query.Const{}) 136 - gob.Register(&query.GobCache{}) 137 - gob.Register(&query.Language{}) 138 - gob.Register(&query.Not{}) 139 - gob.Register(&query.Or{}) 140 - gob.Register(&query.Regexp{}) 141 - gob.Register(&query.RepoRegexp{}) 142 - gob.Register(&query.RepoSet{}) 143 - gob.Register(&query.Repo{}) 144 - gob.Register(&query.Substring{}) 145 - gob.Register(&query.Symbol{}) 146 - gob.Register(&query.Type{}) 147 - gob.Register(query.RawConfig(41)) 133 + gobRegister(&query.And{}) 134 + gobRegister(&query.BranchRepos{}) 135 + gobRegister(&query.BranchesRepos{}) 136 + gobRegister(&query.Branch{}) 137 + gobRegister(&query.Const{}) 138 + gobRegister(&query.GobCache{}) 139 + gobRegister(&query.Language{}) 140 + gobRegister(&query.Not{}) 141 + gobRegister(&query.Or{}) 142 + gobRegister(&query.Regexp{}) 143 + gobRegister(&query.RepoRegexp{}) 144 + gobRegister(&query.RepoSet{}) 145 + gobRegister(&query.Repo{}) 146 + gobRegister(&query.Substring{}) 147 + gobRegister(&query.Symbol{}) 148 + gobRegister(&query.Type{}) 149 + gobRegister(query.RawConfig(41)) 148 150 }) 149 151 } 152 + 153 + // gobRegister exists to keep backwards compatibility around renames of the go 154 + // module. This is to avoid breaking the wire protocol due to refactors. In 155 + // particular in August 2022 we renamed the go module from 156 + // github.com/google/zoekt to github.com/sourcegraph/zoekt which breaks the 157 + // wire protocol. So this function will replace those names so we keep using 158 + // google/zoekt. 159 + func gobRegister(value any) { 160 + name := gobRegister_name(value) 161 + 162 + name = strings.Replace(name, "github.com/sourcegraph/", "github.com/google/", 1) 163 + 164 + gob.RegisterName(name, value) 165 + } 166 + 167 + // gobRegister_name is copy-pasta from the stdlib gob.Register, returning the 168 + // name it picks for gob.RegisterName. 169 + func gobRegister_name(value any) string { 170 + // Default to printed representation for unnamed types 171 + rt := reflect.TypeOf(value) 172 + name := rt.String() 173 + 174 + // But for named types (or pointers to them), qualify with import path (but see inner comment). 175 + // Dereference one pointer looking for a named type. 176 + star := "" 177 + if rt.Name() == "" { 178 + if pt := rt; pt.Kind() == reflect.Pointer { 179 + star = "*" 180 + // NOTE: The following line should be rt = pt.Elem() to implement 181 + // what the comment above claims, but fixing it would break compatibility 182 + // with existing gobs. 183 + // 184 + // Given package p imported as "full/p" with these definitions: 185 + // package p 186 + // type T1 struct { ... } 187 + // this table shows the intended and actual strings used by gob to 188 + // name the types: 189 + // 190 + // Type Correct string Actual string 191 + // 192 + // T1 full/p.T1 full/p.T1 193 + // *T1 *full/p.T1 *p.T1 194 + // 195 + // The missing full path cannot be fixed without breaking existing gob decoders. 196 + rt = pt 197 + } 198 + } 199 + if rt.Name() != "" { 200 + if rt.PkgPath() == "" { 201 + name = star + rt.Name() 202 + } else { 203 + name = star + rt.PkgPath() + "." + rt.Name() 204 + } 205 + } 206 + 207 + return name 208 + }