mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 10:58:57 +00:00
* Trigger connection loop on config device addition (fixes #7600) * Also check for device address equality * Move EqualStrings from api_test to utils, and use in connections/service.go * Make sure CommitConfiguration cannot block due on the deviceAddressesChanged channel * Update lib/connections/service.go Co-authored-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
parent
8734fa65fc
commit
66662cd678
@ -42,6 +42,7 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
"github.com/syncthing/syncthing/lib/tlsutil"
|
||||
"github.com/syncthing/syncthing/lib/ur"
|
||||
"github.com/syncthing/syncthing/lib/util"
|
||||
"github.com/thejerf/suture/v4"
|
||||
)
|
||||
|
||||
@ -126,6 +127,7 @@ func TestStopAfterBrokenConfig(t *testing.T) {
|
||||
|
||||
srv := New(protocol.LocalDeviceID, w, "", "syncthing", nil, nil, nil, events.NoopLogger, nil, nil, nil, nil, nil, nil, false).(*service)
|
||||
defer os.Remove(token)
|
||||
|
||||
srv.started = make(chan string)
|
||||
|
||||
sup := suture.New("test", svcutil.SpecWithDebugLogger(l))
|
||||
@ -1178,7 +1180,7 @@ func TestBrowse(t *testing.T) {
|
||||
|
||||
for _, tc := range cases {
|
||||
ret := browseFiles(tc.current, fs.FilesystemTypeBasic)
|
||||
if !equalStrings(ret, tc.returns) {
|
||||
if !util.EqualStrings(ret, tc.returns) {
|
||||
t.Errorf("browseFiles(%q) => %q, expected %q", tc.current, ret, tc.returns)
|
||||
}
|
||||
}
|
||||
@ -1389,18 +1391,6 @@ func TestSanitizedHostname(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func equalStrings(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// runningInContainer returns true if we are inside Docker or LXC. It might
|
||||
// be prone to false negatives if things change in the future, but likely
|
||||
// not false positives.
|
||||
|
@ -141,10 +141,11 @@ type service struct {
|
||||
natService *nat.Service
|
||||
evLogger events.Logger
|
||||
|
||||
listenersMut sync.RWMutex
|
||||
listeners map[string]genericListener
|
||||
listenerTokens map[string]suture.ServiceToken
|
||||
listenerSupervisor *suture.Supervisor
|
||||
deviceAddressesChanged chan struct{}
|
||||
listenersMut sync.RWMutex
|
||||
listeners map[string]genericListener
|
||||
listenerTokens map[string]suture.ServiceToken
|
||||
listenerSupervisor *suture.Supervisor
|
||||
}
|
||||
|
||||
func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *tls.Config, discoverer discover.Finder, bepProtocolName string, tlsDefaultCommonName string, evLogger events.Logger) Service {
|
||||
@ -165,9 +166,10 @@ func NewService(cfg config.Wrapper, myID protocol.DeviceID, mdl Model, tlsCfg *t
|
||||
natService: nat.NewService(myID, cfg),
|
||||
evLogger: evLogger,
|
||||
|
||||
listenersMut: sync.NewRWMutex(),
|
||||
listeners: make(map[string]genericListener),
|
||||
listenerTokens: make(map[string]suture.ServiceToken),
|
||||
deviceAddressesChanged: make(chan struct{}, 1),
|
||||
listenersMut: sync.NewRWMutex(),
|
||||
listeners: make(map[string]genericListener),
|
||||
listenerTokens: make(map[string]suture.ServiceToken),
|
||||
|
||||
// A listener can fail twice, rapidly. Any more than that and it
|
||||
// will be put on suspension for ten minutes. Restarts and changes
|
||||
@ -392,6 +394,7 @@ func (s *service) connect(ctx context.Context) error {
|
||||
l.Debugln("Next connection loop in", sleep)
|
||||
|
||||
select {
|
||||
case <-s.deviceAddressesChanged:
|
||||
case <-time.After(sleep):
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
@ -675,6 +678,8 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
|
||||
}
|
||||
}
|
||||
|
||||
s.checkAndSignalConnectLoopOnUpdatedDevices(from, to)
|
||||
|
||||
s.listenersMut.Lock()
|
||||
seen := make(map[string]struct{})
|
||||
for _, addr := range to.Options.ListenAddresses() {
|
||||
@ -733,6 +738,25 @@ func (s *service) CommitConfiguration(from, to config.Configuration) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (s *service) checkAndSignalConnectLoopOnUpdatedDevices(from, to config.Configuration) {
|
||||
oldDevices := make(map[protocol.DeviceID]config.DeviceConfiguration, len(from.Devices))
|
||||
for _, dev := range from.Devices {
|
||||
oldDevices[dev.DeviceID] = dev
|
||||
}
|
||||
|
||||
for _, dev := range to.Devices {
|
||||
oldDev, ok := oldDevices[dev.DeviceID]
|
||||
if !ok || !util.EqualStrings(oldDev.Addresses, dev.Addresses) {
|
||||
select {
|
||||
case s.deviceAddressesChanged <- struct{}{}:
|
||||
default:
|
||||
// channel is blocked - a config update is already pending for the connection loop.
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) AllAddresses() []string {
|
||||
s.listenersMut.RLock()
|
||||
var addrs []string
|
||||
|
@ -280,3 +280,15 @@ func NiceDurationString(d time.Duration) string {
|
||||
}
|
||||
return d.String()
|
||||
}
|
||||
|
||||
func EqualStrings(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user