func New(ctx context.Context, config Config) (*Gun, error) {
	g := &Gun{
		currentPeers:         make([]*Peer, len(config.PeerURLs)),
		storage:              config.Storage,
		soulGen:              config.SoulGen,
		peerErrorHandler:     config.PeerErrorHandler,
		peerSleepOnError:     config.PeerSleepOnError,
		myPeerID:             config.MyPeerID,
		tracking:             config.Tracking,
		messageIDListeners:   map[string]chan<- *messageReceived{},
		messageSoulListeners: map[string]chan<- *messageReceived{},
	}
	// Set config defaults
	if g.storage == nil {
		g.storage = NewStorageInMem(DefaultOldestAllowedStorageValue)
	}
	if g.soulGen == nil {
		g.soulGen = DefaultSoulGen
	}
	if g.peerSleepOnError == 0 {
		g.peerSleepOnError = DefaultPeerSleepOnError
	}
	if g.myPeerID == "" {
		g.myPeerID = randString(9)
	}
	// Create all the peers
	var err error
	for i := 0; i < len(config.PeerURLs) && err == nil; i++ {
		peerURL := config.PeerURLs[i]
		newConn := func() (PeerConn, error) { return NewPeerConn(ctx, peerURL) }
		if g.currentPeers[i], err = newPeer(peerURL, newConn, g.peerSleepOnError); err != nil {
			err = fmt.Errorf("Failed connecting to peer %v: %v", peerURL, err)
		}
	}
	// If there was an error, we need to close what we did create
	if err != nil {
		for _, peer := range g.currentPeers {
			if peer != nil {
				peer.Close()
			}
		}
		return nil, err
	}
	// Start receiving from peers
	for _, peer := range g.currentPeers {
		go g.startReceiving(ctx, peer)
	}
	// Start all the servers
	go g.startServers(ctx, config.Servers)
	return g, nil
}
// New creates a new Gun instance for the given config. The given context is
// used for all peer connection reconnects now/later, all server servings, and
// peer message handling. Therefore it should be kept available at least until
// Close. Callers must still call Close on complete, the completion of the
// context does not automatically do it.
//
// This returns nil with an error on any initial peer connection failure (and
// cleans up any other peers temporarily connected to).
New creates a new Gun instance for the given config. The given context is
used for all peer connection reconnects now/later, all server servings, and
peer message handling. Therefore it should be kept available at least until
Close. Callers must still call Close on complete, the completion of the
context does not automatically do it.

This returns nil with an error on any initial peer connection failure (and
cleans up any other peers temporarily connected to).
// New creates a new Gun instance for the given config . The given context is // used for all peer connection reconnects now / later all server servings and // peer message handling . Therefore it should be kept available at least until // Close . Callers must still call Close on complete the completion of the // context does not automatically do it . // // This returns nil with an error on any initial peer connection failure ( and // cleans up any other peers temporarily connected to ) .
func New(ctx context.Context, config Config) (*Gun, error) {
	g := &Gun{
		currentPeers:         make([]*Peer, len(config.PeerURLs)),
		storage:              config.Storage,
		soulGen:              config.SoulGen,
		peerErrorHandler:     config.PeerErrorHandler,
		peerSleepOnError:     config.PeerSleepOnError,
		myPeerID:             config.MyPeerID,
		tracking:             config.Tracking,
		messageIDListeners:   map[string]chan<- *messageReceived{},
		messageSoulListeners: map[string]chan<- *messageReceived{},
	}
	if g.storage == nil {
		g.storage = NewStorageInMem(DefaultOldestAllowedStorageValue)
	}
	if g.soulGen == nil {
		g.soulGen = DefaultSoulGen
	}
	if g.peerSleepOnError == 0 {
		g.peerSleepOnError = DefaultPeerSleepOnError
	}
	if g.myPeerID == "" {
		g.myPeerID = randString(9)
	}
	var err error
	for i := 0; i < len(config.PeerURLs) && err == nil; i++ {
		peerURL := config.PeerURLs[i]
		newConn := func() (PeerConn, error) { return NewPeerConn(ctx, peerURL) }
		if g.currentPeers[i], err = newPeer(peerURL, newConn, g.peerSleepOnError); err != nil {
			err = fmt.Errorf("Failed connecting to peer %v: %v", peerURL, err)
		}
	}
	if err != nil {
		for _, peer := range g.currentPeers {
			if peer != nil {
				peer.Close()
			}
		}
		return nil, err
	}
	for _, peer := range g.currentPeers {
		go g.startReceiving(ctx, peer)
	}
	go g.startServers(ctx, config.Servers)
	return g, nil
}
func New ( ctx context . Context , config Config ) ( * Gun , error ) { g := & Gun { currentPeers : make ( [ ] * Peer , len ( config . PeerURLs ) ) , storage : config . Storage , soulGen : config . SoulGen , peerErrorHandler : config . PeerErrorHandler , peerSleepOnError : config . PeerSleepOnError , myPeerID : config . MyPeerID , tracking : config . Tracking , messageIDListeners : map [ string ] chan <- * messageReceived { } , messageSoulListeners : map [ string ] chan <- * messageReceived { } , } if g . storage == nil { g . storage = NewStorageInMem ( DefaultOldestAllowedStorageValue ) } if g . soulGen == nil { g . soulGen = DefaultSoulGen } if g . peerSleepOnError == 0 { g . peerSleepOnError = DefaultPeerSleepOnError } if g . myPeerID == " " { g . myPeerID = randString ( 9 ) } var err error for i := 0 ; i < len ( config . PeerURLs ) && err == nil ; i ++ { peerURL := config . PeerURLs [ i ] newConn := func ( ) ( PeerConn , error ) { return NewPeerConn ( ctx , peerURL ) } if g . currentPeers [ i ] , err = newPeer ( peerURL , newConn , g . peerSleepOnError ) ; err != nil { err = fmt . Errorf ( " " , peerURL , err ) } } if err != nil { for _ , peer := range g . currentPeers { if peer != nil { peer . Close ( ) } } return nil , err } for _ , peer := range g . currentPeers { go g . startReceiving ( ctx , peer ) } go g . startServers ( ctx , config . Servers ) return g , nil }
New creates a new Gun instance for the given config.
New creates a new Gun instance for the given config .
// Set config defaults // Create all the peers // If there was an error, we need to close what we did create // Start receiving from peers // Start all the servers