merge app/applets; remove engine init from create/load flow; add ability to turn on/off engine
This commit is contained in:
parent
82346e399f
commit
cce35fd86e
122
app/app.go
122
app/app.go
|
@ -21,10 +21,12 @@ import (
|
||||||
type application struct {
|
type application struct {
|
||||||
eventBuses map[string]event.Manager
|
eventBuses map[string]event.Manager
|
||||||
directory string
|
directory string
|
||||||
coremutex sync.Mutex
|
|
||||||
appletPeers
|
peerLock sync.Mutex
|
||||||
appletACN
|
peers map[string]peer.CwtchPeer
|
||||||
appletPlugins
|
acn connectivity.ACN
|
||||||
|
plugins sync.Map //map[string] []plugins.Plugin
|
||||||
|
|
||||||
engines map[string]connections.Engine
|
engines map[string]connections.Engine
|
||||||
appBus event.Manager
|
appBus event.Manager
|
||||||
appmutex sync.Mutex
|
appmutex sync.Mutex
|
||||||
|
@ -37,13 +39,15 @@ type Application interface {
|
||||||
ImportProfile(exportedCwtchFile string, password string) (peer.CwtchPeer, error)
|
ImportProfile(exportedCwtchFile string, password string) (peer.CwtchPeer, error)
|
||||||
DeletePeer(onion string, currentPassword string)
|
DeletePeer(onion string, currentPassword string)
|
||||||
AddPeerPlugin(onion string, pluginID plugins.PluginID)
|
AddPeerPlugin(onion string, pluginID plugins.PluginID)
|
||||||
LaunchPeers()
|
|
||||||
|
|
||||||
GetPrimaryBus() event.Manager
|
GetPrimaryBus() event.Manager
|
||||||
GetEventBus(onion string) event.Manager
|
GetEventBus(onion string) event.Manager
|
||||||
QueryACNStatus()
|
QueryACNStatus()
|
||||||
QueryACNVersion()
|
QueryACNVersion()
|
||||||
|
|
||||||
|
ActivePeerEngine(onion string)
|
||||||
|
DeactivatePeerEngine(onion string)
|
||||||
|
|
||||||
ShutdownPeer(string)
|
ShutdownPeer(string)
|
||||||
Shutdown()
|
Shutdown()
|
||||||
|
|
||||||
|
@ -60,12 +64,57 @@ func NewApp(acn connectivity.ACN, appDirectory string) Application {
|
||||||
os.MkdirAll(path.Join(appDirectory, "profiles"), 0700)
|
os.MkdirAll(path.Join(appDirectory, "profiles"), 0700)
|
||||||
|
|
||||||
app := &application{engines: make(map[string]connections.Engine), eventBuses: make(map[string]event.Manager), directory: appDirectory, appBus: event.NewEventManager()}
|
app := &application{engines: make(map[string]connections.Engine), eventBuses: make(map[string]event.Manager), directory: appDirectory, appBus: event.NewEventManager()}
|
||||||
app.appletPeers.init()
|
app.peers = make(map[string]peer.CwtchPeer)
|
||||||
|
|
||||||
|
app.acn = acn
|
||||||
|
statusHandler := app.getACNStatusHandler()
|
||||||
|
acn.SetStatusCallback(statusHandler)
|
||||||
|
acn.SetVersionCallback(app.getACNVersionHandler())
|
||||||
|
prog, status := acn.GetBootstrapStatus()
|
||||||
|
statusHandler(prog, status)
|
||||||
|
|
||||||
app.appletACN.init(acn, app.getACNStatusHandler(), app.getACNVersionHandler())
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListProfiles returns a map of onions to their profile's Name
|
||||||
|
func (app *application) ListProfiles() []string {
|
||||||
|
var keys []string
|
||||||
|
|
||||||
|
app.peerLock.Lock()
|
||||||
|
defer app.peerLock.Unlock()
|
||||||
|
for handle := range app.peers {
|
||||||
|
keys = append(keys, handle)
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPeer returns a cwtchPeer for a given onion address
|
||||||
|
func (app *application) GetPeer(onion string) peer.CwtchPeer {
|
||||||
|
if peer, ok := app.peers[onion]; ok {
|
||||||
|
return peer
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ap *application) AddPlugin(peerid string, id plugins.PluginID, bus event.Manager, acn connectivity.ACN) {
|
||||||
|
if _, exists := ap.plugins.Load(peerid); !exists {
|
||||||
|
ap.plugins.Store(peerid, []plugins.Plugin{})
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginsinf, _ := ap.plugins.Load(peerid)
|
||||||
|
peerPlugins := pluginsinf.([]plugins.Plugin)
|
||||||
|
|
||||||
|
newp, err := plugins.Get(id, bus, acn, peerid)
|
||||||
|
if err == nil {
|
||||||
|
newp.Start()
|
||||||
|
peerPlugins = append(peerPlugins, newp)
|
||||||
|
log.Debugf("storing plugin for %v %v", peerid, peerPlugins)
|
||||||
|
ap.plugins.Store(peerid, peerPlugins)
|
||||||
|
} else {
|
||||||
|
log.Errorf("error adding plugin: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (app *application) CreateTaggedPeer(name string, password string, tag string) {
|
func (app *application) CreateTaggedPeer(name string, password string, tag string) {
|
||||||
app.appmutex.Lock()
|
app.appmutex.Lock()
|
||||||
defer app.appmutex.Unlock()
|
defer app.appmutex.Unlock()
|
||||||
|
@ -83,7 +132,6 @@ func (app *application) CreateTaggedPeer(name string, password string, tag strin
|
||||||
app.eventBuses[profile.GetOnion()] = eventBus
|
app.eventBuses[profile.GetOnion()] = eventBus
|
||||||
profile.Init(app.eventBuses[profile.GetOnion()])
|
profile.Init(app.eventBuses[profile.GetOnion()])
|
||||||
app.peers[profile.GetOnion()] = profile
|
app.peers[profile.GetOnion()] = profile
|
||||||
app.engines[profile.GetOnion()], _ = profile.GenerateProtocolEngine(app.acn, app.eventBuses[profile.GetOnion()])
|
|
||||||
|
|
||||||
if tag != "" {
|
if tag != "" {
|
||||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Tag, tag)
|
profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Tag, tag)
|
||||||
|
@ -98,22 +146,10 @@ func (app *application) DeletePeer(onion string, password string) {
|
||||||
defer app.appmutex.Unlock()
|
defer app.appmutex.Unlock()
|
||||||
|
|
||||||
if app.peers[onion].CheckPassword(password) {
|
if app.peers[onion].CheckPassword(password) {
|
||||||
app.appletPlugins.ShutdownPeer(onion)
|
app.shutdownPeer(onion)
|
||||||
app.plugins.Delete(onion)
|
app.peers[onion].Delete()
|
||||||
|
|
||||||
// Shutdown and Remove the Engine
|
// Shutdown and Remove the Engine
|
||||||
app.engines[onion].Shutdown()
|
|
||||||
delete(app.engines, onion)
|
|
||||||
|
|
||||||
app.peers[onion].Shutdown()
|
|
||||||
app.peers[onion].Delete()
|
|
||||||
delete(app.peers, onion)
|
|
||||||
app.eventBuses[onion].Publish(event.NewEventList(event.ShutdownPeer, event.Identity, onion))
|
|
||||||
|
|
||||||
app.coremutex.Lock()
|
|
||||||
defer app.coremutex.Unlock()
|
|
||||||
app.eventBuses[onion].Shutdown()
|
|
||||||
delete(app.eventBuses, onion)
|
|
||||||
|
|
||||||
log.Debugf("Delete peer for %v Done\n", onion)
|
log.Debugf("Delete peer for %v Done\n", onion)
|
||||||
app.appBus.Publish(event.NewEventList(event.PeerDeleted, event.Identity, onion))
|
app.appBus.Publish(event.NewEventList(event.PeerDeleted, event.Identity, onion))
|
||||||
|
@ -198,7 +234,6 @@ func (app *application) installProfile(profile peer.CwtchPeer) bool {
|
||||||
app.eventBuses[profile.GetOnion()] = eventBus
|
app.eventBuses[profile.GetOnion()] = eventBus
|
||||||
profile.Init(app.eventBuses[profile.GetOnion()])
|
profile.Init(app.eventBuses[profile.GetOnion()])
|
||||||
app.peers[profile.GetOnion()] = profile
|
app.peers[profile.GetOnion()] = profile
|
||||||
app.engines[profile.GetOnion()], _ = profile.GenerateProtocolEngine(app.acn, app.eventBuses[profile.GetOnion()])
|
|
||||||
app.appBus.Publish(event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.GetOnion(), event.Created: event.False}))
|
app.appBus.Publish(event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.GetOnion(), event.Created: event.False}))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -207,6 +242,22 @@ func (app *application) installProfile(profile peer.CwtchPeer) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// ActivePeerEngine creates a peer engine for use with an ACN, should be called once the underlying ACN is online
|
||||||
|
func (app *application) ActivePeerEngine(onion string) {
|
||||||
|
profile := app.GetPeer(onion)
|
||||||
|
if profile != nil {
|
||||||
|
app.engines[profile.GetOnion()], _ = profile.GenerateProtocolEngine(app.acn, app.eventBuses[profile.GetOnion()])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// DeactivatePeerEngine shutsdown and cleans up a peer engine, should be called when an underlying ACN goes offline
|
||||||
|
func (app *application) DeactivatePeerEngine(onion string) {
|
||||||
|
if engine, exists := app.engines[onion]; exists {
|
||||||
|
engine.Shutdown()
|
||||||
|
delete(app.engines, onion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GetPrimaryBus returns the bus the Application uses for events that aren't peer specific
|
// GetPrimaryBus returns the bus the Application uses for events that aren't peer specific
|
||||||
func (app *application) GetPrimaryBus() event.Manager {
|
func (app *application) GetPrimaryBus() event.Manager {
|
||||||
return app.appBus
|
return app.appBus
|
||||||
|
@ -254,22 +305,41 @@ func (app *application) QueryACNVersion() {
|
||||||
func (app *application) ShutdownPeer(onion string) {
|
func (app *application) ShutdownPeer(onion string) {
|
||||||
app.appmutex.Lock()
|
app.appmutex.Lock()
|
||||||
defer app.appmutex.Unlock()
|
defer app.appmutex.Unlock()
|
||||||
|
app.shutdownPeer(onion)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// shutdownPeer unlocked helper shutdown peer
|
||||||
|
func (app *application) shutdownPeer(onion string) {
|
||||||
app.eventBuses[onion].Shutdown()
|
app.eventBuses[onion].Shutdown()
|
||||||
delete(app.eventBuses, onion)
|
delete(app.eventBuses, onion)
|
||||||
app.peers[onion].Shutdown()
|
app.peers[onion].Shutdown()
|
||||||
delete(app.peers, onion)
|
delete(app.peers, onion)
|
||||||
app.engines[onion].Shutdown()
|
app.engines[onion].Shutdown()
|
||||||
delete(app.engines, onion)
|
delete(app.engines, onion)
|
||||||
app.appletPlugins.Shutdown()
|
log.Debugf("shutting down plugins for %v", onion)
|
||||||
|
pluginsI, ok := app.plugins.Load(onion)
|
||||||
|
if ok {
|
||||||
|
plugins := pluginsI.([]plugins.Plugin)
|
||||||
|
for _, plugin := range plugins {
|
||||||
|
log.Debugf("shutting down plugin: %v", plugin)
|
||||||
|
plugin.Shutdown()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
app.plugins.Delete(onion)
|
||||||
|
app.eventBuses[onion].Publish(event.NewEventList(event.ShutdownPeer, event.Identity, onion))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown shutsdown all peers of an app and then the tormanager
|
// Shutdown shutsdown all peers of an app
|
||||||
func (app *application) Shutdown() {
|
func (app *application) Shutdown() {
|
||||||
for id, peer := range app.peers {
|
for id, peer := range app.peers {
|
||||||
log.Debugf("Shutting Down Peer %v", id)
|
log.Debugf("Shutting Down Peer %v", id)
|
||||||
peer.Shutdown()
|
peer.Shutdown()
|
||||||
log.Debugf("Shutting Down Plugins for %v", id)
|
log.Debugf("Shutting Down Plugins for %v", id)
|
||||||
app.appletPlugins.ShutdownPeer(id)
|
app.plugins.Range(func(k, v interface{}) bool {
|
||||||
|
log.Debugf("shutting down plugins for %v", k)
|
||||||
|
app.ShutdownPeer(k.(string))
|
||||||
|
return true
|
||||||
|
})
|
||||||
log.Debugf("Shutting Down Engines for %v", id)
|
log.Debugf("Shutting Down Engines for %v", id)
|
||||||
app.engines[id].Shutdown()
|
app.engines[id].Shutdown()
|
||||||
log.Debugf("Shutting Down Bus for %v", id)
|
log.Debugf("Shutting Down Bus for %v", id)
|
||||||
|
|
126
app/applets.go
126
app/applets.go
|
@ -1,126 +0,0 @@
|
||||||
package app
|
|
||||||
|
|
||||||
import (
|
|
||||||
"cwtch.im/cwtch/event"
|
|
||||||
"git.openprivacy.ca/openprivacy/connectivity"
|
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"cwtch.im/cwtch/app/plugins"
|
|
||||||
"cwtch.im/cwtch/peer"
|
|
||||||
)
|
|
||||||
|
|
||||||
type appletPeers struct {
|
|
||||||
peerLock sync.Mutex
|
|
||||||
peers map[string]peer.CwtchPeer
|
|
||||||
launched bool // bit hacky, place holder while we transition to full multi peer support and a better api
|
|
||||||
}
|
|
||||||
|
|
||||||
type appletACN struct {
|
|
||||||
acn connectivity.ACN
|
|
||||||
}
|
|
||||||
|
|
||||||
type appletPlugins struct {
|
|
||||||
plugins sync.Map //map[string] []plugins.Plugin
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***** applet ACN
|
|
||||||
|
|
||||||
func (a *appletACN) init(acn connectivity.ACN, publishStatus func(int, string), publishVersion func(string)) {
|
|
||||||
a.acn = acn
|
|
||||||
acn.SetStatusCallback(publishStatus)
|
|
||||||
acn.SetVersionCallback(publishVersion)
|
|
||||||
prog, status := acn.GetBootstrapStatus()
|
|
||||||
publishStatus(prog, status)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *appletACN) Shutdown() {
|
|
||||||
a.acn.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***** appletPeers
|
|
||||||
|
|
||||||
func (ap *appletPeers) init() {
|
|
||||||
ap.peers = make(map[string]peer.CwtchPeer)
|
|
||||||
ap.launched = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// LaunchPeers starts each peer Listening and connecting to peers and groups
|
|
||||||
func (ap *appletPeers) LaunchPeers() {
|
|
||||||
log.Debugf("appletPeers LaunchPeers\n")
|
|
||||||
ap.peerLock.Lock()
|
|
||||||
defer ap.peerLock.Unlock()
|
|
||||||
if ap.launched {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for pid, p := range ap.peers {
|
|
||||||
log.Debugf("Launching %v\n", pid)
|
|
||||||
p.Listen()
|
|
||||||
log.Debugf("done Listen() for %v\n", pid)
|
|
||||||
p.StartPeersConnections()
|
|
||||||
log.Debugf("done StartPeersConnections() for %v\n", pid)
|
|
||||||
}
|
|
||||||
ap.launched = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListProfiles returns a map of onions to their profile's Name
|
|
||||||
func (ap *appletPeers) ListProfiles() []string {
|
|
||||||
var keys []string
|
|
||||||
|
|
||||||
ap.peerLock.Lock()
|
|
||||||
defer ap.peerLock.Unlock()
|
|
||||||
for handle := range ap.peers {
|
|
||||||
keys = append(keys, handle)
|
|
||||||
}
|
|
||||||
return keys
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetPeer returns a cwtchPeer for a given onion address
|
|
||||||
func (ap *appletPeers) GetPeer(onion string) peer.CwtchPeer {
|
|
||||||
if peer, ok := ap.peers[onion]; ok {
|
|
||||||
return peer
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ***** applet Plugins
|
|
||||||
|
|
||||||
func (ap *appletPlugins) Shutdown() {
|
|
||||||
log.Debugf("shutting down applet plugins...")
|
|
||||||
ap.plugins.Range(func(k, v interface{}) bool {
|
|
||||||
log.Debugf("shutting down plugins for %v", k)
|
|
||||||
ap.ShutdownPeer(k.(string))
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ap *appletPlugins) ShutdownPeer(peerid string) {
|
|
||||||
log.Debugf("shutting down plugins for %v", peerid)
|
|
||||||
pluginsI, ok := ap.plugins.Load(peerid)
|
|
||||||
if ok {
|
|
||||||
plugins := pluginsI.([]plugins.Plugin)
|
|
||||||
for _, plugin := range plugins {
|
|
||||||
log.Debugf("shutting down plugin: %v", plugin)
|
|
||||||
plugin.Shutdown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ap *appletPlugins) AddPlugin(peerid string, id plugins.PluginID, bus event.Manager, acn connectivity.ACN) {
|
|
||||||
if _, exists := ap.plugins.Load(peerid); !exists {
|
|
||||||
ap.plugins.Store(peerid, []plugins.Plugin{})
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginsinf, _ := ap.plugins.Load(peerid)
|
|
||||||
peerPlugins := pluginsinf.([]plugins.Plugin)
|
|
||||||
|
|
||||||
newp, err := plugins.Get(id, bus, acn, peerid)
|
|
||||||
if err == nil {
|
|
||||||
newp.Start()
|
|
||||||
peerPlugins = append(peerPlugins, newp)
|
|
||||||
log.Debugf("storing plugin for %v %v", peerid, peerPlugins)
|
|
||||||
ap.plugins.Store(peerid, peerPlugins)
|
|
||||||
} else {
|
|
||||||
log.Errorf("error adding plugin: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue