ProxyACN and ErrorACN for nicer ACN Management

This commit is contained in:
Sarah Jamie Lewis 2022-01-11 12:11:45 -08:00
parent dbc3d675ec
commit 9169018529
5 changed files with 128 additions and 0 deletions

2
acn.go
View File

@ -58,5 +58,7 @@ type ACN interface {
// GetVersion returns a string of what the ACN returns when asked for a version
GetVersion() string
Callback() func(int, string)
Close()
}

49
error_acn.go Normal file
View File

@ -0,0 +1,49 @@
package connectivity
import (
"fmt"
"net"
)
// ErrorACN - a status-callback safe errored ACN. Use this when ACN construction goes wrong
// and you need a safe substitute that can later be replaced with a working ACN without impacting calling clients.
type ErrorACN struct {
statusCallbackCache func(int, string)
}
func (e ErrorACN) Callback() func(int, string) {
return e.statusCallbackCache
}
func (e ErrorACN) GetBootstrapStatus() (int, string) {
return -1, "error initializing tor"
}
func (e ErrorACN) WaitTillBootstrapped() {
}
func (e *ErrorACN) SetStatusCallback(callback func(int, string)) {
e.statusCallbackCache = callback
}
func (e ErrorACN) Restart() {
}
func (e ErrorACN) Open(hostname string) (net.Conn, string, error) {
return nil, "", fmt.Errorf("error initializing tor")
}
func (e ErrorACN) Listen(identity PrivateKey, port int) (ListenService, error) {
return nil, fmt.Errorf("error initializing tor")
}
func (e ErrorACN) GetPID() (int, error) {
return -1, fmt.Errorf("error initializing tor")
}
func (e ErrorACN) GetVersion() string {
return "Error Initializing Tor"
}
func (e ErrorACN) Close() {
}

View File

@ -18,6 +18,10 @@ func NewLocalACN() ACN {
return &localProvider{}
}
func (lp *localProvider) Callback() func(int, string) {
return func(int, string) {}
}
func (ls *localListenService) AddressFull() string {
return ls.l.Addr().String()
}

67
proxy_acn.go Normal file
View File

@ -0,0 +1,67 @@
package connectivity
import (
"net"
)
// ProxyACN because there is rarely a problem that can't be solved by another layer of indirection.
// ACN is a core resource that many parts of a system may need access too e.g. all clients and servers need an instance
// and a UI may also need status information and a configuration interface.
// We want to allow configuration and replacement of an ACN without impacting the API of all downstream systems - introducing
// ProxyACN - a wrapper around an ACN that allows safe replacement of a running ACN that is transparent to callers.
type ProxyACN struct {
acn ACN
}
func NewProxyACN(acn ACN) ProxyACN {
return ProxyACN{
acn: acn,
}
}
// ReplaceACN closes down the current ACN and replaces it with a new ACN.
func (p *ProxyACN) ReplaceACN(acn ACN) {
p.acn.Close()
acn.SetStatusCallback(p.acn.Callback())
p.acn = acn
}
func (p *ProxyACN) GetBootstrapStatus() (int, string) {
return p.acn.GetBootstrapStatus()
}
func (p *ProxyACN) WaitTillBootstrapped() {
p.acn.WaitTillBootstrapped()
}
func (p *ProxyACN) SetStatusCallback(callback func(int, string)) {
p.acn.SetStatusCallback(callback)
}
func (p *ProxyACN) Restart() {
p.acn.Restart()
}
func (p *ProxyACN) Open(hostname string) (net.Conn, string, error) {
return p.acn.Open(hostname)
}
func (p *ProxyACN) Listen(identity PrivateKey, port int) (ListenService, error) {
return p.acn.Listen(identity, port)
}
func (p *ProxyACN) GetPID() (int, error) {
return p.acn.GetPID()
}
func (p *ProxyACN) GetVersion() string {
return p.acn.GetVersion()
}
func (p *ProxyACN) Close() {
p.acn.Close()
}
func (p *ProxyACN) Callback() func(int, string) {
return p.acn.Callback()
}

View File

@ -303,6 +303,12 @@ func (tp *torProvider) SetStatusCallback(callback func(int, string)) {
tp.statusCallback = callback
}
func (tp *torProvider) Callback() func(int, string) {
tp.lock.Lock()
defer tp.lock.Unlock()
return tp.statusCallback
}
func (tp *torProvider) callStatusCallback(prog int, status string) {
tp.lock.Lock()
if tp.statusCallback != nil {