internal/postgres: sort symbols to prevent deadlocks
Before inserting into symbols, package_symbols and documentation_symbols,
sort to prevent deadlocks.
For golang/go#37102
Change-Id: Ibcf5e6bc9f30320499ea0ea28db4a67f3a67d4e8
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/304509
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
diff --git a/internal/postgres/symbol.go b/internal/postgres/symbol.go
index 5a15de1..4700db1 100644
--- a/internal/postgres/symbol.go
+++ b/internal/postgres/symbol.go
@@ -8,6 +8,7 @@
"context"
"database/sql"
"fmt"
+ "sort"
"github.com/lib/pq"
"golang.org/x/pkgsite/internal"
@@ -105,10 +106,17 @@
// Get the difference between the documentation_symbols for this package,
// and the ones that already exist in the documentation_symbols table. Only
// insert rows that do not already exist.
+ //
+ // Sort first to prevent deadlocks.
+ var docIDs []int
+ for docID := range docIDToPkgsymIDs {
+ docIDs = append(docIDs, docID)
+ }
+ sort.Ints(docIDs)
var values []interface{}
- for docID, pkgsymIDSet := range docIDToPkgsymIDs {
+ for _, docID := range docIDs {
gotSet := gotDocIDToPkgsymIDs[docID]
- for pkgsymID := range pkgsymIDSet {
+ for pkgsymID := range docIDToPkgsymIDs[docID] {
if !gotSet[pkgsymID] {
values = append(values, docID, pkgsymID)
}
@@ -182,8 +190,16 @@
return nil, err
}
+ // Sort to prevent deadlocks.
+ var paths []string
+ for path := range pathToDocIDToDoc {
+ paths = append(paths, path)
+ }
+ sort.Strings(paths)
+
var packageSymbols []interface{}
- for path, docs := range pathToDocIDToDoc {
+ for _, path := range paths {
+ docs := pathToDocIDToDoc[path]
pathID := pathToID[path]
if pathID == 0 {
return nil, fmt.Errorf("pathID cannot be 0: %q", path)
@@ -268,6 +284,7 @@
return nil, err
}
+ sort.Strings(names)
var values []interface{}
for _, name := range names {
if _, ok := nameToID[name]; !ok {