diff --git a/indexedDb/channels/handlers.go b/indexedDb/channels/handlers.go index ca9a4f4873427d32d9f7c3c52844cd79a305d3d1..ddae6568e297d34710b0042704b65177f2eae5cb 100644 --- a/indexedDb/channels/handlers.go +++ b/indexedDb/channels/handlers.go @@ -71,7 +71,7 @@ func (m *manager) newWASMEventModelHandler(data []byte) ([]byte, error) { } m.model, err = NewWASMEventModel(msg.Path, encryption, - m.messageReceivedCallback, m.storeEncryptionStatus) + m.messageReceivedCallback, m.storeDatabaseName, m.storeEncryptionStatus) if err != nil { return []byte(err.Error()), nil } @@ -102,9 +102,42 @@ func (m *manager) messageReceivedCallback( worker.GetMessageTag, worker.InitID, data) } -// storeEncryptionStatus augments the functionality of -// storage.StoreIndexedDbEncryptionStatus. It takes the database name and -// encryption status +// storeDatabaseName sends the database name to the main thread and waits for +// the response. This function mocks the behavior of storage.StoreIndexedDb. +// +// storeDatabaseName adheres to the storeDatabaseNameFn type. +func (m *manager) storeDatabaseName(databaseName string) error { + // Register response handler with channel that will wait for the response + responseChan := make(chan []byte) + m.mh.RegisterHandler(worker.StoreDatabaseNameTag, + func(data []byte) ([]byte, error) { + responseChan <- data + return nil, nil + }) + + // Send encryption status to main thread + m.mh.SendResponse( + worker.StoreDatabaseNameTag, worker.InitID, []byte(databaseName)) + + // Wait for response + select { + case response := <-responseChan: + if len(response) > 0 { + return errors.New(string(response)) + } + case <-time.After(worker.ResponseTimeout): + return errors.Errorf("[WW] Timed out after %s waiting for response "+ + "about storing the database name in local storage in the main "+ + "thread", worker.ResponseTimeout) + } + + return nil +} + +// storeEncryptionStatus sends the database name and encryption status to the +// main thread and waits for the response. If the value has not been previously +// saved, it returns the saves encryption status. This function mocks the +// behavior of storage.StoreIndexedDbEncryptionStatus. // // storeEncryptionStatus adheres to the storeEncryptionStatusFn type. func (m *manager) storeEncryptionStatus( diff --git a/indexedDb/channels/implementation_test.go b/indexedDb/channels/implementation_test.go index c11c014fa94cc5cbc5f03aad88c9f32d67d2f563..3bb61bc4f0c143844e12b1a1d7c1bb0c70381711 100644 --- a/indexedDb/channels/implementation_test.go +++ b/indexedDb/channels/implementation_test.go @@ -38,7 +38,12 @@ func TestMain(m *testing.M) { func dummyCallback(uint64, *id.ID, bool) {} -// dummyStoreEncryptionStatus returns the same encryption status passed into it. +// dummyStoreDatabaseName always returns nil error and adheres to the +// storeDatabaseNameFn type. +func dummyStoreDatabaseName(string) error { return nil } + +// dummyStoreEncryptionStatus returns the same encryption status passed into it +// and adheres to the storeEncryptionStatusFn type. func dummyStoreEncryptionStatus(_ string, encryptionStatus bool) (bool, error) { return encryptionStatus, nil } @@ -61,10 +66,10 @@ func TestWasmModel_msgIDLookup(t *testing.T) { testString := "TestWasmModel_msgIDLookup" + cs testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString)) - eventModel, err := newWASMModel( - testString, c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatalf("%+v", err) + eventModel, err2 := newWASMModel(testString, c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err2) } testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, @@ -72,12 +77,12 @@ func TestWasmModel_msgIDLookup(t *testing.T) { netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) _, err = eventModel.receiveHelper(testMsg, false) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } - msg, err := eventModel.msgIDLookup(testMsgId) - if err != nil { - t.Fatalf("%+v", err) + msg, err2 := eventModel.msgIDLookup(testMsgId) + if err2 != nil { + t.Fatal(err2) } if msg.ID == 0 { t.Fatalf("Expected to get a UUID!") @@ -91,10 +96,10 @@ func TestWasmModel_DeleteMessage(t *testing.T) { storage.GetLocalStorage().Clear() testString := "TestWasmModel_DeleteMessage" testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString)) - eventModel, err := newWASMModel( - testString, nil, dummyCallback, dummyStoreEncryptionStatus) + eventModel, err := newWASMModel(testString, nil, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } // Insert a message @@ -103,13 +108,13 @@ func TestWasmModel_DeleteMessage(t *testing.T) { time.Second, 0, 0, false, false, channels.Sent) _, err = eventModel.receiveHelper(testMsg, false) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } // Check the resulting status results, err := indexedDb.Dump(eventModel.db, messageStoreName) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } if len(results) != 1 { t.Fatalf("Expected 1 message to exist") @@ -118,13 +123,13 @@ func TestWasmModel_DeleteMessage(t *testing.T) { // Delete the message err = eventModel.DeleteMessage(testMsgId) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } // Check the resulting status results, err = indexedDb.Dump(eventModel.db, messageStoreName) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } if len(results) != 0 { t.Fatalf("Expected no messages to exist") @@ -148,25 +153,25 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { testString := "Test_wasmModel_UpdateSentStatus" + cs testMsgId := message.DeriveChannelMessageID( &id.ID{1}, 0, []byte(testString)) - eventModel, err := newWASMModel( - testString, c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatalf("%+v", err) + eventModel, err2 := newWASMModel(testString, c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err) } // Store a test message testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) - uuid, err := eventModel.receiveHelper(testMsg, false) - if err != nil { - t.Fatalf("%+v", err) + uuid, err2 := eventModel.receiveHelper(testMsg, false) + if err2 != nil { + t.Fatal(err2) } // Ensure one message is stored - results, err := indexedDb.Dump(eventModel.db, messageStoreName) - if err != nil { - t.Fatalf("%+v", err) + results, err2 := indexedDb.Dump(eventModel.db, messageStoreName) + if err2 != nil { + t.Fatal(err2) } if len(results) != 1 { t.Fatalf("Expected 1 message to exist") @@ -180,7 +185,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { // Check the resulting status results, err = indexedDb.Dump(eventModel.db, messageStoreName) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } if len(results) != 1 { t.Fatalf("Expected 1 message to exist") @@ -188,7 +193,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { resultMsg := &Message{} err = json.Unmarshal([]byte(results[0]), resultMsg) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } if resultMsg.Status != uint8(expectedStatus) { t.Fatalf("Unexpected Status: %v", resultMsg.Status) @@ -216,10 +221,10 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { } t.Run("Test_wasmModel_JoinChannel_LeaveChannel"+cs, func(t *testing.T) { storage.GetLocalStorage().Clear() - eventModel, err := newWASMModel( - "test", c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatalf("%+v", err) + eventModel, err2 := newWASMModel("test", c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err2) } testChannel := &cryptoBroadcast.Channel{ @@ -236,9 +241,9 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { } eventModel.JoinChannel(testChannel) eventModel.JoinChannel(testChannel2) - results, err := indexedDb.Dump(eventModel.db, channelsStoreName) - if err != nil { - t.Fatalf("%+v", err) + results, err2 := indexedDb.Dump(eventModel.db, channelsStoreName) + if err2 != nil { + t.Fatal(err2) } if len(results) != 2 { t.Fatalf("Expected 2 channels to exist") @@ -246,7 +251,7 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { eventModel.LeaveChannel(testChannel.ReceptionID) results, err = indexedDb.Dump(eventModel.db, channelsStoreName) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } if len(results) != 1 { t.Fatalf("Expected 1 channels to exist") @@ -270,10 +275,10 @@ func Test_wasmModel_UUIDTest(t *testing.T) { t.Run("Test_wasmModel_UUIDTest"+cs, func(t *testing.T) { storage.GetLocalStorage().Clear() testString := "testHello" + cs - eventModel, err := newWASMModel( - testString, c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatalf("%+v", err) + eventModel, err2 := newWASMModel(testString, c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err2) } uuids := make([]uint64, 10) @@ -317,10 +322,10 @@ func Test_wasmModel_DuplicateReceives(t *testing.T) { t.Run("Test_wasmModel_DuplicateReceives"+cs, func(t *testing.T) { storage.GetLocalStorage().Clear() testString := "testHello" - eventModel, err := newWASMModel( - testString, c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatalf("%+v", err) + eventModel, err2 := newWASMModel(testString, c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err2) } uuids := make([]uint64, 10) @@ -367,10 +372,10 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { testString := "test_deleteMsgByChannel" totalMessages := 10 expectedMessages := 5 - eventModel, err := newWASMModel( - testString, c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatalf("%+v", err) + eventModel, err2 := newWASMModel(testString, c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err2) } // Create a test channel id @@ -396,9 +401,9 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { } // Check pre-results - result, err := indexedDb.Dump(eventModel.db, messageStoreName) - if err != nil { - t.Fatalf("%+v", err) + result, err2 := indexedDb.Dump(eventModel.db, messageStoreName) + if err2 != nil { + t.Fatal(err2) } if len(result) != totalMessages { t.Errorf("Expected %d messages, got %d", totalMessages, len(result)) @@ -413,7 +418,7 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { // Check final results result, err = indexedDb.Dump(eventModel.db, messageStoreName) if err != nil { - t.Fatalf("%+v", err) + t.Fatal(err) } if len(result) != expectedMessages { t.Errorf("Expected %d messages, got %d", expectedMessages, len(result)) @@ -438,30 +443,30 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { t.Run("TestWasmModel_receiveHelper_UniqueIndex"+cs, func(t *testing.T) { storage.GetLocalStorage().Clear() testString := fmt.Sprintf("test_receiveHelper_UniqueIndex_%d", i) - eventModel, err := newWASMModel( - testString, c, dummyCallback, dummyStoreEncryptionStatus) - if err != nil { - t.Fatal(err) + eventModel, err2 := newWASMModel(testString, c, dummyCallback, + dummyStoreDatabaseName, dummyStoreEncryptionStatus) + if err2 != nil { + t.Fatal(err2) } // Ensure index is unique - txn, err := eventModel.db.Transaction( + txn, err2 := eventModel.db.Transaction( idb.TransactionReadOnly, messageStoreName) - if err != nil { - t.Fatal(err) + if err2 != nil { + t.Fatal(err2) } - store, err := txn.ObjectStore(messageStoreName) - if err != nil { - t.Fatal(err) + store, err2 := txn.ObjectStore(messageStoreName) + if err2 != nil { + t.Fatal(err2) } - idx, err := store.Index(messageStoreMessageIndex) - if err != nil { - t.Fatal(err) + idx, err2 := store.Index(messageStoreMessageIndex) + if err2 != nil { + t.Fatal(err2) } - if isUnique, err2 := idx.Unique(); !isUnique { + if isUnique, err3 := idx.Unique(); !isUnique { t.Fatalf("Index is not unique!") - } else if err2 != nil { - t.Fatal(err2) + } else if err3 != nil { + t.Fatal(err3) } // First message insert should succeed @@ -469,15 +474,15 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) - uuid, err := eventModel.receiveHelper(testMsg, false) - if err != nil { - t.Fatal(err) + uuid, err2 := eventModel.receiveHelper(testMsg, false) + if err2 != nil { + t.Fatal(err2) } // The duplicate entry should return the same UUID - duplicateUuid, err := eventModel.receiveHelper(testMsg, false) - if err != nil { - t.Fatal(err) + duplicateUuid, err2 := eventModel.receiveHelper(testMsg, false) + if err2 != nil { + t.Fatal(err2) } if uuid != duplicateUuid { t.Fatalf("Expected UUID %d to match %d", uuid, duplicateUuid) @@ -489,9 +494,9 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { testMsg = buildMessage([]byte(testString), testMsgId2.Bytes(), nil, testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) - uuid2, err := eventModel.receiveHelper(testMsg, false) - if err != nil { - t.Fatal(err) + uuid2, err2 := eventModel.receiveHelper(testMsg, false) + if err2 != nil { + t.Fatal(err2) } if uuid2 == uuid { t.Fatalf("Expected UUID %d to NOT match %d", uuid, duplicateUuid) @@ -501,9 +506,9 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { // message ID as the first testMsg.ID = uuid testMsg.MessageID = testMsgId.Bytes() - duplicateUuid2, err := eventModel.receiveHelper(testMsg, true) - if err != nil { - t.Fatal(err) + duplicateUuid2, err2 := eventModel.receiveHelper(testMsg, true) + if err2 != nil { + t.Fatal(err2) } if duplicateUuid2 != duplicateUuid { t.Fatalf("Expected UUID %d to match %d", uuid, duplicateUuid) diff --git a/indexedDb/channels/init.go b/indexedDb/channels/init.go index b7f1ec547ae7ab865b9a744b9be5325dcd069b9d..39b0aeb8b3ddbb9d298fb9e446c6bdcb0c463030 100644 --- a/indexedDb/channels/init.go +++ b/indexedDb/channels/init.go @@ -16,10 +16,8 @@ import ( "gitlab.com/elixxir/client/v4/channels" cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/xxdk-wasm/indexedDb" - "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" "gitlab.com/xx_network/primitives/id" "syscall/js" - "time" ) const ( @@ -37,24 +35,29 @@ const ( // update is true if the row is old and was edited. type MessageReceivedCallback func(uuid uint64, channelID *id.ID, update bool) -// NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. -// The name should be a base64 encoding of the users public key. -func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, - cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) ( - channels.EventModel, error) { - databaseName := path + databaseSuffix - return newWASMModel(databaseName, encryption, cb, storeEncryptionStatus) -} +// storeDatabaseNameFn matches storage.StoreIndexedDb so that the data can be +// sent between the worker and main thread. +type storeDatabaseNameFn func(databaseName string) error // storeEncryptionStatusFn matches storage.StoreIndexedDbEncryptionStatus so // that the data can be sent between the worker and main thread. type storeEncryptionStatusFn func( databaseName string, encryptionStatus bool) (bool, error) +// NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. +// The name should be a base64 encoding of the users public key. +func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, + cb MessageReceivedCallback, storeDatabaseName storeDatabaseNameFn, + storeEncryptionStatus storeEncryptionStatusFn) (channels.EventModel, error) { + databaseName := path + databaseSuffix + return newWASMModel( + databaseName, encryption, cb, storeDatabaseName, storeEncryptionStatus) +} + // newWASMModel creates the given [idb.Database] and returns a wasmModel. func newWASMModel(databaseName string, encryption cryptoChannel.Cipher, - cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) ( - *wasmModel, error) { + cb MessageReceivedCallback, storeDatabaseName storeDatabaseNameFn, + storeEncryptionStatus storeEncryptionStatusFn) (*wasmModel, error) { // Attempt to open database object ctx, cancel := indexedDb.NewContext() defer cancel() @@ -174,43 +177,3 @@ func v1Upgrade(db *idb.Database) error { return nil } - -// storeDatabaseName sends the database name to storage.StoreIndexedDb in the -// main thread to be stored in localstorage and waits for the error to be -// returned. -// -// The function specified below is a placeholder until set by -// registerDatabaseNameStore. registerDatabaseNameStore must be called before -// storeDatabaseName. -var storeDatabaseName = func(databaseName string) error { return nil } - -// RegisterDatabaseNameStore sets storeDatabaseName to send the database to -// storage.StoreIndexedDb in the main thread when called and registers a handler -// to listen for the response. -func RegisterDatabaseNameStore(m *manager) { - storeDatabaseNameResponseChan := make(chan []byte) - // Register handler - m.mh.RegisterHandler(indexedDbWorker.StoreDatabaseNameTag, - func(data []byte) ([]byte, error) { - storeDatabaseNameResponseChan <- data - return nil, nil - }) - - storeDatabaseName = func(databaseName string) error { - m.mh.SendResponse(indexedDbWorker.StoreDatabaseNameTag, - indexedDbWorker.InitID, []byte(databaseName)) - - // Wait for response - select { - case response := <-storeDatabaseNameResponseChan: - if len(response) > 0 { - return errors.New(string(response)) - } - case <-time.After(indexedDbWorker.ResponseTimeout): - return errors.Errorf("[WW] Timed out after %s waiting for "+ - "response about storing the database name in local "+ - "storage in the main thread", indexedDbWorker.ResponseTimeout) - } - return nil - } -} diff --git a/indexedDb/channels/main.go b/indexedDb/channels/main.go index 5a950b922f0791f6b316aee42547566e12434b22..e8f6279809ca10aa0e5f62cc4560708d5effa7d9 100644 --- a/indexedDb/channels/main.go +++ b/indexedDb/channels/main.go @@ -21,7 +21,6 @@ func main() { jww.INFO.Print("[WW] Starting xxDK WebAssembly Channels Database Worker.") m := &manager{mh: indexedDb.NewMessageHandler("ChannelsIndexedDbWorker")} - RegisterDatabaseNameStore(m) m.RegisterHandlers() m.mh.SignalReady() <-make(chan bool) diff --git a/indexedDb/dm/handlers.go b/indexedDb/dm/handlers.go index a49783c67ff1af6c97cda3f0119cb0720497f0bc..ba3d33d4c1a1627f0a3ac3bfc0e2390ec0a47153 100644 --- a/indexedDb/dm/handlers.go +++ b/indexedDb/dm/handlers.go @@ -65,7 +65,7 @@ func (m *manager) newWASMEventModelHandler(data []byte) ([]byte, error) { } m.model, err = NewWASMEventModel(msg.Path, encryption, - m.messageReceivedCallback, m.storeEncryptionStatus) + m.messageReceivedCallback, m.storeDatabaseName, m.storeEncryptionStatus) if err != nil { return []byte(err.Error()), nil } @@ -96,9 +96,42 @@ func (m *manager) messageReceivedCallback( worker.GetMessageTag, worker.InitID, data) } -// storeEncryptionStatus augments the functionality of -// storage.StoreIndexedDbEncryptionStatus. It takes the database name and -// encryption status +// storeDatabaseName sends the database name to the main thread and waits for +// the response. This function mocks the behavior of storage.StoreIndexedDb. +// +// storeDatabaseName adheres to the storeDatabaseNameFn type. +func (m *manager) storeDatabaseName(databaseName string) error { + // Register response handler with channel that will wait for the response + responseChan := make(chan []byte) + m.mh.RegisterHandler(worker.StoreDatabaseNameTag, + func(data []byte) ([]byte, error) { + responseChan <- data + return nil, nil + }) + + // Send encryption status to main thread + m.mh.SendResponse( + worker.StoreDatabaseNameTag, worker.InitID, []byte(databaseName)) + + // Wait for response + select { + case response := <-responseChan: + if len(response) > 0 { + return errors.New(string(response)) + } + case <-time.After(worker.ResponseTimeout): + return errors.Errorf("[WW] Timed out after %s waiting for response "+ + "about storing the database name in local storage in the main "+ + "thread", worker.ResponseTimeout) + } + + return nil +} + +// storeEncryptionStatus sends the database name and encryption status to the +// main thread and waits for the response. If the value has not been previously +// saved, it returns the saves encryption status. This function mocks the +// behavior of storage.StoreIndexedDbEncryptionStatus. // // storeEncryptionStatus adheres to the storeEncryptionStatusFn type. func (m *manager) storeEncryptionStatus( diff --git a/indexedDb/dm/init.go b/indexedDb/dm/init.go index e3e371cfded9bd87a990d5df02cd74ecb6f14a17..aaee49ff4f63411dfec3b3187bb244b6fcd4b4f2 100644 --- a/indexedDb/dm/init.go +++ b/indexedDb/dm/init.go @@ -12,7 +12,6 @@ package main import ( "crypto/ed25519" "syscall/js" - "time" "github.com/hack-pad/go-indexeddb/idb" "github.com/pkg/errors" @@ -20,7 +19,6 @@ import ( "gitlab.com/elixxir/client/v4/dm" cryptoChannel "gitlab.com/elixxir/crypto/channel" "gitlab.com/elixxir/xxdk-wasm/indexedDb" - "gitlab.com/elixxir/xxdk-wasm/indexedDbWorker" ) const ( @@ -39,24 +37,29 @@ const ( type MessageReceivedCallback func( uuid uint64, pubKey ed25519.PublicKey, update bool) -// NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. -// The name should be a base64 encoding of the users public key. -func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, - cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) ( - dm.EventModel, error) { - databaseName := path + databaseSuffix - return newWASMModel(databaseName, encryption, cb, storeEncryptionStatus) -} +// storeDatabaseNameFn matches storage.StoreIndexedDb so that the data can be +// sent between the worker and main thread. +type storeDatabaseNameFn func(databaseName string) error // storeEncryptionStatusFn matches storage.StoreIndexedDbEncryptionStatus so // that the data can be sent between the worker and main thread. type storeEncryptionStatusFn func( databaseName string, encryptionStatus bool) (bool, error) +// NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. +// The name should be a base64 encoding of the users public key. +func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, + cb MessageReceivedCallback, storeDatabaseName storeDatabaseNameFn, + storeEncryptionStatus storeEncryptionStatusFn) (dm.EventModel, error) { + databaseName := path + databaseSuffix + return newWASMModel( + databaseName, encryption, cb, storeDatabaseName, storeEncryptionStatus) +} + // newWASMModel creates the given [idb.Database] and returns a wasmModel. func newWASMModel(databaseName string, encryption cryptoChannel.Cipher, - cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) ( - *wasmModel, error) { + cb MessageReceivedCallback, storeDatabaseName storeDatabaseNameFn, + storeEncryptionStatus storeEncryptionStatusFn) (*wasmModel, error) { // Attempt to open database object ctx, cancel := indexedDb.NewContext() defer cancel() @@ -175,44 +178,3 @@ func v1Upgrade(db *idb.Database) error { return nil } - -// storeDatabaseName sends the database name to storage.StoreIndexedDb in the -// main thread to be stored in localstorage and waits for the error to be -// returned. -// -// The function specified below is a placeholder until set by -// registerDatabaseNameStore. registerDatabaseNameStore must be called before -// storeDatabaseName. -var storeDatabaseName = func(databaseName string) error { return nil } - -// RegisterDatabaseNameStore sets storeDatabaseName to send the database to -// storage.StoreIndexedDb in the main thread when called and registers a handler -// to listen for the response. -func RegisterDatabaseNameStore(m *manager) { - storeDatabaseNameResponseChan := make(chan []byte) - // Register handler - m.mh.RegisterHandler(indexedDbWorker.StoreDatabaseNameTag, - func(data []byte) ([]byte, error) { - storeDatabaseNameResponseChan <- data - return nil, nil - }) - - storeDatabaseName = func(databaseName string) error { - m.mh.SendResponse(indexedDbWorker.StoreDatabaseNameTag, - indexedDbWorker.InitID, []byte(databaseName)) - - // Wait for response - select { - case response := <-storeDatabaseNameResponseChan: - if len(response) > 0 { - return errors.New(string(response)) - } - case <-time.After(indexedDbWorker.ResponseTimeout): - return errors.Errorf("timed out after %s waiting for "+ - "response about storing the database name in local "+ - "storage in the main thread", indexedDbWorker.ResponseTimeout) - } - - return nil - } -} diff --git a/indexedDb/dm/main.go b/indexedDb/dm/main.go index 138504f4ceea0ce678fd59ab5f4fc53b320f2c1d..6a25027554bbde08ce0b0995f9375261fc3515a6 100644 --- a/indexedDb/dm/main.go +++ b/indexedDb/dm/main.go @@ -22,7 +22,6 @@ func main() { m := &manager{mh: indexedDb.NewMessageHandler("DmIndexedDbWorker")} m.RegisterHandlers() - RegisterDatabaseNameStore(m) m.mh.SignalReady() <-make(chan bool) fmt.Println("[WW] Closing xxDK WebAssembly Channels Database Worker.") diff --git a/indexedDbWorker/channels/implementation.go b/indexedDbWorker/channels/implementation.go index 5c6032109b946c22868f58409551371332e27f87..64f91227ba1f21e3927c5dc75636b66b978afb31 100644 --- a/indexedDbWorker/channels/implementation.go +++ b/indexedDbWorker/channels/implementation.go @@ -362,7 +362,7 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, return uuid case <-time.After(indexedDbWorker.ResponseTimeout): jww.ERROR.Printf("Timed out after %s waiting for response from the "+ - "worker about ReceiveReply", indexedDbWorker.ResponseTimeout) + "worker about UpdateFromMessageID", indexedDbWorker.ResponseTimeout) } return 0 diff --git a/indexedDbWorker/worker.go b/indexedDbWorker/worker.go index 0937a6ee5cacb49c254928fbf30b2f40680a65ba..d34b09d1a11c98bdb5d9b8e5c13ded563b766181 100644 --- a/indexedDbWorker/worker.go +++ b/indexedDbWorker/worker.go @@ -32,11 +32,11 @@ const InitID = uint64(0) const ( // workerInitialConnectionTimeout is the time to wait to receive initial // contact from a new worker before timing out. - workerInitialConnectionTimeout = 2 * time.Second + workerInitialConnectionTimeout = 16 * time.Second // ResponseTimeout is the general time to wait after sending a message to // receive a response before timing out. - ResponseTimeout = 25 * time.Millisecond + ResponseTimeout = 8 * time.Second ) // HandlerFn is the function that handles incoming data from the worker.