Wait quietly for an absent braille display
Helper retries BrlAPI open in-process until BRLTTY answers, supervisor waits with the parked helper instead of kill/respawn cycles, exponential backoff and warn-once for real helper exits, bounded give-up so permanent failures still surface.
This commit is contained in:
1 parent
6c10ed0517
commit
002e515edf
5 files changed
+279
-15
No files matched your search
@@ -11,6 +11,43 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// openRetryDelay and openRetryGiveUp bound the in-helper wait for a
|
||||
// display to become ready. Variables so tests can shrink them.
|
||||
var (
|
||||
openRetryDelay = time.Second
|
||||
openRetryGiveUp = 4 * time.Minute
|
||||
)
|
||||
|
||||
// openWithRetry waits for a usable display inside the helper. While a
|
||||
// display is switched off or still negotiating, BRLTTY stalls, refuses, or
|
||||
// half-answers connection attempts (query failures, zero geometry); each
|
||||
// is transient, so retrying here claims the display as soon as BRLTTY is
|
||||
// ready instead of bouncing through supervisor respawn backoff. The last
|
||||
// error is returned at the give-up bound so permanent misconfiguration
|
||||
// (e.g. authorization) still surfaces to the parent's log.
|
||||
func openWithRetry(ctx context.Context, backend Backend) (Geometry, error) {
|
||||
deadline := time.NewTimer(openRetryGiveUp)
|
||||
defer deadline.Stop()
|
||||
for {
|
||||
geometry, err := backend.Open()
|
||||
if err == nil {
|
||||
if _, cellErr := geometry.Cells(); cellErr == nil {
|
||||
return geometry, nil
|
||||
} else {
|
||||
err = cellErr
|
||||
}
|
||||
_ = backend.Close()
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return Geometry{}, ctx.Err()
|
||||
case <-deadline.C:
|
||||
return Geometry{}, err
|
||||
case <-time.After(openRetryDelay):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RunClient owns BrlAPI inside the disposable helper process. The parent can
|
||||
// terminate this process if a native call blocks or BRLTTY disconnects.
|
||||
func RunClient(ctx context.Context, backend Backend, input io.ReadCloser, ready io.Writer) (result error) {
|
||||
@@ -18,11 +55,14 @@ func RunClient(ctx context.Context, backend Backend, input io.ReadCloser, ready
|
||||
// produced an unexpected EOF with the live BRLTTY connection.
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
geometry, err := backend.Open()
|
||||
defer func() { result = errors.Join(result, backend.Close()) }()
|
||||
geometry, err := openWithRetry(ctx, backend)
|
||||
if err != nil {
|
||||
if ctx.Err() != nil {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer func() { result = errors.Join(result, backend.Close()) }()
|
||||
cells, err := geometry.Cells()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in new issue
Block a user