Reduce boilerplate in worker/UI
This commit is contained in:
parent
ee73c41950
commit
d24e4712a4
4 changed files with 100 additions and 74 deletions
|
@ -12,11 +12,10 @@ import (
|
||||||
|
|
||||||
type AccountTab struct {
|
type AccountTab struct {
|
||||||
Config *config.AccountConfig
|
Config *config.AccountConfig
|
||||||
Worker worker.Worker
|
Worker *types.Worker
|
||||||
Parent *UIState
|
Parent *UIState
|
||||||
logger *log.Logger
|
logger *log.Logger
|
||||||
counter int
|
counter int
|
||||||
callbacks map[types.WorkerMessage]func(msg types.WorkerMessage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAccountTab(conf *config.AccountConfig,
|
func NewAccountTab(conf *config.AccountConfig,
|
||||||
|
@ -26,15 +25,14 @@ func NewAccountTab(conf *config.AccountConfig,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
go work.Run()
|
go work.Backend.Run()
|
||||||
acc := &AccountTab{
|
acc := &AccountTab{
|
||||||
Config: conf,
|
Config: conf,
|
||||||
Worker: work,
|
Worker: work,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
callbacks: make(map[types.WorkerMessage]func(msg types.WorkerMessage)),
|
|
||||||
}
|
}
|
||||||
acc.postAction(types.Configure{Config: conf}, nil)
|
acc.Worker.PostAction(types.Configure{Config: conf}, nil)
|
||||||
acc.postAction(types.Connect{}, func(msg types.WorkerMessage) {
|
acc.Worker.PostAction(types.Connect{}, func(msg types.WorkerMessage) {
|
||||||
if _, ok := msg.(types.Ack); ok {
|
if _, ok := msg.(types.Ack); ok {
|
||||||
acc.logger.Println("Connected.")
|
acc.logger.Println("Connected.")
|
||||||
} else {
|
} else {
|
||||||
|
@ -68,36 +66,22 @@ func (acc *AccountTab) Render(at Geometry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
|
func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
|
||||||
return acc.Worker.GetMessages()
|
return acc.Worker.Messages
|
||||||
}
|
|
||||||
|
|
||||||
func (acc *AccountTab) postAction(msg types.WorkerMessage,
|
|
||||||
cb func(msg types.WorkerMessage)) {
|
|
||||||
|
|
||||||
acc.logger.Printf("-> %T\n", msg)
|
|
||||||
acc.Worker.PostAction(msg)
|
|
||||||
if cb != nil {
|
|
||||||
acc.callbacks[msg] = cb
|
|
||||||
delete(acc.callbacks, msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
|
func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
|
||||||
acc.logger.Printf("<- %T\n", msg)
|
msg = acc.Worker.ProcessMessage(msg)
|
||||||
if cb, ok := acc.callbacks[msg.InResponseTo()]; ok {
|
|
||||||
cb(msg)
|
|
||||||
}
|
|
||||||
switch msg.(type) {
|
switch msg.(type) {
|
||||||
case types.Ack:
|
case types.Ack:
|
||||||
// no-op
|
// no-op
|
||||||
case types.ApproveCertificate:
|
case types.ApproveCertificate:
|
||||||
// TODO: Ask the user
|
// TODO: Ask the user
|
||||||
acc.logger.Println("Approving certificate")
|
acc.logger.Println("Approving certificate")
|
||||||
acc.postAction(types.Ack{
|
acc.Worker.PostAction(types.Ack{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
}, nil)
|
}, nil)
|
||||||
default:
|
default:
|
||||||
acc.postAction(types.Unsupported{
|
acc.Worker.PostAction(types.Unsupported{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -23,9 +22,6 @@ type imapClient struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type IMAPWorker struct {
|
type IMAPWorker struct {
|
||||||
messages chan types.WorkerMessage
|
|
||||||
actions chan types.WorkerMessage
|
|
||||||
|
|
||||||
config struct {
|
config struct {
|
||||||
scheme string
|
scheme string
|
||||||
insecure bool
|
insecure bool
|
||||||
|
@ -33,33 +29,18 @@ type IMAPWorker struct {
|
||||||
user *url.Userinfo
|
user *url.Userinfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
worker *types.Worker
|
||||||
client *imapClient
|
client *imapClient
|
||||||
updates chan client.Update
|
updates chan client.Update
|
||||||
logger *log.Logger
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewIMAPWorker(logger *log.Logger) *IMAPWorker {
|
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
||||||
return &IMAPWorker{
|
return &IMAPWorker{
|
||||||
messages: make(chan types.WorkerMessage, 50),
|
worker: worker,
|
||||||
actions: make(chan types.WorkerMessage, 50),
|
|
||||||
updates: make(chan client.Update, 50),
|
updates: make(chan client.Update, 50),
|
||||||
logger: logger,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *IMAPWorker) GetMessages() chan types.WorkerMessage {
|
|
||||||
return w.messages
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *IMAPWorker) PostAction(msg types.WorkerMessage) {
|
|
||||||
w.actions <- msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *IMAPWorker) postMessage(msg types.WorkerMessage) {
|
|
||||||
w.logger.Printf("=> %T\n", msg)
|
|
||||||
w.messages <- msg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
|
func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
|
||||||
rawCerts [][]byte, _ [][]*x509.Certificate) error {
|
rawCerts [][]byte, _ [][]*x509.Certificate) error {
|
||||||
|
|
||||||
|
@ -77,9 +58,9 @@ func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
CertPool: pool,
|
CertPool: pool,
|
||||||
}
|
}
|
||||||
w.postMessage(request)
|
w.worker.PostMessage(request, nil)
|
||||||
|
|
||||||
response := <-w.actions
|
response := <-w.worker.Actions
|
||||||
if response.InResponseTo() != request {
|
if response.InResponseTo() != request {
|
||||||
return fmt.Errorf("Expected UI to answer cert request")
|
return fmt.Errorf("Expected UI to answer cert request")
|
||||||
}
|
}
|
||||||
|
@ -176,24 +157,24 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
|
||||||
func (w *IMAPWorker) Run() {
|
func (w *IMAPWorker) Run() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case msg := <-w.actions:
|
case msg := <-w.worker.Actions:
|
||||||
w.logger.Printf("<= %T\n", msg)
|
msg = w.worker.ProcessAction(msg)
|
||||||
if err := w.handleMessage(msg); err == errUnsupported {
|
if err := w.handleMessage(msg); err == errUnsupported {
|
||||||
w.postMessage(types.Unsupported{
|
w.worker.PostMessage(types.Unsupported{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
})
|
}, nil)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
w.postMessage(types.Error{
|
w.worker.PostMessage(types.Error{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
Error: err,
|
Error: err,
|
||||||
})
|
}, nil)
|
||||||
} else {
|
} else {
|
||||||
w.postMessage(types.Ack{
|
w.worker.PostMessage(types.Ack{
|
||||||
Message: types.RespondTo(msg),
|
Message: types.RespondTo(msg),
|
||||||
})
|
}, nil)
|
||||||
}
|
}
|
||||||
case update := <-w.updates:
|
case update := <-w.updates:
|
||||||
w.logger.Printf("[= %T", update)
|
w.worker.Logger.Printf("(= %T", update)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
worker/types/worker.go
Normal file
59
worker/types/worker.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Backend interface {
|
||||||
|
Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
type Worker struct {
|
||||||
|
Actions chan WorkerMessage
|
||||||
|
Backend Backend
|
||||||
|
Callbacks map[WorkerMessage]func(msg WorkerMessage)
|
||||||
|
Messages chan WorkerMessage
|
||||||
|
Logger *log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worker *Worker) PostAction(msg WorkerMessage,
|
||||||
|
cb func(msg WorkerMessage)) {
|
||||||
|
|
||||||
|
worker.Logger.Printf("=> %T\n", msg)
|
||||||
|
worker.Actions <- msg
|
||||||
|
|
||||||
|
if cb != nil {
|
||||||
|
worker.Callbacks[msg] = cb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worker *Worker) PostMessage(msg WorkerMessage,
|
||||||
|
cb func(msg WorkerMessage)) {
|
||||||
|
|
||||||
|
worker.Logger.Printf("-> %T\n", msg)
|
||||||
|
worker.Messages <- msg
|
||||||
|
|
||||||
|
if cb != nil {
|
||||||
|
worker.Callbacks[msg] = cb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worker *Worker) ProcessMessage(msg WorkerMessage) WorkerMessage {
|
||||||
|
|
||||||
|
worker.Logger.Printf("<= %T\n", msg)
|
||||||
|
if cb, ok := worker.Callbacks[msg.InResponseTo()]; ok {
|
||||||
|
cb(msg)
|
||||||
|
delete(worker.Callbacks, msg)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (worker *Worker) ProcessAction(msg WorkerMessage) WorkerMessage {
|
||||||
|
|
||||||
|
worker.Logger.Printf("<- %T\n", msg)
|
||||||
|
if cb, ok := worker.Callbacks[msg.InResponseTo()]; ok {
|
||||||
|
cb(msg)
|
||||||
|
delete(worker.Callbacks, msg)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
|
@ -9,22 +9,24 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Worker interface {
|
|
||||||
GetMessages() chan types.WorkerMessage
|
|
||||||
PostAction(types.WorkerMessage)
|
|
||||||
Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Guesses the appropriate worker type based on the given source string
|
// Guesses the appropriate worker type based on the given source string
|
||||||
func NewWorker(source string, logger *log.Logger) (Worker, error) {
|
func NewWorker(source string, logger *log.Logger) (*types.Worker, error) {
|
||||||
u, err := url.Parse(source)
|
u, err := url.Parse(source)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
worker := &types.Worker{
|
||||||
|
Actions: make(chan types.WorkerMessage, 50),
|
||||||
|
Callbacks: make(map[types.WorkerMessage]func(msg types.WorkerMessage)),
|
||||||
|
Messages: make(chan types.WorkerMessage, 50),
|
||||||
|
Logger: logger,
|
||||||
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "imap":
|
case "imap":
|
||||||
case "imaps":
|
case "imaps":
|
||||||
return imap.NewIMAPWorker(logger), nil
|
worker.Backend = imap.NewIMAPWorker(worker)
|
||||||
}
|
default:
|
||||||
return nil, fmt.Errorf("Unknown backend %s", u.Scheme)
|
return nil, fmt.Errorf("Unknown backend %s", u.Scheme)
|
||||||
|
}
|
||||||
|
return worker, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue