diff --git a/indexedDb/channels/handlers.go b/indexedDb/channels/handlers.go index fd7eba407ed1848088a1313f6089635a6d43f3a4..9d8a0d49b27e441b1cbdebf6ffa95738fb2e7aa3 100644 --- a/indexedDb/channels/handlers.go +++ b/indexedDb/channels/handlers.go @@ -19,9 +19,8 @@ import ( cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/crypto/fastRNG" "gitlab.com/elixxir/crypto/message" - "gitlab.com/elixxir/xxdk-wasm/indexedDb" - worker "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" mChannels "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker/channels" + "gitlab.com/elixxir/xxdk-wasm/worker" "gitlab.com/xx_network/crypto/csprng" "gitlab.com/xx_network/primitives/id" "time" @@ -32,7 +31,7 @@ var zeroUUID = []byte{0, 0, 0, 0, 0, 0, 0, 0} // manager handles the event model and the message handler, which is used to // send information between the event model and the main thread. type manager struct { - mh *indexedDb.MessageHandler + mh *worker.ThreadManager model channels.EventModel } diff --git a/indexedDb/channels/main.go b/indexedDb/channels/main.go index f89c42b7f650eb93b7b5c082fffaab26c97ac93d..1c4e23847d29bc26332bb14ede5be511ab3f69b6 100644 --- a/indexedDb/channels/main.go +++ b/indexedDb/channels/main.go @@ -12,8 +12,8 @@ package main import ( "fmt" jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/xxdk-wasm/indexedDb" "gitlab.com/elixxir/xxdk-wasm/wasm" + "gitlab.com/elixxir/xxdk-wasm/worker" "syscall/js" ) @@ -32,7 +32,7 @@ func main() { js.Global().Set("LogToFile", js.FuncOf(wasm.LogToFile)) js.Global().Set("RegisterLogWriter", js.FuncOf(wasm.RegisterLogWriter)) - m := &manager{mh: indexedDb.NewMessageHandler("ChannelsIndexedDbWorker")} + m := &manager{mh: worker.NewThreadManager("ChannelsIndexedDbWorker")} m.RegisterHandlers() m.mh.SignalReady() <-make(chan bool) diff --git a/indexedDb/dm/handlers.go b/indexedDb/dm/handlers.go index d599cc4e5377f247f4dc7ce6f3e42f88051c0562..60c6b9f3b2889eedefbbcb511b156cd2e8d7bb37 100644 --- a/indexedDb/dm/handlers.go +++ b/indexedDb/dm/handlers.go @@ -17,10 +17,9 @@ import ( "gitlab.com/elixxir/client/v4/dm" cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/crypto/fastRNG" - "gitlab.com/elixxir/xxdk-wasm/indexedDb" - worker "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" mChannels "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker/channels" mDm "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker/dm" + "gitlab.com/elixxir/xxdk-wasm/worker" "gitlab.com/xx_network/crypto/csprng" "time" ) @@ -30,7 +29,7 @@ var zeroUUID = []byte{0, 0, 0, 0, 0, 0, 0, 0} // manager handles the event model and the message handler, which is used to // send information between the event model and the main thread. type manager struct { - mh *indexedDb.MessageHandler + mh *worker.ThreadManager model dm.EventModel } diff --git a/indexedDb/dm/main.go b/indexedDb/dm/main.go index f6a507b3b46ab832a3a165bbd82136381357f004..2ce1289b9ee8e41cc65d2f51f411e5d3663bf8b4 100644 --- a/indexedDb/dm/main.go +++ b/indexedDb/dm/main.go @@ -12,8 +12,8 @@ package main import ( "fmt" jww "github.com/spf13/jwalterweatherman" - "gitlab.com/elixxir/xxdk-wasm/indexedDb" "gitlab.com/elixxir/xxdk-wasm/wasm" + "gitlab.com/elixxir/xxdk-wasm/worker" "syscall/js" ) @@ -32,7 +32,7 @@ func main() { js.Global().Set("LogToFile", js.FuncOf(wasm.LogToFile)) js.Global().Set("RegisterLogWriter", js.FuncOf(wasm.RegisterLogWriter)) - m := &manager{mh: indexedDb.NewMessageHandler("DmIndexedDbWorker")} + m := &manager{mh: worker.NewThreadManager("DmIndexedDbWorker")} m.RegisterHandlers() m.mh.SignalReady() <-make(chan bool) diff --git a/indexedDbWorker/channels/implementation.go b/indexedDbWorker/channels/implementation.go index 64f91227ba1f21e3927c5dc75636b66b978afb31..6e62eb6204c39a3c882720b0651b560a4fd59f23 100644 --- a/indexedDbWorker/channels/implementation.go +++ b/indexedDbWorker/channels/implementation.go @@ -14,8 +14,6 @@ import ( "encoding/json" "time" - "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" - "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" @@ -23,6 +21,7 @@ import ( "gitlab.com/elixxir/client/v4/cmix/rounds" cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast" "gitlab.com/elixxir/crypto/message" + "gitlab.com/elixxir/xxdk-wasm/worker" "gitlab.com/xx_network/primitives/id" ) @@ -30,7 +29,7 @@ import ( // system passed an object that adheres to in order to get events on the // channel. type wasmModel struct { - wh *indexedDbWorker.WorkerHandler + wm *worker.Manager } // JoinChannel is called whenever a channel is joined locally. @@ -41,12 +40,12 @@ func (w *wasmModel) JoinChannel(channel *cryptoBroadcast.Channel) { return } - w.wh.SendMessage(indexedDbWorker.JoinChannelTag, data, nil) + w.wm.SendMessage(worker.JoinChannelTag, data, nil) } // LeaveChannel is called whenever a channel is left locally. func (w *wasmModel) LeaveChannel(channelID *id.ID) { - w.wh.SendMessage(indexedDbWorker.LeaveChannelTag, channelID.Marshal(), nil) + w.wm.SendMessage(worker.LeaveChannelTag, channelID.Marshal(), nil) } // ReceiveMessage is called whenever a message is received on a given channel. @@ -82,7 +81,7 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveMessageTag, data, func(data []byte) { + w.wm.SendMessage(worker.ReceiveMessageTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -96,9 +95,9 @@ func (w *wasmModel) ReceiveMessage(channelID *id.ID, messageID message.ID, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveMessage", indexedDbWorker.ResponseTimeout) + "worker about ReceiveMessage", worker.ResponseTimeout) } return 0 @@ -150,7 +149,7 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveReplyTag, data, func(data []byte) { + w.wm.SendMessage(worker.ReceiveReplyTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -164,9 +163,9 @@ func (w *wasmModel) ReceiveReply(channelID *id.ID, messageID, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveReply", indexedDbWorker.ResponseTimeout) + "worker about ReceiveReply", worker.ResponseTimeout) } return 0 @@ -212,7 +211,7 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveReactionTag, data, func(data []byte) { + w.wm.SendMessage(worker.ReceiveReactionTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -226,9 +225,9 @@ func (w *wasmModel) ReceiveReaction(channelID *id.ID, messageID, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveReply", indexedDbWorker.ResponseTimeout) + "worker about ReceiveReply", worker.ResponseTimeout) } return 0 @@ -299,7 +298,7 @@ func (w *wasmModel) UpdateFromUUID(uuid uint64, messageID *message.ID, return } - w.wh.SendMessage(indexedDbWorker.UpdateFromUUIDTag, data, nil) + w.wm.SendMessage(worker.UpdateFromUUIDTag, data, nil) } // UpdateFromMessageID is called whenever a message with the message ID is @@ -345,7 +344,7 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.UpdateFromMessageIDTag, data, + w.wm.SendMessage(worker.UpdateFromMessageIDTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) @@ -360,9 +359,9 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about UpdateFromMessageID", indexedDbWorker.ResponseTimeout) + "worker about UpdateFromMessageID", worker.ResponseTimeout) } return 0 @@ -379,7 +378,7 @@ type GetMessageMessage struct { func (w *wasmModel) GetMessage( messageID message.ID) (channels.ModelMessage, error) { msgChan := make(chan GetMessageMessage) - w.wh.SendMessage(indexedDbWorker.GetMessageTag, messageID.Marshal(), + w.wm.SendMessage(worker.GetMessageTag, messageID.Marshal(), func(data []byte) { var msg GetMessageMessage err := json.Unmarshal(data, &msg) @@ -396,17 +395,17 @@ func (w *wasmModel) GetMessage( return channels.ModelMessage{}, errors.New(msg.Error) } return msg.Message, nil - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): return channels.ModelMessage{}, errors.Errorf("timed out after %s "+ "waiting for response from the worker about GetMessage", - indexedDbWorker.ResponseTimeout) + worker.ResponseTimeout) } } // DeleteMessage removes a message with the given messageID from storage. func (w *wasmModel) DeleteMessage(messageID message.ID) error { errChan := make(chan error) - w.wh.SendMessage(indexedDbWorker.DeleteMessageTag, messageID.Marshal(), + w.wm.SendMessage(worker.DeleteMessageTag, messageID.Marshal(), func(data []byte) { if data != nil { errChan <- errors.New(string(data)) @@ -418,8 +417,8 @@ func (w *wasmModel) DeleteMessage(messageID message.ID) error { select { case err := <-errChan: return err - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): return errors.Errorf("timed out after %s waiting for response from "+ - "the worker about DeleteMessage", indexedDbWorker.ResponseTimeout) + "the worker about DeleteMessage", worker.ResponseTimeout) } } diff --git a/indexedDbWorker/channels/init.go b/indexedDbWorker/channels/init.go index b73d6f7d735c6938ead37a7365276d842dd0f734..78ffc47dfe13ee0fa9022e2c9b043dbcfe0b8dee 100644 --- a/indexedDbWorker/channels/init.go +++ b/indexedDbWorker/channels/init.go @@ -12,13 +12,15 @@ package channels import ( "encoding/json" "github.com/pkg/errors" + "time" + jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/channels" + cryptoChannel "gitlab.com/elixxir/crypto/channel" - "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" "gitlab.com/elixxir/xxdk-wasm/storage" + "gitlab.com/elixxir/xxdk-wasm/worker" "gitlab.com/xx_network/primitives/id" - "time" ) // WorkerJavascriptFileURL is the URL of the script the worker will execute to @@ -54,23 +56,23 @@ func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, cb MessageReceivedCallback) (channels.EventModel, error) { // TODO: bring in URL and name from caller - wh, err := indexedDbWorker.NewWorkerHandler( + wm, err := worker.NewManager( WorkerJavascriptFileURL, "channelsIndexedDb") if err != nil { return nil, err } // Register handler to manage messages for the MessageReceivedCallback - wh.RegisterHandler(indexedDbWorker.MessageReceivedCallbackTag, - indexedDbWorker.InitID, false, messageReceivedCallbackHandler(cb)) + wm.RegisterHandler(worker.MessageReceivedCallbackTag, + worker.InitID, false, messageReceivedCallbackHandler(cb)) // Register handler to manage checking encryption status from local storage - wh.RegisterHandler(indexedDbWorker.EncryptionStatusTag, - indexedDbWorker.InitID, false, checkDbEncryptionStatusHandler(wh)) + wm.RegisterHandler(worker.EncryptionStatusTag, + worker.InitID, false, checkDbEncryptionStatusHandler(wm)) // Register handler to manage the storage of the database name - wh.RegisterHandler(indexedDbWorker.StoreDatabaseNameTag, - indexedDbWorker.InitID, false, storeDatabaseNameHandler(wh)) + wm.RegisterHandler(worker.StoreDatabaseNameTag, + worker.InitID, false, storeDatabaseNameHandler(wm)) encryptionJSON, err := json.Marshal(encryption) if err != nil { @@ -88,7 +90,7 @@ func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, } errChan := make(chan string) - wh.SendMessage(indexedDbWorker.NewWASMEventModelTag, payload, + wm.SendMessage(worker.NewWASMEventModelTag, payload, func(data []byte) { errChan <- string(data) }) select { @@ -96,12 +98,12 @@ func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, if workerErr != "" { return nil, errors.New(workerErr) } - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): return nil, errors.Errorf("timed out after %s waiting for indexedDB "+ - "database in worker to intialize", indexedDbWorker.ResponseTimeout) + "database in worker to intialize", worker.ResponseTimeout) } - return &wasmModel{wh}, nil + return &wasmModel{wm}, nil } // MessageReceivedCallbackMessage is JSON marshalled and received from the @@ -144,7 +146,7 @@ type EncryptionStatusReply struct { // checkDbEncryptionStatusHandler returns a handler to manage checking // encryption status from local storage. func checkDbEncryptionStatusHandler( - wh *indexedDbWorker.WorkerHandler) func(data []byte) { + wh *worker.Manager) func(data []byte) { return func(data []byte) { // Unmarshal received message var msg EncryptionStatusMessage @@ -173,14 +175,14 @@ func checkDbEncryptionStatusHandler( return } - wh.SendMessage(indexedDbWorker.EncryptionStatusTag, statusData, nil) + wh.SendMessage(worker.EncryptionStatusTag, statusData, nil) } } // storeDatabaseNameHandler returns a handler that stores the database name to // storage when it is received from the worker. func storeDatabaseNameHandler( - wh *indexedDbWorker.WorkerHandler) func(data []byte) { + wh *worker.Manager) func(data []byte) { return func(data []byte) { var returnData []byte @@ -189,6 +191,6 @@ func storeDatabaseNameHandler( returnData = []byte(err.Error()) } - wh.SendMessage(indexedDbWorker.StoreDatabaseNameTag, returnData, nil) + wh.SendMessage(worker.StoreDatabaseNameTag, returnData, nil) } } diff --git a/indexedDbWorker/dm/implementation.go b/indexedDbWorker/dm/implementation.go index fba5c296cbd9f69bd6da60e9c82bf80bc00e9c54..ed89a476ae03e8c4b3bac49b5667db5d0f53209d 100644 --- a/indexedDbWorker/dm/implementation.go +++ b/indexedDbWorker/dm/implementation.go @@ -12,19 +12,19 @@ package channelEventModel import ( "crypto/ed25519" "encoding/json" - "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" "time" jww "github.com/spf13/jwalterweatherman" "gitlab.com/elixxir/client/v4/cmix/rounds" "gitlab.com/elixxir/client/v4/dm" "gitlab.com/elixxir/crypto/message" + "gitlab.com/elixxir/xxdk-wasm/worker" ) // wasmModel implements dm.EventModel interface, which uses the channels system // passed an object that adheres to in order to get events on the channel. type wasmModel struct { - wh *indexedDbWorker.WorkerHandler + wh *worker.Manager } // TransferMessage is JSON marshalled and sent to the worker. @@ -67,7 +67,7 @@ func (w *wasmModel) Receive(messageID message.ID, nickname string, text []byte, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveTag, data, func(data []byte) { + w.wh.SendMessage(worker.ReceiveTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -81,9 +81,9 @@ func (w *wasmModel) Receive(messageID message.ID, nickname string, text []byte, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about Receive", indexedDbWorker.ResponseTimeout) + "worker about Receive", worker.ResponseTimeout) } return 0 @@ -112,7 +112,7 @@ func (w *wasmModel) ReceiveText(messageID message.ID, nickname, text string, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveTextTag, data, func(data []byte) { + w.wh.SendMessage(worker.ReceiveTextTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -126,9 +126,9 @@ func (w *wasmModel) ReceiveText(messageID message.ID, nickname, text string, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveText", indexedDbWorker.ResponseTimeout) + "worker about ReceiveText", worker.ResponseTimeout) } return 0 @@ -158,7 +158,7 @@ func (w *wasmModel) ReceiveReply(messageID, reactionTo message.ID, nickname, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveReplyTag, data, func(data []byte) { + w.wh.SendMessage(worker.ReceiveReplyTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -172,9 +172,9 @@ func (w *wasmModel) ReceiveReply(messageID, reactionTo message.ID, nickname, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveReply", indexedDbWorker.ResponseTimeout) + "worker about ReceiveReply", worker.ResponseTimeout) } return 0 @@ -204,7 +204,7 @@ func (w *wasmModel) ReceiveReaction(messageID, reactionTo message.ID, nickname, } uuidChan := make(chan uint64) - w.wh.SendMessage(indexedDbWorker.ReceiveReactionTag, data, func(data []byte) { + w.wh.SendMessage(worker.ReceiveReactionTag, data, func(data []byte) { var uuid uint64 err = json.Unmarshal(data, &uuid) if err != nil { @@ -218,9 +218,9 @@ func (w *wasmModel) ReceiveReaction(messageID, reactionTo message.ID, nickname, select { case uuid := <-uuidChan: return uuid - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveReaction", indexedDbWorker.ResponseTimeout) + "worker about ReceiveReaction", worker.ResponseTimeout) } return 0 @@ -242,5 +242,5 @@ func (w *wasmModel) UpdateSentStatus(uuid uint64, messageID message.ID, "Could not JSON marshal payload for TransferMessage: %+v", err) } - w.wh.SendMessage(indexedDbWorker.UpdateSentStatusTag, data, nil) + w.wh.SendMessage(worker.UpdateSentStatusTag, data, nil) } diff --git a/indexedDbWorker/dm/init.go b/indexedDbWorker/dm/init.go index 460036288812f5e425e73e7640a631e8adf67d81..378b6a0c11d46e642456cd9d0ab11846f2928780 100644 --- a/indexedDbWorker/dm/init.go +++ b/indexedDbWorker/dm/init.go @@ -12,14 +12,15 @@ package channelEventModel import ( "crypto/ed25519" "encoding/json" - "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" "time" "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" + "gitlab.com/elixxir/client/v4/dm" cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/xxdk-wasm/storage" + "gitlab.com/elixxir/xxdk-wasm/worker" ) // WorkerJavascriptFileURL is the URL of the script the worker will execute to @@ -45,23 +46,23 @@ func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, cb MessageReceivedCallback) (dm.EventModel, error) { // TODO: bring in URL and name from caller - wh, err := indexedDbWorker.NewWorkerHandler( + wh, err := worker.NewManager( WorkerJavascriptFileURL, "dmIndexedDb") if err != nil { return nil, err } // Register handler to manage messages for the MessageReceivedCallback - wh.RegisterHandler(indexedDbWorker.MessageReceivedCallbackTag, - indexedDbWorker.InitID, false, messageReceivedCallbackHandler(cb)) + wh.RegisterHandler(worker.MessageReceivedCallbackTag, worker.InitID, false, + messageReceivedCallbackHandler(cb)) // Register handler to manage checking encryption status from local storage - wh.RegisterHandler(indexedDbWorker.EncryptionStatusTag, - indexedDbWorker.InitID, false, checkDbEncryptionStatusHandler(wh)) + wh.RegisterHandler(worker.EncryptionStatusTag, worker.InitID, false, + checkDbEncryptionStatusHandler(wh)) // Register handler to manage the storage of the database name - wh.RegisterHandler(indexedDbWorker.StoreDatabaseNameTag, - indexedDbWorker.InitID, false, storeDatabaseNameHandler(wh)) + wh.RegisterHandler(worker.StoreDatabaseNameTag, worker.InitID, false, + storeDatabaseNameHandler(wh)) encryptionJSON, err := json.Marshal(encryption) if err != nil { @@ -79,7 +80,7 @@ func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, } errChan := make(chan string) - wh.SendMessage(indexedDbWorker.NewWASMEventModelTag, payload, + wh.SendMessage(worker.NewWASMEventModelTag, payload, func(data []byte) { errChan <- string(data) }) select { @@ -87,9 +88,9 @@ func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, if workerErr != "" { return nil, errors.New(workerErr) } - case <-time.After(indexedDbWorker.ResponseTimeout): + case <-time.After(worker.ResponseTimeout): return nil, errors.Errorf("timed out after %s waiting for indexedDB "+ - "database in worker to intialize", indexedDbWorker.ResponseTimeout) + "database in worker to intialize", worker.ResponseTimeout) } return &wasmModel{wh}, nil @@ -134,8 +135,7 @@ type EncryptionStatusReply struct { // checkDbEncryptionStatusHandler returns a handler to manage checking // encryption status from local storage. -func checkDbEncryptionStatusHandler( - wh *indexedDbWorker.WorkerHandler) func(data []byte) { +func checkDbEncryptionStatusHandler(wh *worker.Manager) func(data []byte) { return func(data []byte) { // Unmarshal received message var msg EncryptionStatusMessage @@ -164,14 +164,13 @@ func checkDbEncryptionStatusHandler( return } - wh.SendMessage(indexedDbWorker.EncryptionStatusTag, statusData, nil) + wh.SendMessage(worker.EncryptionStatusTag, statusData, nil) } } // storeDatabaseNameHandler returns a handler that stores the database name to // storage when it is received from the worker. -func storeDatabaseNameHandler( - wh *indexedDbWorker.WorkerHandler) func(data []byte) { +func storeDatabaseNameHandler(wh *worker.Manager) func(data []byte) { return func(data []byte) { var returnData []byte @@ -180,6 +179,6 @@ func storeDatabaseNameHandler( returnData = []byte(err.Error()) } - wh.SendMessage(indexedDbWorker.StoreDatabaseNameTag, returnData, nil) + wh.SendMessage(worker.StoreDatabaseNameTag, returnData, nil) } } diff --git a/worker/README.md b/worker/README.md new file mode 100644 index 0000000000000000000000000000000000000000..978d296ccebbabbc81a4e2f0e8f00b853e051630 --- /dev/null +++ b/worker/README.md @@ -0,0 +1,53 @@ +# Web Worker API + +This package allows you to create a [Javascript Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) +from WASM and facilitates communication between the web worker and the main +thread using a messaging system. + +## Creating a Worker + +Web workers have two sides. There is the main side that creates the worker +thread and the thread itself. The thread needs to be compiled into its own WASM +binary and must have a corresponding Javascript file to launch it. + +Example `main.go`: + +```go +package main + +import ( + "fmt" + "gitlab.com/elixxir/xxdk-wasm/utils/worker" +) + +func main() { + fmt.Println("Starting WebAssembly Worker.") + _ = worker.NewThreadManager("exampleWebWorker") + <-make(chan bool) +} +``` + + +Example WASM start file: + +```javascript +importScripts('wasm_exec.js'); + +const go = new Go(); +const binPath = 'xxdk-exampleWebWorker.wasm' +WebAssembly.instantiateStreaming(fetch(binPath), go.importObject).then((result) => { + go.run(result.instance); +}).catch((err) => { + console.error(err); +}); +``` + +To start the worker, call `worker.NewManager` with the Javascript file to launch +the worker. + +```go +wm, err := worker.NewManager("workerWasm.js", "exampleWebWorker") +if err != nil { + return nil, err +} +``` \ No newline at end of file diff --git a/indexedDbWorker/worker.go b/worker/manager.go similarity index 76% rename from indexedDbWorker/worker.go rename to worker/manager.go index ebd4e4ec14a8c6ea06455a4285838b76dda391a5..26c8a85e40d318f9d667ee2b592fdd7c02e19563 100644 --- a/indexedDbWorker/worker.go +++ b/worker/manager.go @@ -7,7 +7,7 @@ //go:build js && wasm -package indexedDbWorker +package worker import ( "encoding/json" @@ -23,7 +23,7 @@ import ( // 1. fix tag system // 2. restructure packages // 3. Get path to JS file from bindings -// 4. Add tests for worker.go and messageHandler.go +// 4. Add tests for manager.go and thread.go // InitID is the ID for the first item in the handler list. If the list only // contains one handler, then this is the ID of that handler. If the list has @@ -41,11 +41,11 @@ const ( ResponseTimeout = 8 * time.Second ) -// HandlerFn is the function that handles incoming data from the worker. -type HandlerFn func(data []byte) +// RHandlerFn is the function that handles incoming data from the worker. +type RHandlerFn func(data []byte) -// WorkerHandler manages the handling of messages received from the worker. -type WorkerHandler struct { +// Manager manages the handling of messages received from the worker. +type Manager struct { // worker is the Worker Javascript object. // Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker worker js.Value @@ -55,7 +55,7 @@ type WorkerHandler struct { // received message should be handled. If the message is a reply to a // message sent to the worker, then the handler is also keyed on a unique // ID. If the message is not a reply, then it appears on InitID. - handlers map[Tag]map[uint64]HandlerFn + handlers map[Tag]map[uint64]RHandlerFn // handlerIDs is a list of the newest ID to assign to each handler when // registered. The IDs are used to connect a reply from the worker to the @@ -68,35 +68,35 @@ type WorkerHandler struct { mux sync.Mutex } -// WorkerMessage is the outer message that contains the contents of each message -// sent to the worker. It is transmitted as JSON. -type WorkerMessage struct { +// Message is the outer message that contains the contents of each message sent +// to the worker. It is transmitted as JSON. +type Message struct { Tag Tag `json:"tag"` ID uint64 `json:"id"` Data []byte `json:"data"` } -// NewWorkerHandler generates a new WorkerHandler. This functions will only -// return once communication with the worker has been established. -func NewWorkerHandler(aURL, name string) (*WorkerHandler, error) { +// NewManager generates a new Manager. This functions will only return once +// communication with the worker has been established. +func NewManager(aURL, name string) (*Manager, error) { // Create new worker options with the given name opts := newWorkerOptions("", "", name) - wh := &WorkerHandler{ + m := &Manager{ worker: js.Global().Get("Worker").New(aURL, opts), - handlers: make(map[Tag]map[uint64]HandlerFn), + handlers: make(map[Tag]map[uint64]RHandlerFn), handlerIDs: make(map[Tag]uint64), name: name, } // Register listeners on the Javascript worker object that receive messages // and errors from the worker - wh.addEventListeners() + m.addEventListeners() // Register a handler that will receive initial message from worker // indicating that it is ready ready := make(chan struct{}) - wh.RegisterHandler( + m.RegisterHandler( ReadyTag, InitID, false, func([]byte) { ready <- struct{}{} }) // Wait for the ready signal from the worker @@ -105,26 +105,26 @@ func NewWorkerHandler(aURL, name string) (*WorkerHandler, error) { case <-time.After(workerInitialConnectionTimeout): return nil, errors.Errorf("[WW] [%s] timed out after %s waiting for "+ "initial message from worker", - wh.name, workerInitialConnectionTimeout) + m.name, workerInitialConnectionTimeout) } - return wh, nil + return m, nil } // SendMessage sends a message to the worker with the given tag. If a reception // handler is specified, then the message is given a unique ID to handle the // reply. Set receptionHandler to nil if no reply is expected. -func (wh *WorkerHandler) SendMessage( - tag Tag, data []byte, receptionHandler HandlerFn) { +func (m *Manager) SendMessage( + tag Tag, data []byte, receptionHandler RHandlerFn) { var id uint64 if receptionHandler != nil { - id = wh.RegisterHandler(tag, 0, true, receptionHandler) + id = m.RegisterHandler(tag, 0, true, receptionHandler) } jww.DEBUG.Printf("[WW] [%s] Main sending message for %q and ID %d with "+ - "data: %s", wh.name, tag, id, data) + "data: %s", m.name, tag, id, data) - msg := WorkerMessage{ + msg := Message{ Tag: tag, ID: id, Data: data, @@ -132,24 +132,24 @@ func (wh *WorkerHandler) SendMessage( payload, err := json.Marshal(msg) if err != nil { jww.FATAL.Panicf("[WW] [%s] Main failed to marshal %T for %q and "+ - "ID %d going to worker: %+v", wh.name, msg, tag, id, err) + "ID %d going to worker: %+v", m.name, msg, tag, id, err) } - go wh.postMessage(string(payload)) + go m.postMessage(string(payload)) } // receiveMessage is registered with the Javascript event listener and is called // every time a new message from the worker is received. -func (wh *WorkerHandler) receiveMessage(data []byte) error { - var msg WorkerMessage +func (m *Manager) receiveMessage(data []byte) error { + var msg Message err := json.Unmarshal(data, &msg) if err != nil { return err } jww.DEBUG.Printf("[WW] [%s] Main received message for %q and ID %d with "+ - "data: %s", wh.name, msg.Tag, msg.ID, msg.Data) + "data: %s", m.name, msg.Tag, msg.ID, msg.Data) - handler, err := wh.getHandler(msg.Tag, msg.ID) + handler, err := m.getHandler(msg.Tag, msg.ID) if err != nil { return err } @@ -162,10 +162,10 @@ func (wh *WorkerHandler) receiveMessage(data []byte) error { // getHandler returns the handler with the given ID or returns an error if no // handler is found. The handler is deleted from the map if specified in // deleteAfterReceiving. This function is thread safe. -func (wh *WorkerHandler) getHandler(tag Tag, id uint64) (HandlerFn, error) { - wh.mux.Lock() - defer wh.mux.Unlock() - handlers, exists := wh.handlers[tag] +func (m *Manager) getHandler(tag Tag, id uint64) (RHandlerFn, error) { + m.mux.Lock() + defer m.mux.Unlock() + handlers, exists := m.handlers[tag] if !exists { return nil, errors.Errorf("no handlers found for tag %q", tag) } @@ -176,9 +176,9 @@ func (wh *WorkerHandler) getHandler(tag Tag, id uint64) (HandlerFn, error) { } if _, exists = deleteAfterReceiving[tag]; exists { - delete(wh.handlers[tag], id) - if len(wh.handlers[tag]) == 0 { - delete(wh.handlers, tag) + delete(m.handlers[tag], id) + if len(m.handlers[tag]) == 0 { + delete(m.handlers, tag) } } @@ -189,35 +189,35 @@ func (wh *WorkerHandler) getHandler(tag Tag, id uint64) (HandlerFn, error) { // is true, in which case a unique ID is used. Returns the ID that was // registered. If a previous handler was registered, it is overwritten. // This function is thread safe. -func (wh *WorkerHandler) RegisterHandler( - tag Tag, id uint64, autoID bool, handler HandlerFn) uint64 { - wh.mux.Lock() - defer wh.mux.Unlock() +func (m *Manager) RegisterHandler( + tag Tag, id uint64, autoID bool, handler RHandlerFn) uint64 { + m.mux.Lock() + defer m.mux.Unlock() if autoID { - id = wh.getNextID(tag) + id = m.getNextID(tag) } jww.DEBUG.Printf("[WW] [%s] Main registering handler for tag %q and ID %d "+ - "(autoID: %t)", wh.name, tag, id, autoID) + "(autoID: %t)", m.name, tag, id, autoID) - if _, exists := wh.handlers[tag]; !exists { - wh.handlers[tag] = make(map[uint64]HandlerFn) + if _, exists := m.handlers[tag]; !exists { + m.handlers[tag] = make(map[uint64]RHandlerFn) } - wh.handlers[tag][id] = handler + m.handlers[tag][id] = handler return id } // getNextID returns the next unique ID for the given tag. This function is not // thread-safe. -func (wh *WorkerHandler) getNextID(tag Tag) uint64 { - if _, exists := wh.handlerIDs[tag]; !exists { - wh.handlerIDs[tag] = InitID +func (m *Manager) getNextID(tag Tag) uint64 { + if _, exists := m.handlerIDs[tag]; !exists { + m.handlerIDs[tag] = InitID } - id := wh.handlerIDs[tag] - wh.handlerIDs[tag]++ + id := m.handlerIDs[tag] + m.handlerIDs[tag]++ return id } @@ -228,15 +228,15 @@ func (wh *WorkerHandler) getNextID(tag Tag) uint64 { // addEventListeners adds the event listeners needed to receive a message from // the worker. Two listeners were added; one to receive messages from the worker // and the other to receive errors. -func (wh *WorkerHandler) addEventListeners() { +func (m *Manager) addEventListeners() { // Create a listener for when the message event is fired on the worker. This // occurs when a message is received from the worker. // Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/message_event messageEvent := js.FuncOf(func(_ js.Value, args []js.Value) any { - err := wh.receiveMessage([]byte(args[0].Get("data").String())) + err := m.receiveMessage([]byte(args[0].Get("data").String())) if err != nil { jww.ERROR.Printf("[WW] [%s] Failed to receive message from "+ - "worker: %+v", wh.name, err) + "worker: %+v", m.name, err) } return nil }) @@ -247,14 +247,14 @@ func (wh *WorkerHandler) addEventListeners() { messageError := js.FuncOf(func(_ js.Value, args []js.Value) any { event := args[0] jww.ERROR.Printf("[WW] [%s] Main received error message from worker: %s", - wh.name, utils.JsToJson(event)) + m.name, utils.JsToJson(event)) return nil }) // Register each event listener on the worker using addEventListener // Doc: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener - wh.worker.Call("addEventListener", "message", messageEvent) - wh.worker.Call("addEventListener", "messageerror", messageError) + m.worker.Call("addEventListener", "message", messageEvent) + m.worker.Call("addEventListener", "messageerror", messageError) } // postMessage sends a message to the worker. @@ -271,16 +271,16 @@ func (wh *WorkerHandler) addEventListeners() { // js.Undefined can be passed explicitly. // // Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage -func (wh *WorkerHandler) postMessage(msg any) { - wh.worker.Call("postMessage", msg) +func (m *Manager) postMessage(msg any) { + m.worker.Call("postMessage", msg) } // Terminate immediately terminates the Worker. This does not offer the worker // an opportunity to finish its operations; it is stopped at once. // // Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/terminate -func (wh *WorkerHandler) Terminate() { - wh.worker.Call("terminate") +func (m *Manager) Terminate() { + m.worker.Call("terminate") } // newWorkerOptions creates a new Javascript object containing optional diff --git a/indexedDbWorker/worker_test.go b/worker/manager_test.go similarity index 70% rename from indexedDbWorker/worker_test.go rename to worker/manager_test.go index 1c2e09a5918e3fa8103c7c3ef6d9bc5c6edc748c..ebee8ceb2c8c3adcfa3d18cb7ddec9a3aa2b0789 100644 --- a/indexedDbWorker/worker_test.go +++ b/worker/manager_test.go @@ -7,31 +7,31 @@ //go:build js && wasm -package indexedDbWorker +package worker import ( "testing" ) -func TestNewWorkerHandler(t *testing.T) { +func TestNewManager(t *testing.T) { } -func TestWorkerHandler_SendMessage(t *testing.T) { +func TestManager_SendMessage(t *testing.T) { } -func TestWorkerHandler_receiveMessage(t *testing.T) { +func TestManager_receiveMessage(t *testing.T) { } -func TestWorkerHandler_getHandler(t *testing.T) { +func TestManager_getHandler(t *testing.T) { } -func TestWorkerHandler_RegisterHandler(t *testing.T) { +func TestManager_RegisterHandler(t *testing.T) { } -// Tests that WorkerHandler.getNextID returns the expected ID for various Tags. -func TestWorkerHandler_getNextID(t *testing.T) { - wh := &WorkerHandler{ - handlers: make(map[Tag]map[uint64]HandlerFn), +// Tests that Manager.getNextID returns the expected ID for various Tags. +func TestManager_getNextID(t *testing.T) { + m := &Manager{ + handlers: make(map[Tag]map[uint64]RHandlerFn), handlerIDs: make(map[Tag]uint64), } @@ -42,14 +42,14 @@ func TestWorkerHandler_getNextID(t *testing.T) { UpdateFromUUIDTag, UpdateFromMessageIDTag, GetMessageTag, DeleteMessageTag, ReceiveTag, ReceiveTextTag, UpdateSentStatusTag, } { - id := wh.getNextID(tag) + id := m.getNextID(tag) if id != InitID { t.Errorf("ID for new tag %q is not InitID."+ "\nexpected: %d\nreceived: %d", tag, InitID, id) } for j := uint64(1); j < 100; j++ { - id = wh.getNextID(tag) + id = m.getNextID(tag) if id != j { t.Errorf("Unexpected ID for tag %q."+ "\nexpected: %d\nreceived: %d", tag, j, id) @@ -62,10 +62,10 @@ func TestWorkerHandler_getNextID(t *testing.T) { // Javascript Call Wrappers // //////////////////////////////////////////////////////////////////////////////// -func TestWorkerHandler_addEventListeners(t *testing.T) { +func TestManager_addEventListeners(t *testing.T) { } -func TestWorkerHandler_postMessage(t *testing.T) { +func TestManager_postMessage(t *testing.T) { } func Test_newWorkerOptions(t *testing.T) { diff --git a/indexedDbWorker/tag.go b/worker/tag.go similarity index 96% rename from indexedDbWorker/tag.go rename to worker/tag.go index dcda42cca518c44c64990577733d962489cc7730..9375d20c33f022b1f8291b0dbc3fe5409370cb50 100644 --- a/indexedDbWorker/tag.go +++ b/worker/tag.go @@ -7,13 +7,13 @@ //go:build js && wasm -package indexedDbWorker +package worker // Tag describes how a message sent to or from the worker should be handled. type Tag string // FIXME: This system of tagging does not work so well when using the -// WorkerHandler for more than one database. This should bed fixed. +// Manager for more than one database. This should bed fixed. // List of tags that can be used when sending a message or registering a handler // to receive a message. diff --git a/indexedDb/messageHandler.go b/worker/thread.go similarity index 75% rename from indexedDb/messageHandler.go rename to worker/thread.go index 735cfcbe5944e762c86f4b15dd18ca2cbb9d9354..3ed8ba33ea35741cb60eee2507734b9fd9301433 100644 --- a/indexedDb/messageHandler.go +++ b/worker/thread.go @@ -7,13 +7,12 @@ //go:build js && wasm -package indexedDb +package worker import ( "encoding/json" "github.com/pkg/errors" jww "github.com/spf13/jwalterweatherman" - worker "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" "gitlab.com/elixxir/xxdk-wasm/utils" "sync" "syscall/js" @@ -22,15 +21,15 @@ import ( // HandlerFn is the function that handles incoming data from the main thread. type HandlerFn func(data []byte) ([]byte, error) -// MessageHandler queues incoming messages from the main thread and handles them +// ThreadManager queues incoming messages from the main thread and handles them // based on their tag. -type MessageHandler struct { +type ThreadManager struct { // messages is a list of queued messages sent from the main thread. messages chan js.Value // handlers is a list of functions to handle messages that come from the // main thread keyed on the handler tag. - handlers map[worker.Tag]HandlerFn + handlers map[Tag]HandlerFn // name describes the worker. It is used for debugging and logging purposes. name string @@ -38,11 +37,11 @@ type MessageHandler struct { mux sync.Mutex } -// NewMessageHandler initialises a new MessageHandler. -func NewMessageHandler(name string) *MessageHandler { - mh := &MessageHandler{ +// NewThreadManager initialises a new ThreadManager. +func NewThreadManager(name string) *ThreadManager { + mh := &ThreadManager{ messages: make(chan js.Value, 100), - handlers: make(map[worker.Tag]HandlerFn), + handlers: make(map[Tag]HandlerFn), name: name, } @@ -54,45 +53,45 @@ func NewMessageHandler(name string) *MessageHandler { // SignalReady sends a signal to the main thread indicating that the worker is // ready. Once the main thread receives this, it will initiate communication. // Therefore, this should only be run once all listeners are ready. -func (mh *MessageHandler) SignalReady() { - mh.SendResponse(worker.ReadyTag, worker.InitID, nil) +func (tm *ThreadManager) SignalReady() { + tm.SendResponse(ReadyTag, InitID, nil) } // SendResponse sends a reply to the main thread with the given tag and ID, -func (mh *MessageHandler) SendResponse( - tag worker.Tag, id uint64, data []byte) { - msg := worker.WorkerMessage{ +func (tm *ThreadManager) SendResponse( + tag Tag, id uint64, data []byte) { + msg := Message{ Tag: tag, ID: id, Data: data, } jww.DEBUG.Printf("[WW] [%s] Worker sending message for %q and ID %d with "+ - "data: %s", mh.name, tag, id, data) + "data: %s", tm.name, tag, id, data) payload, err := json.Marshal(msg) if err != nil { jww.FATAL.Panicf("[WW] [%s] Worker failed to marshal %T for %q and ID "+ - "%d going to main: %+v", mh.name, msg, tag, id, err) + "%d going to main: %+v", tm.name, msg, tag, id, err) } - go mh.postMessage(string(payload)) + go tm.postMessage(string(payload)) } // receiveMessage is registered with the Javascript event listener and is called // everytime a message from the main thread is received. If the registered // handler returns a response, it is sent to the main thread. -func (mh *MessageHandler) receiveMessage(data []byte) error { - var msg worker.WorkerMessage +func (tm *ThreadManager) receiveMessage(data []byte) error { + var msg Message err := json.Unmarshal(data, &msg) if err != nil { return err } jww.DEBUG.Printf("[WW] [%s] Worker received message for %q and ID %d with "+ - "data: %s", mh.name, msg.Tag, msg.ID, msg.Data) + "data: %s", tm.name, msg.Tag, msg.ID, msg.Data) - mh.mux.Lock() - handler, exists := mh.handlers[msg.Tag] - mh.mux.Unlock() + tm.mux.Lock() + handler, exists := tm.handlers[msg.Tag] + tm.mux.Unlock() if !exists { return errors.Errorf("no handler found for tag %q", msg.Tag) } @@ -102,10 +101,10 @@ func (mh *MessageHandler) receiveMessage(data []byte) error { response, err2 := handler(msg.Data) if err2 != nil { jww.ERROR.Printf("[WW] [%s] Handler for for %q and ID %d returned "+ - "an error: %+v", mh.name, msg.Tag, msg.ID, err) + "an error: %+v", tm.name, msg.Tag, msg.ID, err) } if response != nil { - mh.SendResponse(msg.Tag, msg.ID, response) + tm.SendResponse(msg.Tag, msg.ID, response) } }() @@ -116,12 +115,12 @@ func (mh *MessageHandler) receiveMessage(data []byte) error { // previous registered handler with the same tag. This function is thread safe. // // If the handler returns anything but nil, it will be returned as a response. -func (mh *MessageHandler) RegisterHandler(tag worker.Tag, handler HandlerFn) { +func (tm *ThreadManager) RegisterHandler(tag Tag, handler HandlerFn) { jww.DEBUG.Printf( - "[WW] [%s] Worker registering handler for tag %q", mh.name, tag) - mh.mux.Lock() - mh.handlers[tag] = handler - mh.mux.Unlock() + "[WW] [%s] Worker registering handler for tag %q", tm.name, tag) + tm.mux.Lock() + tm.handlers[tag] = handler + tm.mux.Unlock() } //////////////////////////////////////////////////////////////////////////////// @@ -131,15 +130,15 @@ func (mh *MessageHandler) RegisterHandler(tag worker.Tag, handler HandlerFn) { // addEventListeners adds the event listeners needed to receive a message from // the worker. Two listeners were added; one to receive messages from the worker // and the other to receive errors. -func (mh *MessageHandler) addEventListeners() { +func (tm *ThreadManager) addEventListeners() { // Create a listener for when the message event is fire on the worker. This // occurs when a message is received from the main thread. // Doc: https://developer.mozilla.org/en-US/docs/Web/API/Worker/message_event messageEvent := js.FuncOf(func(_ js.Value, args []js.Value) any { - err := mh.receiveMessage([]byte(args[0].Get("data").String())) + err := tm.receiveMessage([]byte(args[0].Get("data").String())) if err != nil { jww.ERROR.Printf("[WW] [%s] Failed to receive message from "+ - "main thread: %+v", mh.name, err) + "main thread: %+v", tm.name, err) } return nil }) @@ -150,7 +149,7 @@ func (mh *MessageHandler) addEventListeners() { messageError := js.FuncOf(func(_ js.Value, args []js.Value) any { event := args[0] jww.ERROR.Printf("[WW] [%s] Worker received error message from main "+ - "thread: %s", mh.name, utils.JsToJson(event)) + "thread: %s", tm.name, utils.JsToJson(event)) return nil }) @@ -167,6 +166,6 @@ func (mh *MessageHandler) addEventListeners() { // handled by the structured clone algorithm". See the doc for more information. // // Doc: https://developer.mozilla.org/docs/Web/API/DedicatedWorkerGlobalScope/postMessage -func (mh *MessageHandler) postMessage(aMessage any) { +func (tm *ThreadManager) postMessage(aMessage any) { js.Global().Call("postMessage", aMessage) }