pinecone manager config tweaks + more comments
This is a bit uglier, but in exchange we get thread safety so it'll have to do.
This commit is contained in:
parent
f8b2a0e1f7
commit
ca2976a142
|
@ -3,11 +3,58 @@ package pineconemanager
|
|||
import (
|
||||
"context"
|
||||
"crypto/ed25519"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type pineconeManagerConfOption int
|
||||
|
||||
const (
|
||||
// The private key for this pinecone peer; effectively its "identity".
|
||||
CONF_PINECONE_IDENTITY pineconeManagerConfOption = iota
|
||||
|
||||
// A logger instance which is passed on to pinecone.
|
||||
CONF_LOGGER
|
||||
|
||||
// The address to listen on for incoming pinecone connections. If this
|
||||
// is an empty string, the node does not listen for connections and
|
||||
// multicast is also disabled (so the node can only connect to peers
|
||||
// outbound and cannot receive peer connections).
|
||||
CONF_INBOUND_ADDR
|
||||
|
||||
// The address to listen on for inbound HTTP. This allows peers to connect
|
||||
// to this node over websockets and exposes a debugging endpoint if enabled
|
||||
// via `WebserverDebugPath`. Additional routes can be configured via
|
||||
// `WebserverHandlers`. The webserver is disabled if this option is an empty
|
||||
// string.
|
||||
CONF_WEBSERVER_ADDR
|
||||
|
||||
// A path on the webserver to expose debugging information at. If this is an
|
||||
// empty string, the node does not expose debugging information. This setting
|
||||
// depends on the webserver being enabled.
|
||||
CONF_WEBSERVER_DEBUG_PATH
|
||||
|
||||
// Whether to advertise this peer on the local network via multicast. This allows
|
||||
// for peers to find each other locally but may require modifications to firewall
|
||||
// rules. This option is always disabled if `InboundAddr` is not set.
|
||||
CONF_USE_MULTICAST
|
||||
|
||||
// A list of protocols to advertise as supported by this node over pinecone.
|
||||
CONF_WRAPPED_PROTOS
|
||||
|
||||
// A list of pinecone nodes with known addresses which this node can connect to
|
||||
// for a more stable connection to the network.
|
||||
CONF_STATIC_PEERS
|
||||
|
||||
// Additional handlers added to the webserver. This option exists mainly for
|
||||
// efficiency, to allow nodes which also need to run a regular webserver to
|
||||
// use the one used by pinecone for websockets. This saves allocating another
|
||||
// port and other system resources.
|
||||
CONF_WEBSERVER_HANDLERS
|
||||
)
|
||||
|
||||
type pineconeManager struct {
|
||||
// Once instances ensuring that each method is only executed once at a given time.
|
||||
startOnce sync.Once
|
||||
|
@ -19,53 +66,124 @@ type pineconeManager struct {
|
|||
ctxCancel context.CancelFunc
|
||||
ctxLock sync.RWMutex
|
||||
|
||||
// A lock for the below config options
|
||||
confLock sync.RWMutex
|
||||
|
||||
//
|
||||
// Config options
|
||||
//
|
||||
|
||||
// The private key for this pinecone peer; effectively its "identity".
|
||||
PineconeIdentity ed25519.PrivateKey
|
||||
|
||||
// A logger instance which is passed on to pinecone.
|
||||
Logger log.Logger
|
||||
|
||||
// The address to listen on for incoming pinecone connections. If this
|
||||
// is an empty string, the node does not listen for connections and
|
||||
// multicast is also disabled (so the node can only connect to peers
|
||||
// outbound and cannot receive peer connections).
|
||||
InboundAddr string
|
||||
|
||||
// The address to listen on for inbound HTTP. This allows peers to connect
|
||||
// to this node over websockets and exposes a debugging endpoint if enabled
|
||||
// via `WebserverManholePath`. Additional routes can be configured via
|
||||
// `WebserverHandlers`. The webserver is disabled if this option is an empty
|
||||
// string.
|
||||
WebserverAddr string
|
||||
|
||||
// A path on the webserver to expose debugging information at. If this is an
|
||||
// empty string, the node does not expose debugging information. This setting
|
||||
// depends on the webserver being enabled.
|
||||
WebserverManholePath string
|
||||
|
||||
// Whether to advertise this peer on the local network via multicast. This allows
|
||||
// for peers to find each other locally but may require modifications to firewall
|
||||
// rules. This option is always disabled if `InboundAddr` is not set.
|
||||
UseMulticast bool
|
||||
|
||||
// A list of protocols supported by this node over pinecone.
|
||||
WrappedProtos []string
|
||||
|
||||
// A list of pinecone nodes with known addresses which this node can connect to
|
||||
// for a more stable connection to the network.
|
||||
StaticPeers []string
|
||||
|
||||
// Additional handlers added to the webserver. This option exists mainly for
|
||||
// efficiency, to allow nodes which also need to run a regular webserver to
|
||||
// use the one used by pinecone for websockets. This saves allocating another
|
||||
// port and other system resources.
|
||||
WebserverHandlers map[string]http.Handler
|
||||
pineconeIdentity ed25519.PrivateKey
|
||||
logger log.Logger
|
||||
inboundAddr string
|
||||
webserverAddr string
|
||||
webserverDebugPath string
|
||||
useMulticast bool
|
||||
wrappedProtos []string
|
||||
staticPeers []string
|
||||
webserverHandlers map[string]http.Handler
|
||||
}
|
||||
|
||||
// Read a config option of the pinecone manager. This is thread-safe.
|
||||
func (pm *pineconeManager) ConfGet(confId pineconeManagerConfOption) (any, error) {
|
||||
defer pm.confLock.RUnlock()
|
||||
pm.confLock.RLock()
|
||||
|
||||
switch confId {
|
||||
case CONF_PINECONE_IDENTITY:
|
||||
return pm.pineconeIdentity, nil
|
||||
case CONF_LOGGER:
|
||||
return pm.logger, nil
|
||||
case CONF_INBOUND_ADDR:
|
||||
return pm.inboundAddr, nil
|
||||
case CONF_WEBSERVER_ADDR:
|
||||
return pm.inboundAddr, nil
|
||||
case CONF_WEBSERVER_DEBUG_PATH:
|
||||
return pm.webserverDebugPath, nil
|
||||
case CONF_USE_MULTICAST:
|
||||
return pm.useMulticast, nil
|
||||
case CONF_WRAPPED_PROTOS:
|
||||
return pm.wrappedProtos, nil
|
||||
case CONF_STATIC_PEERS:
|
||||
return pm.staticPeers, nil
|
||||
case CONF_WEBSERVER_HANDLERS:
|
||||
return pm.webserverHandlers, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("config option %d does not exist", confId)
|
||||
}
|
||||
}
|
||||
|
||||
// Set a config option of the pinecone manager. This is thead-safe. Note that the
|
||||
// manager will need to be restarted for changes to take effect.
|
||||
func (pm *pineconeManager) ConfSet(confId pineconeManagerConfOption, confVal any) error {
|
||||
defer pm.confLock.Unlock()
|
||||
pm.confLock.Lock()
|
||||
|
||||
invalidTypeErr := fmt.Errorf("invalid value type for config %d", confId)
|
||||
|
||||
switch confId {
|
||||
case CONF_PINECONE_IDENTITY:
|
||||
if val, ok := confVal.(ed25519.PrivateKey); ok {
|
||||
pm.pineconeIdentity = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_LOGGER:
|
||||
if val, ok := confVal.(log.Logger); ok {
|
||||
pm.logger = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_INBOUND_ADDR:
|
||||
if val, ok := confVal.(string); ok {
|
||||
pm.inboundAddr = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_WEBSERVER_ADDR:
|
||||
if val, ok := confVal.(string); ok {
|
||||
pm.webserverAddr = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_WEBSERVER_DEBUG_PATH:
|
||||
if val, ok := confVal.(string); ok {
|
||||
pm.webserverDebugPath = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_USE_MULTICAST:
|
||||
if val, ok := confVal.(bool); ok {
|
||||
pm.useMulticast = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_WRAPPED_PROTOS:
|
||||
if val, ok := confVal.([]string); ok {
|
||||
pm.wrappedProtos = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_STATIC_PEERS:
|
||||
if val, ok := confVal.([]string); ok {
|
||||
pm.staticPeers = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
case CONF_WEBSERVER_HANDLERS:
|
||||
if val, ok := confVal.(map[string]http.Handler); ok {
|
||||
pm.webserverHandlers = val
|
||||
} else {
|
||||
return invalidTypeErr
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("config option %d does not exist", confId)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start the pinecone manager as configured. This blocks while the
|
||||
// manager is running but can be started in a goroutine.
|
||||
func (pm *pineconeManager) Start() {
|
||||
// Only execute this once at a time.
|
||||
pm.startOnce.Do(func() {
|
||||
|
@ -88,6 +206,7 @@ func (pm *pineconeManager) Start() {
|
|||
})
|
||||
}
|
||||
|
||||
// Stop the pinecone manager.
|
||||
func (pm *pineconeManager) Stop() {
|
||||
// Only execute this once at a time.
|
||||
pm.stopOnce.Do(func() {
|
||||
|
@ -112,6 +231,7 @@ func (pm *pineconeManager) Stop() {
|
|||
})
|
||||
}
|
||||
|
||||
// Restart the pinecone manager. Equivalent to calling Stop() and Start().
|
||||
func (pm *pineconeManager) Restart() {
|
||||
// Only execute this once at a time.
|
||||
pm.restartOnce.Do(func() {
|
||||
|
@ -125,6 +245,7 @@ func (pm *pineconeManager) Restart() {
|
|||
})
|
||||
}
|
||||
|
||||
// Check whether the pinecone manager is currently running.
|
||||
func (pm *pineconeManager) IsRunning() bool {
|
||||
// Make sure the context isn't modified while we're checking it.
|
||||
defer pm.ctxLock.RUnlock()
|
||||
|
@ -147,6 +268,8 @@ func (pm *pineconeManager) IsRunning() bool {
|
|||
var initonce sync.Once
|
||||
var pineconeManagerInstance *pineconeManager = nil
|
||||
|
||||
// Get the instance of the pinecone manager. This instance is shared for
|
||||
// the entire program and successive calls return the existing instance.
|
||||
func GetInstance() *pineconeManager {
|
||||
// Create and initialise an instance of pineconeManager only once.
|
||||
initonce.Do(func() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user