Skip to content

Commit fa0e787

Browse files
committed
testserver: fix URL file polling code
The asynchronous code that polls for the URL file leads to very opaque failures. This change reworks this code to waiting synchronously, so that we know the server is started before we return. In cases of failure, we now get more useful errors.
1 parent b5ebaaa commit fa0e787

File tree

2 files changed

+25
-16
lines changed

2 files changed

+25
-16
lines changed

testserver/testserver.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -760,34 +760,44 @@ func (ts *testServerImpl) WaitForInit() error {
760760
}
761761

762762
func (ts *testServerImpl) pollListeningURLFile(nodeNum int) error {
763+
log.Printf("node %d: waiting for listening URL file %q\n", nodeNum, ts.nodes[nodeNum].listeningURLFile)
763764
var data []byte
764-
for i := 0; i < ts.serverArgs.pollListenURLTimeoutSeconds*10; i++ {
765+
var err error
766+
maxWait := time.Duration(ts.serverArgs.pollListenURLTimeoutSeconds) * time.Second
767+
for startTime := time.Now(); ; {
765768
ts.mu.RLock()
766769
state := ts.nodes[nodeNum].state
767770
ts.mu.RUnlock()
768771
if state != stateRunning {
769-
return fmt.Errorf("server stopped or crashed before listening URL file was available")
772+
return fmt.Errorf("node %d stopped or crashed before listening URL file was available", nodeNum)
770773
}
771-
var err error
772774
data, err = os.ReadFile(ts.nodes[nodeNum].listeningURLFile)
773-
if len(data) == 0 {
775+
// There are two cases where we want to retry:
776+
// - the file does not exist yet.
777+
// - the file exists but it is empty (we probably raced with the file being written).
778+
if (os.IsNotExist(err) || (err == nil && len(data) == 0)) && time.Since(startTime) < maxWait {
774779
time.Sleep(100 * time.Millisecond)
775780
continue
776-
} else if err == nil {
777-
break
778-
} else if !os.IsNotExist(err) {
779-
return fmt.Errorf("unexpected error while reading listening URL file: %w", err)
780781
}
782+
break
781783
}
782784

785+
if err != nil {
786+
if !os.IsNotExist(err) {
787+
return fmt.Errorf("node %d: unexpected error while reading listening URL file %q: %w", nodeNum, ts.nodes[nodeNum].listeningURLFile, err)
788+
}
789+
return fmt.Errorf("node %d: file %q did not show up afer %d seconds", nodeNum, ts.nodes[nodeNum].listeningURLFile, ts.serverArgs.pollListenURLTimeoutSeconds)
790+
}
783791
if len(data) == 0 {
784-
panic("empty connection string")
792+
return fmt.Errorf("node %d: listening URL file %q is empty", nodeNum, ts.nodes[nodeNum].listeningURLFile)
785793
}
786794

787795
u, err := url.Parse(string(bytes.TrimSpace(data)))
788796
if err != nil {
789797
return fmt.Errorf("failed to parse SQL URL: %w", err)
790798
}
799+
log.Printf("node %d: got URL %s\n", nodeNum, u)
800+
791801
ts.pgURL[nodeNum].orig = *u
792802
if pw := ts.serverArgs.rootPW; pw != "" {
793803
db, err := sql.Open("postgres", u.String())

testserver/testservernode.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,12 @@ func (ts *testServerImpl) StartNode(i int) error {
148148
capturedI := i
149149

150150
if ts.pgURL[capturedI].u == nil {
151-
go func() {
152-
if err := ts.pollListeningURLFile(capturedI); err != nil {
153-
log.Printf("%s failed to poll listening URL file: %v", testserverMessagePrefix, err)
154-
close(ts.pgURL[capturedI].set)
155-
ts.Stop()
156-
}
157-
}()
151+
if err := ts.pollListeningURLFile(capturedI); err != nil {
152+
log.Printf("%s failed to poll listening URL file: %v", testserverMessagePrefix, err)
153+
close(ts.pgURL[capturedI].set)
154+
ts.Stop()
155+
return err
156+
}
158157
}
159158

160159
return nil

0 commit comments

Comments
 (0)