Files

183 lines
4.9 KiB
Go
Raw Permalink Normal View History

2019-10-08 06:12:08 +11:00
package ipc
2019-01-08 07:58:46 +11:00
import (
"fmt"
2019-10-23 14:08:56 +11:00
"sync"
2019-10-08 06:12:08 +11:00
"github.com/wailsapp/wails/lib/interfaces"
"github.com/wailsapp/wails/lib/logger"
"github.com/wailsapp/wails/lib/messages"
2019-01-08 07:58:46 +11:00
)
2019-10-08 06:12:08 +11:00
// Manager manages the IPC subsystem
type Manager struct {
renderer interfaces.Renderer // The renderer
2019-01-08 07:58:46 +11:00
messageQueue chan *ipcMessage
2019-10-23 14:08:56 +11:00
quitChannel chan struct{}
2019-01-08 07:58:46 +11:00
// signals chan os.Signal
2019-10-08 06:12:08 +11:00
log *logger.CustomLogger
eventManager interfaces.EventManager
bindingManager interfaces.BindingManager
2019-10-23 14:08:56 +11:00
running bool
wg sync.WaitGroup
2019-01-08 07:58:46 +11:00
}
2019-10-08 06:12:08 +11:00
// NewManager creates a new IPC Manager
func NewManager() interfaces.IPCManager {
result := &Manager{
2019-01-08 07:58:46 +11:00
messageQueue: make(chan *ipcMessage, 100),
2019-10-23 14:08:56 +11:00
quitChannel: make(chan struct{}),
2019-01-08 07:58:46 +11:00
// signals: make(chan os.Signal, 1),
2019-10-08 06:12:08 +11:00
log: logger.NewCustomLogger("IPC"),
2019-01-08 07:58:46 +11:00
}
return result
}
2019-10-08 06:12:08 +11:00
// BindRenderer sets the renderer, returns the dispatch function
func (i *Manager) BindRenderer(renderer interfaces.Renderer) {
2019-01-08 07:58:46 +11:00
i.renderer = renderer
}
2019-10-08 06:12:08 +11:00
// Start the IPC Manager
func (i *Manager) Start(eventManager interfaces.EventManager, bindingManager interfaces.BindingManager) {
2019-01-08 07:58:46 +11:00
// Store manager references
i.eventManager = eventManager
i.bindingManager = bindingManager
i.log.Info("Starting")
// signal.Notify(manager.signals, os.Interrupt)
2019-10-23 14:08:56 +11:00
i.running = true
// Keep track of this goroutine
i.wg.Add(1)
2019-01-08 07:58:46 +11:00
go func() {
2019-10-23 14:08:56 +11:00
for i.running {
2019-01-08 07:58:46 +11:00
select {
case incomingMessage := <-i.messageQueue:
2019-10-08 06:12:08 +11:00
i.log.DebugFields("Processing message", logger.Fields{
2019-01-08 07:58:46 +11:00
"1D": &incomingMessage,
})
switch incomingMessage.Type {
case "call":
2019-10-08 06:12:08 +11:00
callData := incomingMessage.Payload.(*messages.CallData)
i.log.DebugFields("Processing call", logger.Fields{
2019-01-08 07:58:46 +11:00
"1D": &incomingMessage,
"bindingName": callData.BindingName,
"data": callData.Data,
})
go func() {
2019-10-08 06:12:08 +11:00
result, err := bindingManager.ProcessCall(callData)
i.log.DebugFields("processed call", logger.Fields{"result": result, "err": err})
2019-01-08 07:58:46 +11:00
if err != nil {
incomingMessage.ReturnError(err.Error())
} else {
incomingMessage.ReturnSuccess(result)
}
2019-10-08 06:12:08 +11:00
i.log.DebugFields("Finished processing call", logger.Fields{
2019-01-08 07:58:46 +11:00
"1D": &incomingMessage,
})
}()
case "event":
// Extract event data
2019-10-08 06:12:08 +11:00
eventData := incomingMessage.Payload.(*messages.EventData)
2019-01-08 07:58:46 +11:00
// Log
2019-10-08 06:12:08 +11:00
i.log.DebugFields("Processing event", logger.Fields{
2019-01-08 07:58:46 +11:00
"name": eventData.Name,
"data": eventData.Data,
})
// Push the event to the event manager
i.eventManager.PushEvent(eventData)
// Log
2019-10-08 06:12:08 +11:00
i.log.DebugFields("Finished processing event", logger.Fields{
2019-01-08 07:58:46 +11:00
"name": eventData.Name,
})
case "log":
2019-10-08 06:12:08 +11:00
logdata := incomingMessage.Payload.(*messages.LogData)
2019-01-08 07:58:46 +11:00
switch logdata.Level {
case "info":
2019-10-08 06:12:08 +11:00
logger.GlobalLogger.Info(logdata.Message)
2019-01-08 07:58:46 +11:00
case "debug":
2019-10-08 06:12:08 +11:00
logger.GlobalLogger.Debug(logdata.Message)
2019-01-08 07:58:46 +11:00
case "warning":
2019-10-08 06:12:08 +11:00
logger.GlobalLogger.Warn(logdata.Message)
2019-01-08 07:58:46 +11:00
case "error":
2019-10-08 06:12:08 +11:00
logger.GlobalLogger.Error(logdata.Message)
2019-01-08 07:58:46 +11:00
case "fatal":
2019-10-08 06:12:08 +11:00
logger.GlobalLogger.Fatal(logdata.Message)
2019-01-08 07:58:46 +11:00
default:
2019-10-08 06:12:08 +11:00
logger.ErrorFields("Invalid log level sent", logger.Fields{
2019-01-08 07:58:46 +11:00
"level": logdata.Level,
"message": logdata.Message,
})
}
default:
i.log.Debugf("bad message sent to MessageQueue! Unknown type: %s", incomingMessage.Type)
}
// Log
2019-10-08 06:12:08 +11:00
i.log.DebugFields("Finished processing message", logger.Fields{
2019-01-08 07:58:46 +11:00
"1D": &incomingMessage,
})
2020-02-08 09:58:16 +11:00
case <-i.quitChannel:
i.running = false
2019-01-08 07:58:46 +11:00
}
}
i.log.Debug("Stopping")
2019-10-23 14:08:56 +11:00
i.wg.Done()
2019-01-08 07:58:46 +11:00
}()
}
// Dispatch receives JSON encoded messages from the renderer.
// It processes the message to ensure that it is valid and places
// the processed message on the message queue
2020-02-08 09:58:16 +11:00
func (i *Manager) Dispatch(message string, cb interfaces.CallbackFunc) {
2019-01-08 07:58:46 +11:00
// Create a new IPC Message
2020-02-08 09:58:16 +11:00
incomingMessage, err := newIPCMessage(message, i.SendResponse(cb))
2019-01-08 07:58:46 +11:00
if err != nil {
i.log.ErrorFields("Could not understand incoming message! ", map[string]interface{}{
"message": message,
"error": err,
})
return
}
// Put message on queue
i.log.DebugFields("Message received", map[string]interface{}{
"type": incomingMessage.Type,
"payload": incomingMessage.Payload,
})
// Put incoming message on the message queue
i.messageQueue <- incomingMessage
}
// SendResponse sends the given response back to the frontend
2020-02-08 09:58:16 +11:00
// It sends the data back to the correct renderer by way of the provided callback function
func (i *Manager) SendResponse(cb interfaces.CallbackFunc) func(i *ipcResponse) error {
2019-01-08 07:58:46 +11:00
2020-02-08 09:58:16 +11:00
return func(response *ipcResponse) error {
// Serialise the Message
data, err := response.Serialise()
if err != nil {
fmt.Printf(err.Error())
return err
}
return cb(data)
2019-01-08 07:58:46 +11:00
}
}
2019-10-23 14:08:56 +11:00
// Shutdown is called when exiting the Application
func (i *Manager) Shutdown() {
i.log.Debug("Shutdown called")
2020-02-08 09:58:16 +11:00
i.quitChannel <- struct{}{}
2019-10-23 14:08:56 +11:00
i.log.Debug("Waiting of main loop shutdown")
i.wg.Wait()
}