mirror of
https://github.com/netbirdio/netbird.git
synced 2026-05-20 15:49:55 +00:00
- Peers.Get returns Status{Status: DaemonUnavailable} on Unavailable
instead of an error so the React useStatus initial refresh picks up
the same string the live event stream emits — the overlay no longer
depends on receiving the synthetic event during boot.
- ProfileContext.refresh swallows Unavailable so the redundant
"Load Profiles Failed" popup does not overlap the overlay.
- Tray Profiles submenu is disabled while the daemon is unavailable,
matching the existing settings/debug/connect gating.
- gRPC client uses a 5s ConnectParams MaxDelay; the default 120s cap
was keeping the SubChannel in backoff for tens of seconds after the
daemon came back, masking the recovery.
73 lines
1.8 KiB
Go
73 lines
1.8 KiB
Go
//go:build !android && !ios && !freebsd && !js
|
|
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"runtime"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/backoff"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
|
|
"github.com/netbirdio/netbird/client/proto"
|
|
"github.com/netbirdio/netbird/client/ui/desktop"
|
|
)
|
|
|
|
// Conn is a lazy, lock-protected gRPC connection to the NetBird daemon.
|
|
// One Conn instance is shared by all services so they reuse the same channel.
|
|
type Conn struct {
|
|
addr string
|
|
|
|
mu sync.Mutex
|
|
client proto.DaemonServiceClient
|
|
}
|
|
|
|
func NewConn(addr string) *Conn {
|
|
return &Conn{addr: addr}
|
|
}
|
|
|
|
func (c *Conn) Client() (proto.DaemonServiceClient, error) {
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
if c.client != nil {
|
|
return c.client, nil
|
|
}
|
|
|
|
cc, err := grpc.NewClient(
|
|
strings.TrimPrefix(c.addr, "tcp://"),
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
grpc.WithUserAgent(desktop.GetUIUserAgent()),
|
|
// Without ConnectParams the SubChannel uses gRPC's default 120s
|
|
// MaxDelay, so after a couple of failed dials the UI waits 30-60s
|
|
// before noticing a freshly-started daemon. The Wails UI is a
|
|
// desktop client expecting prompt reconnects, not a high-fanout
|
|
// backend, so a 5s cap is a better trade-off than the default.
|
|
grpc.WithConnectParams(grpc.ConnectParams{
|
|
Backoff: backoff.Config{
|
|
BaseDelay: 1 * time.Second,
|
|
Multiplier: 1.6,
|
|
Jitter: 0.2,
|
|
MaxDelay: 5 * time.Second,
|
|
},
|
|
}),
|
|
)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("dial daemon: %w", err)
|
|
}
|
|
c.client = proto.NewDaemonServiceClient(cc)
|
|
return c.client, nil
|
|
}
|
|
|
|
// DaemonAddr returns the default daemon gRPC address for the current OS.
|
|
// Linux/macOS use a Unix socket; Windows uses TCP loopback.
|
|
func DaemonAddr() string {
|
|
if runtime.GOOS == "windows" {
|
|
return "tcp://127.0.0.1:41731"
|
|
}
|
|
return "unix:///var/run/netbird.sock"
|
|
}
|