mirror of
https://github.com/netbirdio/netbird.git
synced 2025-06-20 17:58:02 +02:00
Fix/connection listener (#777)
Fix add/remove connection listener In case we call the RemoveConnListener from Java then we lose the reference from the original instance
This commit is contained in:
parent
769388cd21
commit
86f9051a30
@ -118,12 +118,12 @@ func (c *Client) PeersList() *PeerInfoArray {
|
|||||||
return &PeerInfoArray{items: peerInfos}
|
return &PeerInfoArray{items: peerInfos}
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddConnectionListener add new network connection listener
|
// SetConnectionListener set the network connection listener
|
||||||
func (c *Client) AddConnectionListener(listener ConnectionListener) {
|
func (c *Client) SetConnectionListener(listener ConnectionListener) {
|
||||||
c.recorder.AddConnectionListener(listener)
|
c.recorder.SetConnectionListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveConnectionListener remove connection listener
|
// RemoveConnectionListener remove connection listener
|
||||||
func (c *Client) RemoveConnectionListener(listener ConnectionListener) {
|
func (c *Client) RemoveConnectionListener() {
|
||||||
c.recorder.RemoveConnectionListener(listener)
|
c.recorder.RemoveConnectionListener()
|
||||||
}
|
}
|
||||||
|
@ -14,32 +14,31 @@ const (
|
|||||||
type notifier struct {
|
type notifier struct {
|
||||||
serverStateLock sync.Mutex
|
serverStateLock sync.Mutex
|
||||||
listenersLock sync.Mutex
|
listenersLock sync.Mutex
|
||||||
listeners map[Listener]struct{}
|
listener Listener
|
||||||
currentServerState bool
|
currentServerState bool
|
||||||
currentClientState bool
|
currentClientState bool
|
||||||
lastNotification int
|
lastNotification int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNotifier() *notifier {
|
func newNotifier() *notifier {
|
||||||
return ¬ifier{
|
return ¬ifier{}
|
||||||
listeners: make(map[Listener]struct{}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) addListener(listener Listener) {
|
func (n *notifier) setListener(listener Listener) {
|
||||||
n.listenersLock.Lock()
|
n.listenersLock.Lock()
|
||||||
defer n.listenersLock.Unlock()
|
defer n.listenersLock.Unlock()
|
||||||
|
|
||||||
n.serverStateLock.Lock()
|
n.serverStateLock.Lock()
|
||||||
go n.notifyListener(listener, n.lastNotification)
|
n.notifyListener(listener, n.lastNotification)
|
||||||
n.serverStateLock.Unlock()
|
n.serverStateLock.Unlock()
|
||||||
n.listeners[listener] = struct{}{}
|
|
||||||
|
n.listener = listener
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) removeListener(listener Listener) {
|
func (n *notifier) removeListener() {
|
||||||
n.listenersLock.Lock()
|
n.listenersLock.Lock()
|
||||||
defer n.listenersLock.Unlock()
|
defer n.listenersLock.Unlock()
|
||||||
delete(n.listeners, listener)
|
n.listener = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) updateServerStates(mgmState bool, signalState bool) {
|
func (n *notifier) updateServerStates(mgmState bool, signalState bool) {
|
||||||
@ -64,7 +63,7 @@ func (n *notifier) updateServerStates(mgmState bool, signalState bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
n.lastNotification = n.calculateState(newState, n.currentClientState)
|
n.lastNotification = n.calculateState(newState, n.currentClientState)
|
||||||
go n.notifyAll(n.lastNotification)
|
n.notify(n.lastNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) clientStart() {
|
func (n *notifier) clientStart() {
|
||||||
@ -72,7 +71,7 @@ func (n *notifier) clientStart() {
|
|||||||
defer n.serverStateLock.Unlock()
|
defer n.serverStateLock.Unlock()
|
||||||
n.currentClientState = true
|
n.currentClientState = true
|
||||||
n.lastNotification = n.calculateState(n.currentServerState, true)
|
n.lastNotification = n.calculateState(n.currentServerState, true)
|
||||||
go n.notifyAll(n.lastNotification)
|
n.notify(n.lastNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) clientStop() {
|
func (n *notifier) clientStop() {
|
||||||
@ -80,7 +79,7 @@ func (n *notifier) clientStop() {
|
|||||||
defer n.serverStateLock.Unlock()
|
defer n.serverStateLock.Unlock()
|
||||||
n.currentClientState = false
|
n.currentClientState = false
|
||||||
n.lastNotification = n.calculateState(n.currentServerState, false)
|
n.lastNotification = n.calculateState(n.currentServerState, false)
|
||||||
go n.notifyAll(n.lastNotification)
|
n.notify(n.lastNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) clientTearDown() {
|
func (n *notifier) clientTearDown() {
|
||||||
@ -88,33 +87,35 @@ func (n *notifier) clientTearDown() {
|
|||||||
defer n.serverStateLock.Unlock()
|
defer n.serverStateLock.Unlock()
|
||||||
n.currentClientState = false
|
n.currentClientState = false
|
||||||
n.lastNotification = stateDisconnecting
|
n.lastNotification = stateDisconnecting
|
||||||
go n.notifyAll(n.lastNotification)
|
n.notify(n.lastNotification)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) isServerStateChanged(newState bool) bool {
|
func (n *notifier) isServerStateChanged(newState bool) bool {
|
||||||
return n.currentServerState != newState
|
return n.currentServerState != newState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) notifyAll(state int) {
|
func (n *notifier) notify(state int) {
|
||||||
n.listenersLock.Lock()
|
n.listenersLock.Lock()
|
||||||
defer n.listenersLock.Unlock()
|
defer n.listenersLock.Unlock()
|
||||||
|
if n.listener == nil {
|
||||||
for l := range n.listeners {
|
return
|
||||||
n.notifyListener(l, state)
|
|
||||||
}
|
}
|
||||||
|
n.notifyListener(n.listener, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) notifyListener(l Listener, state int) {
|
func (n *notifier) notifyListener(l Listener, state int) {
|
||||||
switch state {
|
go func() {
|
||||||
case stateDisconnected:
|
switch state {
|
||||||
l.OnDisconnected()
|
case stateDisconnected:
|
||||||
case stateConnected:
|
l.OnDisconnected()
|
||||||
l.OnConnected()
|
case stateConnected:
|
||||||
case stateConnecting:
|
l.OnConnected()
|
||||||
l.OnConnecting()
|
case stateConnecting:
|
||||||
case stateDisconnecting:
|
l.OnConnecting()
|
||||||
l.OnDisconnecting()
|
case stateDisconnecting:
|
||||||
}
|
l.OnDisconnecting()
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) calculateState(serverState bool, clientState bool) int {
|
func (n *notifier) calculateState(serverState bool, clientState bool) int {
|
||||||
@ -132,17 +133,17 @@ func (n *notifier) calculateState(serverState bool, clientState bool) int {
|
|||||||
func (n *notifier) peerListChanged(numOfPeers int) {
|
func (n *notifier) peerListChanged(numOfPeers int) {
|
||||||
n.listenersLock.Lock()
|
n.listenersLock.Lock()
|
||||||
defer n.listenersLock.Unlock()
|
defer n.listenersLock.Unlock()
|
||||||
|
if n.listener == nil {
|
||||||
for l := range n.listeners {
|
return
|
||||||
l.OnPeersListChanged(numOfPeers)
|
|
||||||
}
|
}
|
||||||
|
n.listener.OnPeersListChanged(numOfPeers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *notifier) localAddressChanged(fqdn, address string) {
|
func (n *notifier) localAddressChanged(fqdn, address string) {
|
||||||
n.listenersLock.Lock()
|
n.listenersLock.Lock()
|
||||||
defer n.listenersLock.Unlock()
|
defer n.listenersLock.Unlock()
|
||||||
|
if n.listener == nil {
|
||||||
for l := range n.listeners {
|
return
|
||||||
l.OnAddressChanged(fqdn, address)
|
|
||||||
}
|
}
|
||||||
|
n.listener.OnAddressChanged(fqdn, address)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,48 @@
|
|||||||
package peer
|
package peer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type mocListener struct {
|
||||||
|
lastState int
|
||||||
|
wg sync.WaitGroup
|
||||||
|
peers int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *mocListener) OnConnected() {
|
||||||
|
l.lastState = stateConnected
|
||||||
|
l.wg.Done()
|
||||||
|
}
|
||||||
|
func (l *mocListener) OnDisconnected() {
|
||||||
|
l.lastState = stateDisconnected
|
||||||
|
l.wg.Done()
|
||||||
|
}
|
||||||
|
func (l *mocListener) OnConnecting() {
|
||||||
|
l.lastState = stateConnecting
|
||||||
|
l.wg.Done()
|
||||||
|
}
|
||||||
|
func (l *mocListener) OnDisconnecting() {
|
||||||
|
l.lastState = stateDisconnecting
|
||||||
|
l.wg.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *mocListener) OnAddressChanged(host, addr string) {
|
||||||
|
|
||||||
|
}
|
||||||
|
func (l *mocListener) OnPeersListChanged(size int) {
|
||||||
|
l.peers = size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *mocListener) setWaiter() {
|
||||||
|
l.wg.Add(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *mocListener) wait() {
|
||||||
|
l.wg.Wait()
|
||||||
|
}
|
||||||
|
|
||||||
func Test_notifier_serverState(t *testing.T) {
|
func Test_notifier_serverState(t *testing.T) {
|
||||||
|
|
||||||
type scenario struct {
|
type scenario struct {
|
||||||
@ -30,3 +69,30 @@ func Test_notifier_serverState(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_notifier_SetListener(t *testing.T) {
|
||||||
|
listener := &mocListener{}
|
||||||
|
listener.setWaiter()
|
||||||
|
|
||||||
|
n := newNotifier()
|
||||||
|
n.lastNotification = stateConnecting
|
||||||
|
n.setListener(listener)
|
||||||
|
listener.wait()
|
||||||
|
if listener.lastState != n.lastNotification {
|
||||||
|
t.Errorf("invalid state: %d, expected: %d", listener.lastState, n.lastNotification)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_notifier_RemoveListener(t *testing.T) {
|
||||||
|
listener := &mocListener{}
|
||||||
|
listener.setWaiter()
|
||||||
|
n := newNotifier()
|
||||||
|
n.lastNotification = stateConnecting
|
||||||
|
n.setListener(listener)
|
||||||
|
n.removeListener()
|
||||||
|
n.peerListChanged(1)
|
||||||
|
|
||||||
|
if listener.peers != 0 {
|
||||||
|
t.Errorf("invalid state: %d", listener.peers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -293,14 +293,14 @@ func (d *Status) ClientTeardown() {
|
|||||||
d.notifier.clientTearDown()
|
d.notifier.clientTearDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddConnectionListener add a listener to the notifier
|
// SetConnectionListener set a listener to the notifier
|
||||||
func (d *Status) AddConnectionListener(listener Listener) {
|
func (d *Status) SetConnectionListener(listener Listener) {
|
||||||
d.notifier.addListener(listener)
|
d.notifier.setListener(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveConnectionListener remove a listener from the notifier
|
// RemoveConnectionListener remove the listener from the notifier
|
||||||
func (d *Status) RemoveConnectionListener(listener Listener) {
|
func (d *Status) RemoveConnectionListener() {
|
||||||
d.notifier.removeListener(listener)
|
d.notifier.removeListener()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Status) onConnectionChanged() {
|
func (d *Status) onConnectionChanged() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user