Skip to content
Snippets Groups Projects
Commit e4ddb584 authored by Jono Wenger's avatar Jono Wenger
Browse files

Move database name storage to function that is passed into NewWASMEventModel

parent b2defd2a
No related branches found
No related tags found
2 merge requests!67fix for latest client release,!52XX-4382 / Move indexedDb databases to web workers
...@@ -71,7 +71,7 @@ func (m *manager) newWASMEventModelHandler(data []byte) ([]byte, error) { ...@@ -71,7 +71,7 @@ func (m *manager) newWASMEventModelHandler(data []byte) ([]byte, error) {
} }
m.model, err = NewWASMEventModel(msg.Path, encryption, m.model, err = NewWASMEventModel(msg.Path, encryption,
m.messageReceivedCallback, m.storeEncryptionStatus) m.messageReceivedCallback, m.storeDatabaseName, m.storeEncryptionStatus)
if err != nil { if err != nil {
return []byte(err.Error()), nil return []byte(err.Error()), nil
} }
...@@ -102,9 +102,42 @@ func (m *manager) messageReceivedCallback( ...@@ -102,9 +102,42 @@ func (m *manager) messageReceivedCallback(
worker.GetMessageTag, worker.InitID, data) worker.GetMessageTag, worker.InitID, data)
} }
// storeEncryptionStatus augments the functionality of // storeDatabaseName sends the database name to the main thread and waits for
// storage.StoreIndexedDbEncryptionStatus. It takes the database name and // the response. This function mocks the behavior of storage.StoreIndexedDb.
// encryption status //
// 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. // storeEncryptionStatus adheres to the storeEncryptionStatusFn type.
func (m *manager) storeEncryptionStatus( func (m *manager) storeEncryptionStatus(
......
...@@ -38,7 +38,12 @@ func TestMain(m *testing.M) { ...@@ -38,7 +38,12 @@ func TestMain(m *testing.M) {
func dummyCallback(uint64, *id.ID, bool) {} 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) { func dummyStoreEncryptionStatus(_ string, encryptionStatus bool) (bool, error) {
return encryptionStatus, nil return encryptionStatus, nil
} }
...@@ -61,10 +66,10 @@ func TestWasmModel_msgIDLookup(t *testing.T) { ...@@ -61,10 +66,10 @@ func TestWasmModel_msgIDLookup(t *testing.T) {
testString := "TestWasmModel_msgIDLookup" + cs testString := "TestWasmModel_msgIDLookup" + cs
testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString)) testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString))
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel(testString, c, dummyCallback,
testString, c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
...@@ -72,12 +77,12 @@ func TestWasmModel_msgIDLookup(t *testing.T) { ...@@ -72,12 +77,12 @@ func TestWasmModel_msgIDLookup(t *testing.T) {
netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) netTime.Now(), time.Second, 0, 0, false, false, channels.Sent)
_, err = eventModel.receiveHelper(testMsg, false) _, err = eventModel.receiveHelper(testMsg, false)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
msg, err := eventModel.msgIDLookup(testMsgId) msg, err2 := eventModel.msgIDLookup(testMsgId)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
if msg.ID == 0 { if msg.ID == 0 {
t.Fatalf("Expected to get a UUID!") t.Fatalf("Expected to get a UUID!")
...@@ -91,10 +96,10 @@ func TestWasmModel_DeleteMessage(t *testing.T) { ...@@ -91,10 +96,10 @@ func TestWasmModel_DeleteMessage(t *testing.T) {
storage.GetLocalStorage().Clear() storage.GetLocalStorage().Clear()
testString := "TestWasmModel_DeleteMessage" testString := "TestWasmModel_DeleteMessage"
testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString)) testMsgId := message.DeriveChannelMessageID(&id.ID{1}, 0, []byte(testString))
eventModel, err := newWASMModel( eventModel, err := newWASMModel(testString, nil, dummyCallback,
testString, nil, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
// Insert a message // Insert a message
...@@ -103,13 +108,13 @@ func TestWasmModel_DeleteMessage(t *testing.T) { ...@@ -103,13 +108,13 @@ func TestWasmModel_DeleteMessage(t *testing.T) {
time.Second, 0, 0, false, false, channels.Sent) time.Second, 0, 0, false, false, channels.Sent)
_, err = eventModel.receiveHelper(testMsg, false) _, err = eventModel.receiveHelper(testMsg, false)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
// Check the resulting status // Check the resulting status
results, err := indexedDb.Dump(eventModel.db, messageStoreName) results, err := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if len(results) != 1 { if len(results) != 1 {
t.Fatalf("Expected 1 message to exist") t.Fatalf("Expected 1 message to exist")
...@@ -118,13 +123,13 @@ func TestWasmModel_DeleteMessage(t *testing.T) { ...@@ -118,13 +123,13 @@ func TestWasmModel_DeleteMessage(t *testing.T) {
// Delete the message // Delete the message
err = eventModel.DeleteMessage(testMsgId) err = eventModel.DeleteMessage(testMsgId)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
// Check the resulting status // Check the resulting status
results, err = indexedDb.Dump(eventModel.db, messageStoreName) results, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if len(results) != 0 { if len(results) != 0 {
t.Fatalf("Expected no messages to exist") t.Fatalf("Expected no messages to exist")
...@@ -148,25 +153,25 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { ...@@ -148,25 +153,25 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) {
testString := "Test_wasmModel_UpdateSentStatus" + cs testString := "Test_wasmModel_UpdateSentStatus" + cs
testMsgId := message.DeriveChannelMessageID( testMsgId := message.DeriveChannelMessageID(
&id.ID{1}, 0, []byte(testString)) &id.ID{1}, 0, []byte(testString))
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel(testString, c, dummyCallback,
testString, c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
// Store a test message // Store a test message
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, netTime.Now(), testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, netTime.Now(),
time.Second, 0, 0, false, false, channels.Sent) time.Second, 0, 0, false, false, channels.Sent)
uuid, err := eventModel.receiveHelper(testMsg, false) uuid, err2 := eventModel.receiveHelper(testMsg, false)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
// Ensure one message is stored // Ensure one message is stored
results, err := indexedDb.Dump(eventModel.db, messageStoreName) results, err2 := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
if len(results) != 1 { if len(results) != 1 {
t.Fatalf("Expected 1 message to exist") t.Fatalf("Expected 1 message to exist")
...@@ -180,7 +185,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { ...@@ -180,7 +185,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) {
// Check the resulting status // Check the resulting status
results, err = indexedDb.Dump(eventModel.db, messageStoreName) results, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if len(results) != 1 { if len(results) != 1 {
t.Fatalf("Expected 1 message to exist") t.Fatalf("Expected 1 message to exist")
...@@ -188,7 +193,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) { ...@@ -188,7 +193,7 @@ func Test_wasmModel_UpdateSentStatus(t *testing.T) {
resultMsg := &Message{} resultMsg := &Message{}
err = json.Unmarshal([]byte(results[0]), resultMsg) err = json.Unmarshal([]byte(results[0]), resultMsg)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if resultMsg.Status != uint8(expectedStatus) { if resultMsg.Status != uint8(expectedStatus) {
t.Fatalf("Unexpected Status: %v", resultMsg.Status) t.Fatalf("Unexpected Status: %v", resultMsg.Status)
...@@ -216,10 +221,10 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { ...@@ -216,10 +221,10 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
} }
t.Run("Test_wasmModel_JoinChannel_LeaveChannel"+cs, func(t *testing.T) { t.Run("Test_wasmModel_JoinChannel_LeaveChannel"+cs, func(t *testing.T) {
storage.GetLocalStorage().Clear() storage.GetLocalStorage().Clear()
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel("test", c, dummyCallback,
"test", c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
testChannel := &cryptoBroadcast.Channel{ testChannel := &cryptoBroadcast.Channel{
...@@ -236,9 +241,9 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { ...@@ -236,9 +241,9 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
} }
eventModel.JoinChannel(testChannel) eventModel.JoinChannel(testChannel)
eventModel.JoinChannel(testChannel2) eventModel.JoinChannel(testChannel2)
results, err := indexedDb.Dump(eventModel.db, channelsStoreName) results, err2 := indexedDb.Dump(eventModel.db, channelsStoreName)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
if len(results) != 2 { if len(results) != 2 {
t.Fatalf("Expected 2 channels to exist") t.Fatalf("Expected 2 channels to exist")
...@@ -246,7 +251,7 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) { ...@@ -246,7 +251,7 @@ func Test_wasmModel_JoinChannel_LeaveChannel(t *testing.T) {
eventModel.LeaveChannel(testChannel.ReceptionID) eventModel.LeaveChannel(testChannel.ReceptionID)
results, err = indexedDb.Dump(eventModel.db, channelsStoreName) results, err = indexedDb.Dump(eventModel.db, channelsStoreName)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if len(results) != 1 { if len(results) != 1 {
t.Fatalf("Expected 1 channels to exist") t.Fatalf("Expected 1 channels to exist")
...@@ -270,10 +275,10 @@ func Test_wasmModel_UUIDTest(t *testing.T) { ...@@ -270,10 +275,10 @@ func Test_wasmModel_UUIDTest(t *testing.T) {
t.Run("Test_wasmModel_UUIDTest"+cs, func(t *testing.T) { t.Run("Test_wasmModel_UUIDTest"+cs, func(t *testing.T) {
storage.GetLocalStorage().Clear() storage.GetLocalStorage().Clear()
testString := "testHello" + cs testString := "testHello" + cs
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel(testString, c, dummyCallback,
testString, c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
uuids := make([]uint64, 10) uuids := make([]uint64, 10)
...@@ -317,10 +322,10 @@ func Test_wasmModel_DuplicateReceives(t *testing.T) { ...@@ -317,10 +322,10 @@ func Test_wasmModel_DuplicateReceives(t *testing.T) {
t.Run("Test_wasmModel_DuplicateReceives"+cs, func(t *testing.T) { t.Run("Test_wasmModel_DuplicateReceives"+cs, func(t *testing.T) {
storage.GetLocalStorage().Clear() storage.GetLocalStorage().Clear()
testString := "testHello" testString := "testHello"
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel(testString, c, dummyCallback,
testString, c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
uuids := make([]uint64, 10) uuids := make([]uint64, 10)
...@@ -367,10 +372,10 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { ...@@ -367,10 +372,10 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
testString := "test_deleteMsgByChannel" testString := "test_deleteMsgByChannel"
totalMessages := 10 totalMessages := 10
expectedMessages := 5 expectedMessages := 5
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel(testString, c, dummyCallback,
testString, c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
// Create a test channel id // Create a test channel id
...@@ -396,9 +401,9 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { ...@@ -396,9 +401,9 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
} }
// Check pre-results // Check pre-results
result, err := indexedDb.Dump(eventModel.db, messageStoreName) result, err2 := indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil { if err2 != nil {
t.Fatalf("%+v", err) t.Fatal(err2)
} }
if len(result) != totalMessages { if len(result) != totalMessages {
t.Errorf("Expected %d messages, got %d", totalMessages, len(result)) t.Errorf("Expected %d messages, got %d", totalMessages, len(result))
...@@ -413,7 +418,7 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) { ...@@ -413,7 +418,7 @@ func Test_wasmModel_deleteMsgByChannel(t *testing.T) {
// Check final results // Check final results
result, err = indexedDb.Dump(eventModel.db, messageStoreName) result, err = indexedDb.Dump(eventModel.db, messageStoreName)
if err != nil { if err != nil {
t.Fatalf("%+v", err) t.Fatal(err)
} }
if len(result) != expectedMessages { if len(result) != expectedMessages {
t.Errorf("Expected %d messages, got %d", expectedMessages, len(result)) t.Errorf("Expected %d messages, got %d", expectedMessages, len(result))
...@@ -438,30 +443,30 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { ...@@ -438,30 +443,30 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) {
t.Run("TestWasmModel_receiveHelper_UniqueIndex"+cs, func(t *testing.T) { t.Run("TestWasmModel_receiveHelper_UniqueIndex"+cs, func(t *testing.T) {
storage.GetLocalStorage().Clear() storage.GetLocalStorage().Clear()
testString := fmt.Sprintf("test_receiveHelper_UniqueIndex_%d", i) testString := fmt.Sprintf("test_receiveHelper_UniqueIndex_%d", i)
eventModel, err := newWASMModel( eventModel, err2 := newWASMModel(testString, c, dummyCallback,
testString, c, dummyCallback, dummyStoreEncryptionStatus) dummyStoreDatabaseName, dummyStoreEncryptionStatus)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
// Ensure index is unique // Ensure index is unique
txn, err := eventModel.db.Transaction( txn, err2 := eventModel.db.Transaction(
idb.TransactionReadOnly, messageStoreName) idb.TransactionReadOnly, messageStoreName)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
store, err := txn.ObjectStore(messageStoreName) store, err2 := txn.ObjectStore(messageStoreName)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
idx, err := store.Index(messageStoreMessageIndex) idx, err2 := store.Index(messageStoreMessageIndex)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
if isUnique, err2 := idx.Unique(); !isUnique { if isUnique, err3 := idx.Unique(); !isUnique {
t.Fatalf("Index is not unique!") t.Fatalf("Index is not unique!")
} else if err2 != nil { } else if err3 != nil {
t.Fatal(err2) t.Fatal(err3)
} }
// First message insert should succeed // First message insert should succeed
...@@ -469,15 +474,15 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { ...@@ -469,15 +474,15 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) {
testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil, testMsg := buildMessage([]byte(testString), testMsgId.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0,
netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) netTime.Now(), time.Second, 0, 0, false, false, channels.Sent)
uuid, err := eventModel.receiveHelper(testMsg, false) uuid, err2 := eventModel.receiveHelper(testMsg, false)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
// The duplicate entry should return the same UUID // The duplicate entry should return the same UUID
duplicateUuid, err := eventModel.receiveHelper(testMsg, false) duplicateUuid, err2 := eventModel.receiveHelper(testMsg, false)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
if uuid != duplicateUuid { if uuid != duplicateUuid {
t.Fatalf("Expected UUID %d to match %d", uuid, duplicateUuid) t.Fatalf("Expected UUID %d to match %d", uuid, duplicateUuid)
...@@ -489,9 +494,9 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { ...@@ -489,9 +494,9 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) {
testMsg = buildMessage([]byte(testString), testMsgId2.Bytes(), nil, testMsg = buildMessage([]byte(testString), testMsgId2.Bytes(), nil,
testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0, testString, []byte(testString), []byte{8, 6, 7, 5}, 0, 0,
netTime.Now(), time.Second, 0, 0, false, false, channels.Sent) netTime.Now(), time.Second, 0, 0, false, false, channels.Sent)
uuid2, err := eventModel.receiveHelper(testMsg, false) uuid2, err2 := eventModel.receiveHelper(testMsg, false)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
if uuid2 == uuid { if uuid2 == uuid {
t.Fatalf("Expected UUID %d to NOT match %d", uuid, duplicateUuid) t.Fatalf("Expected UUID %d to NOT match %d", uuid, duplicateUuid)
...@@ -501,9 +506,9 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) { ...@@ -501,9 +506,9 @@ func TestWasmModel_receiveHelper_UniqueIndex(t *testing.T) {
// message ID as the first // message ID as the first
testMsg.ID = uuid testMsg.ID = uuid
testMsg.MessageID = testMsgId.Bytes() testMsg.MessageID = testMsgId.Bytes()
duplicateUuid2, err := eventModel.receiveHelper(testMsg, true) duplicateUuid2, err2 := eventModel.receiveHelper(testMsg, true)
if err != nil { if err2 != nil {
t.Fatal(err) t.Fatal(err2)
} }
if duplicateUuid2 != duplicateUuid { if duplicateUuid2 != duplicateUuid {
t.Fatalf("Expected UUID %d to match %d", uuid, duplicateUuid) t.Fatalf("Expected UUID %d to match %d", uuid, duplicateUuid)
......
...@@ -16,10 +16,8 @@ import ( ...@@ -16,10 +16,8 @@ import (
"gitlab.com/elixxir/client/v4/channels" "gitlab.com/elixxir/client/v4/channels"
cryptoChannel "gitlab.com/elixxir/crypto/channel" cryptoChannel "gitlab.com/elixxir/crypto/channel"
"gitlab.com/elixxir/xxdk-wasm/indexedDb" "gitlab.com/elixxir/xxdk-wasm/indexedDb"
"gitlab.com/elixxir/xxdk-wasm/indexedDbWorker"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"syscall/js" "syscall/js"
"time"
) )
const ( const (
...@@ -37,24 +35,29 @@ const ( ...@@ -37,24 +35,29 @@ const (
// update is true if the row is old and was edited. // update is true if the row is old and was edited.
type MessageReceivedCallback func(uuid uint64, channelID *id.ID, update bool) type MessageReceivedCallback func(uuid uint64, channelID *id.ID, update bool)
// NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. // storeDatabaseNameFn matches storage.StoreIndexedDb so that the data can be
// The name should be a base64 encoding of the users public key. // sent between the worker and main thread.
func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, type storeDatabaseNameFn func(databaseName string) error
cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) (
channels.EventModel, error) {
databaseName := path + databaseSuffix
return newWASMModel(databaseName, encryption, cb, storeEncryptionStatus)
}
// storeEncryptionStatusFn matches storage.StoreIndexedDbEncryptionStatus so // storeEncryptionStatusFn matches storage.StoreIndexedDbEncryptionStatus so
// that the data can be sent between the worker and main thread. // that the data can be sent between the worker and main thread.
type storeEncryptionStatusFn func( type storeEncryptionStatusFn func(
databaseName string, encryptionStatus bool) (bool, error) 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. // newWASMModel creates the given [idb.Database] and returns a wasmModel.
func newWASMModel(databaseName string, encryption cryptoChannel.Cipher, func newWASMModel(databaseName string, encryption cryptoChannel.Cipher,
cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) ( cb MessageReceivedCallback, storeDatabaseName storeDatabaseNameFn,
*wasmModel, error) { storeEncryptionStatus storeEncryptionStatusFn) (*wasmModel, error) {
// Attempt to open database object // Attempt to open database object
ctx, cancel := indexedDb.NewContext() ctx, cancel := indexedDb.NewContext()
defer cancel() defer cancel()
...@@ -174,43 +177,3 @@ func v1Upgrade(db *idb.Database) error { ...@@ -174,43 +177,3 @@ func v1Upgrade(db *idb.Database) error {
return nil 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
}
}
...@@ -21,7 +21,6 @@ func main() { ...@@ -21,7 +21,6 @@ func main() {
jww.INFO.Print("[WW] Starting xxDK WebAssembly Channels Database Worker.") jww.INFO.Print("[WW] Starting xxDK WebAssembly Channels Database Worker.")
m := &manager{mh: indexedDb.NewMessageHandler("ChannelsIndexedDbWorker")} m := &manager{mh: indexedDb.NewMessageHandler("ChannelsIndexedDbWorker")}
RegisterDatabaseNameStore(m)
m.RegisterHandlers() m.RegisterHandlers()
m.mh.SignalReady() m.mh.SignalReady()
<-make(chan bool) <-make(chan bool)
......
...@@ -65,7 +65,7 @@ func (m *manager) newWASMEventModelHandler(data []byte) ([]byte, error) { ...@@ -65,7 +65,7 @@ func (m *manager) newWASMEventModelHandler(data []byte) ([]byte, error) {
} }
m.model, err = NewWASMEventModel(msg.Path, encryption, m.model, err = NewWASMEventModel(msg.Path, encryption,
m.messageReceivedCallback, m.storeEncryptionStatus) m.messageReceivedCallback, m.storeDatabaseName, m.storeEncryptionStatus)
if err != nil { if err != nil {
return []byte(err.Error()), nil return []byte(err.Error()), nil
} }
...@@ -96,9 +96,42 @@ func (m *manager) messageReceivedCallback( ...@@ -96,9 +96,42 @@ func (m *manager) messageReceivedCallback(
worker.GetMessageTag, worker.InitID, data) worker.GetMessageTag, worker.InitID, data)
} }
// storeEncryptionStatus augments the functionality of // storeDatabaseName sends the database name to the main thread and waits for
// storage.StoreIndexedDbEncryptionStatus. It takes the database name and // the response. This function mocks the behavior of storage.StoreIndexedDb.
// encryption status //
// 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. // storeEncryptionStatus adheres to the storeEncryptionStatusFn type.
func (m *manager) storeEncryptionStatus( func (m *manager) storeEncryptionStatus(
......
...@@ -12,7 +12,6 @@ package main ...@@ -12,7 +12,6 @@ package main
import ( import (
"crypto/ed25519" "crypto/ed25519"
"syscall/js" "syscall/js"
"time"
"github.com/hack-pad/go-indexeddb/idb" "github.com/hack-pad/go-indexeddb/idb"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -20,7 +19,6 @@ import ( ...@@ -20,7 +19,6 @@ import (
"gitlab.com/elixxir/client/v4/dm" "gitlab.com/elixxir/client/v4/dm"
cryptoChannel "gitlab.com/elixxir/crypto/channel" cryptoChannel "gitlab.com/elixxir/crypto/channel"
"gitlab.com/elixxir/xxdk-wasm/indexedDb" "gitlab.com/elixxir/xxdk-wasm/indexedDb"
"gitlab.com/elixxir/xxdk-wasm/indexedDbWorker"
) )
const ( const (
...@@ -39,24 +37,29 @@ const ( ...@@ -39,24 +37,29 @@ const (
type MessageReceivedCallback func( type MessageReceivedCallback func(
uuid uint64, pubKey ed25519.PublicKey, update bool) uuid uint64, pubKey ed25519.PublicKey, update bool)
// NewWASMEventModel returns a [channels.EventModel] backed by a wasmModel. // storeDatabaseNameFn matches storage.StoreIndexedDb so that the data can be
// The name should be a base64 encoding of the users public key. // sent between the worker and main thread.
func NewWASMEventModel(path string, encryption cryptoChannel.Cipher, type storeDatabaseNameFn func(databaseName string) error
cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) (
dm.EventModel, error) {
databaseName := path + databaseSuffix
return newWASMModel(databaseName, encryption, cb, storeEncryptionStatus)
}
// storeEncryptionStatusFn matches storage.StoreIndexedDbEncryptionStatus so // storeEncryptionStatusFn matches storage.StoreIndexedDbEncryptionStatus so
// that the data can be sent between the worker and main thread. // that the data can be sent between the worker and main thread.
type storeEncryptionStatusFn func( type storeEncryptionStatusFn func(
databaseName string, encryptionStatus bool) (bool, error) 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. // newWASMModel creates the given [idb.Database] and returns a wasmModel.
func newWASMModel(databaseName string, encryption cryptoChannel.Cipher, func newWASMModel(databaseName string, encryption cryptoChannel.Cipher,
cb MessageReceivedCallback, storeEncryptionStatus storeEncryptionStatusFn) ( cb MessageReceivedCallback, storeDatabaseName storeDatabaseNameFn,
*wasmModel, error) { storeEncryptionStatus storeEncryptionStatusFn) (*wasmModel, error) {
// Attempt to open database object // Attempt to open database object
ctx, cancel := indexedDb.NewContext() ctx, cancel := indexedDb.NewContext()
defer cancel() defer cancel()
...@@ -175,44 +178,3 @@ func v1Upgrade(db *idb.Database) error { ...@@ -175,44 +178,3 @@ func v1Upgrade(db *idb.Database) error {
return nil 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
}
}
...@@ -22,7 +22,6 @@ func main() { ...@@ -22,7 +22,6 @@ func main() {
m := &manager{mh: indexedDb.NewMessageHandler("DmIndexedDbWorker")} m := &manager{mh: indexedDb.NewMessageHandler("DmIndexedDbWorker")}
m.RegisterHandlers() m.RegisterHandlers()
RegisterDatabaseNameStore(m)
m.mh.SignalReady() m.mh.SignalReady()
<-make(chan bool) <-make(chan bool)
fmt.Println("[WW] Closing xxDK WebAssembly Channels Database Worker.") fmt.Println("[WW] Closing xxDK WebAssembly Channels Database Worker.")
......
...@@ -362,7 +362,7 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID, ...@@ -362,7 +362,7 @@ func (w *wasmModel) UpdateFromMessageID(messageID message.ID,
return uuid return uuid
case <-time.After(indexedDbWorker.ResponseTimeout): case <-time.After(indexedDbWorker.ResponseTimeout):
jww.ERROR.Printf("Timed out after %s waiting for response from the "+ jww.ERROR.Printf("Timed out after %s waiting for response from the "+
"worker about ReceiveReply", indexedDbWorker.ResponseTimeout) "worker about UpdateFromMessageID", indexedDbWorker.ResponseTimeout)
} }
return 0 return 0
......
...@@ -32,11 +32,11 @@ const InitID = uint64(0) ...@@ -32,11 +32,11 @@ const InitID = uint64(0)
const ( const (
// workerInitialConnectionTimeout is the time to wait to receive initial // workerInitialConnectionTimeout is the time to wait to receive initial
// contact from a new worker before timing out. // 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 // ResponseTimeout is the general time to wait after sending a message to
// receive a response before timing out. // 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. // HandlerFn is the function that handles incoming data from the worker.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment