 5978a0b8f5
			
		
	
	5978a0b8f5
	
	
	
		
			
			- Agent roles and coordination features - Chat API integration testing - New configuration and workspace management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			97 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package relaysvc
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"sync"
 | |
| 
 | |
| 	"github.com/libp2p/go-libp2p/core/event"
 | |
| 	"github.com/libp2p/go-libp2p/core/host"
 | |
| 	"github.com/libp2p/go-libp2p/core/network"
 | |
| 	"github.com/libp2p/go-libp2p/p2p/host/eventbus"
 | |
| 	relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay"
 | |
| )
 | |
| 
 | |
| type RelayManager struct {
 | |
| 	host host.Host
 | |
| 
 | |
| 	mutex sync.Mutex
 | |
| 	relay *relayv2.Relay
 | |
| 	opts  []relayv2.Option
 | |
| 
 | |
| 	refCount  sync.WaitGroup
 | |
| 	ctxCancel context.CancelFunc
 | |
| }
 | |
| 
 | |
| func NewRelayManager(host host.Host, opts ...relayv2.Option) *RelayManager {
 | |
| 	ctx, cancel := context.WithCancel(context.Background())
 | |
| 	m := &RelayManager{
 | |
| 		host:      host,
 | |
| 		opts:      opts,
 | |
| 		ctxCancel: cancel,
 | |
| 	}
 | |
| 	m.refCount.Add(1)
 | |
| 	go m.background(ctx)
 | |
| 	return m
 | |
| }
 | |
| 
 | |
| func (m *RelayManager) background(ctx context.Context) {
 | |
| 	defer m.refCount.Done()
 | |
| 	defer func() {
 | |
| 		m.mutex.Lock()
 | |
| 		if m.relay != nil {
 | |
| 			m.relay.Close()
 | |
| 		}
 | |
| 		m.mutex.Unlock()
 | |
| 	}()
 | |
| 
 | |
| 	subReachability, _ := m.host.EventBus().Subscribe(new(event.EvtLocalReachabilityChanged), eventbus.Name("relaysvc"))
 | |
| 	defer subReachability.Close()
 | |
| 
 | |
| 	for {
 | |
| 		select {
 | |
| 		case <-ctx.Done():
 | |
| 			return
 | |
| 		case ev, ok := <-subReachability.Out():
 | |
| 			if !ok {
 | |
| 				return
 | |
| 			}
 | |
| 			if err := m.reachabilityChanged(ev.(event.EvtLocalReachabilityChanged).Reachability); err != nil {
 | |
| 				return
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (m *RelayManager) reachabilityChanged(r network.Reachability) error {
 | |
| 	switch r {
 | |
| 	case network.ReachabilityPublic:
 | |
| 		m.mutex.Lock()
 | |
| 		defer m.mutex.Unlock()
 | |
| 		// This could happen if two consecutive EvtLocalReachabilityChanged report the same reachability.
 | |
| 		// This shouldn't happen, but it's safer to double-check.
 | |
| 		if m.relay != nil {
 | |
| 			return nil
 | |
| 		}
 | |
| 		relay, err := relayv2.New(m.host, m.opts...)
 | |
| 		if err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 		m.relay = relay
 | |
| 	default:
 | |
| 		m.mutex.Lock()
 | |
| 		defer m.mutex.Unlock()
 | |
| 		if m.relay != nil {
 | |
| 			err := m.relay.Close()
 | |
| 			m.relay = nil
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (m *RelayManager) Close() error {
 | |
| 	m.ctxCancel()
 | |
| 	m.refCount.Wait()
 | |
| 	return nil
 | |
| }
 |