diff --git a/indexedDb/messageHandler.go b/indexedDb/messageHandler.go index 3c74eed9611e32824c1b14743e107bcaab6e8887..735cfcbe5944e762c86f4b15dd18ca2cbb9d9354 100644 --- a/indexedDb/messageHandler.go +++ b/indexedDb/messageHandler.go @@ -124,6 +124,10 @@ func (mh *MessageHandler) RegisterHandler(tag worker.Tag, handler HandlerFn) { mh.mux.Unlock() } +//////////////////////////////////////////////////////////////////////////////// +// Javascript Call Wrappers // +//////////////////////////////////////////////////////////////////////////////// + // 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. diff --git a/indexedDbWorker/worker.go b/indexedDbWorker/worker.go index 99a948d80c1360253cb33d470fcec2c1aaca5d12..69b7d9353744ab273e8ce88851863c54bfe90be5 100644 --- a/indexedDbWorker/worker.go +++ b/indexedDbWorker/worker.go @@ -20,10 +20,10 @@ import ( ) // TODO: -// 1. Fix ID counter -// 2. Get path to JS file from bindings -// 3. restructure packages -// 4. fix tag system +// 1. fix tag system +// 2. restructure packages +// 3. Get path to JS file from bindings +// 4. Add tests for worker.go and messageHandler.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 @@ -57,8 +57,10 @@ type WorkerHandler struct { // ID. If the message is not a reply, then it appears on InitID. handlers map[Tag]map[uint64]HandlerFn - // idCount tracks the newest ID to assign to new handlers. - idCount uint64 + // 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 + // original message sent by the main thread. + handlerIDs map[Tag]uint64 // name describes the worker. It is used for debugging and logging purposes. name string @@ -81,10 +83,10 @@ func NewWorkerHandler(aURL, name string) (*WorkerHandler, error) { opts := newWorkerOptions("", "", name) wh := &WorkerHandler{ - worker: js.Global().Get("Worker").New(aURL, opts), - handlers: make(map[Tag]map[uint64]HandlerFn), - idCount: InitID, - name: name, + worker: js.Global().Get("Worker").New(aURL, opts), + handlers: make(map[Tag]map[uint64]HandlerFn), + handlerIDs: make(map[Tag]uint64), + name: name, } // Register listeners on the Javascript worker object that receive messages @@ -157,6 +159,32 @@ func (wh *WorkerHandler) receiveMessage(data []byte) error { return nil } +// 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] + if !exists { + return nil, errors.Errorf("no handlers found for tag %q", tag) + } + + handler, exists := handlers[id] + if !exists { + return nil, errors.Errorf("no %q handler found for ID %d", tag, id) + } + + if _, exists = deleteAfterReceiving[tag]; exists { + delete(wh.handlers[tag], id) + if len(wh.handlers[tag]) == 0 { + delete(wh.handlers, tag) + } + } + + return handler, nil +} + // RegisterHandler registers the handler for the given tag and ID unless autoID // 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. @@ -166,10 +194,8 @@ func (wh *WorkerHandler) RegisterHandler( wh.mux.Lock() defer wh.mux.Unlock() - // FIXME: This ID system only really works correctly when used with a - // single tag. This should probably be fixed. if autoID { - id = wh.getNextID() + id = wh.getNextID(tag) } jww.DEBUG.Printf("[WW] [%s] Main registering handler for tag %q and ID %d "+ @@ -183,13 +209,22 @@ func (wh *WorkerHandler) RegisterHandler( return id } -// getNextID returns the next unique ID. This function is not thread-safe. -func (wh *WorkerHandler) getNextID() uint64 { - id := wh.idCount - wh.idCount++ +// 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 + } + + id := wh.handlerIDs[tag] + wh.handlerIDs[tag]++ return id } +//////////////////////////////////////////////////////////////////////////////// +// Javascript Call Wrappers // +//////////////////////////////////////////////////////////////////////////////// + // 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. @@ -222,32 +257,6 @@ func (wh *WorkerHandler) addEventListeners() { wh.worker.Call("addEventListener", "messageerror", messageError) } -// 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] - if !exists { - return nil, errors.Errorf("no handlers found for tag %q", tag) - } - - handler, exists := handlers[id] - if !exists { - return nil, errors.Errorf("no %q handler found for ID %d", tag, id) - } - - if _, exists = deleteAfterReceiving[tag]; exists { - delete(wh.handlers[tag], id) - if len(wh.handlers[tag]) == 0 { - delete(wh.handlers, tag) - } - } - - return handler, nil -} - // postMessage sends a message to the worker. // // message is the object to deliver to the worker; this will be in the data diff --git a/indexedDbWorker/worker_test.go b/indexedDbWorker/worker_test.go new file mode 100644 index 0000000000000000000000000000000000000000..da36e795a4fa1fe500b2d0d79f42be9f52d857ce --- /dev/null +++ b/indexedDbWorker/worker_test.go @@ -0,0 +1,70 @@ +//////////////////////////////////////////////////////////////////////////////// +// Copyright © 2022 xx foundation // +// // +// Use of this source code is governed by a license that can be found in the // +// LICENSE file. // +//////////////////////////////////////////////////////////////////////////////// + +package indexedDbWorker + +import ( + "testing" +) + +func TestNewWorkerHandler(t *testing.T) { +} + +func TestWorkerHandler_SendMessage(t *testing.T) { +} + +func TestWorkerHandler_receiveMessage(t *testing.T) { +} + +func TestWorkerHandler_getHandler(t *testing.T) { +} + +func TestWorkerHandler_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), + handlerIDs: make(map[Tag]uint64), + } + + for _, tag := range []Tag{ + ReadyTag, NewWASMEventModelTag, EncryptionStatusTag, + StoreDatabaseNameTag, JoinChannelTag, LeaveChannelTag, + ReceiveMessageTag, ReceiveReplyTag, ReceiveReactionTag, + UpdateFromUUIDTag, UpdateFromMessageIDTag, GetMessageTag, + DeleteMessageTag, ReceiveTag, ReceiveTextTag, UpdateSentStatusTag, + } { + id := wh.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) + if id != j { + t.Errorf("Unexpected ID for tag %q."+ + "\nexpected: %d\nreceived: %d", tag, j, id) + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Javascript Call Wrappers // +//////////////////////////////////////////////////////////////////////////////// + +func TestWorkerHandler_addEventListeners(t *testing.T) { +} + +func TestWorkerHandler_postMessage(t *testing.T) { +} + +func Test_newWorkerOptions(t *testing.T) { +}