Skip to content
Snippets Groups Projects
Commit f3e363cf authored by Jake Taylor's avatar Jake Taylor
Browse files

delete old messages when channel is left

parent 6aa8e0ba
Branches
Tags
2 merge requests!60Revert "Fail a test to be sure it works",!13delete old messages when channel is left
......@@ -20,12 +20,12 @@ import (
"github.com/hack-pad/go-indexeddb/idb"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/elixxir/client/channels"
"gitlab.com/elixxir/client/cmix/rounds"
cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
cryptoChannel "gitlab.com/elixxir/crypto/channel"
"gitlab.com/elixxir/xxdk-wasm/utils"
"gitlab.com/xx_network/primitives/id"
)
......@@ -141,9 +141,60 @@ func (w *wasmModel) LeaveChannel(channelID *id.ID) {
"Deleting Channel failed: %+v", err))
return
}
// Clean up lingering data
err = w.deleteMsgByChannel(channelID)
if err != nil {
jww.ERROR.Printf("%+v", errors.WithMessagef(parentErr,
"Deleting Channel's Message data failed: %+v", err))
return
}
jww.DEBUG.Printf("Successfully deleted channel: %s", channelID)
}
// deleteMsgByChannel is a private helper that uses messageStoreChannelIndex
// to delete all Message with the given Channel ID.
func (w *wasmModel) deleteMsgByChannel(channelID *id.ID) error {
parentErr := errors.New("failed to deleteMsgByChannel")
// Prepare the Transaction
txn, err := w.db.Transaction(idb.TransactionReadWrite, messageStoreName)
if err != nil {
return errors.WithMessagef(parentErr,
"Unable to create Transaction: %+v", err)
}
store, err := txn.ObjectStore(messageStoreName)
if err != nil {
return errors.WithMessagef(parentErr,
"Unable to get ObjectStore: %+v", err)
}
index, err := store.Index(messageStoreChannelIndex)
if err != nil {
return errors.WithMessagef(parentErr,
"Unable to get Index: %+v", err)
}
// Perform the operation
channelIdStr := base64.StdEncoding.EncodeToString(channelID.Marshal())
keyRange, err := idb.NewKeyRangeOnly(js.ValueOf(channelIdStr))
cursorRequest, err := index.OpenCursorRange(keyRange, idb.CursorNext)
if err != nil {
return errors.WithMessagef(parentErr, "Unable to open Cursor: %+v", err)
}
ctx, cancel := newContext()
err = cursorRequest.Iter(ctx,
func(cursor *idb.CursorWithValue) error {
_, err := cursor.Delete()
return err
})
cancel()
if err != nil {
return errors.WithMessagef(parentErr,
"Unable to dump ObjectStore: %+v", err)
}
return nil
}
// ReceiveMessage is called whenever a message is received on a given channel.
//
// It may be called multiple times on the same message; it is incumbent on the
......
......@@ -13,6 +13,7 @@ import (
"encoding/json"
"fmt"
"os"
"strconv"
"testing"
"time"
......@@ -210,3 +211,58 @@ func TestWasmModel_DuplicateReceives(t *testing.T) {
}
}
}
// TestWasmModel_deleteMsgByChannel is a happy path test. Inserts many messages,
// deletes some, and checks that the final result is as expected.
func TestWasmModel_deleteMsgByChannel(t *testing.T) {
testString := "test_deleteMsgByChannel"
totalMessages := 10
expectedMessages := 5
eventModel, err := newWASMModel(testString, dummyCallback)
if err != nil {
t.Fatalf("%+v", err)
}
// Create a test channel id
deleteChannel := id.NewIdFromString("deleteMe", id.Generic, t)
keepChannel := id.NewIdFromString("dontDeleteMe", id.Generic, t)
// Store some test messages
cid := channel.Identity{}
for i := 0; i < expectedMessages; i++ {
testStr := testString + strconv.Itoa(i)
testMsgId := channel.MakeMessageID([]byte(testStr), &id.ID{1})
eventModel.ReceiveMessage(deleteChannel, testMsgId, testStr,
testStr, cid, time.Now(), time.Second, rounds.Round{ID: id.Round(0)}, 0, channels.Sent)
}
for i := expectedMessages; i < totalMessages; i++ {
testStr := testString + strconv.Itoa(i)
testMsgId := channel.MakeMessageID([]byte(testStr), &id.ID{1})
eventModel.ReceiveMessage(keepChannel, testMsgId, testStr,
testStr, cid, time.Now(), time.Second, rounds.Round{ID: id.Round(0)}, 0, channels.Sent)
}
// Check pre-results
result, err := eventModel.dump(messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(result) != totalMessages {
t.Errorf("Expected %d messages, got %d", totalMessages, len(result))
}
// Do delete
err = eventModel.deleteMsgByChannel(deleteChannel)
if err != nil {
t.Error(err)
}
// Check final results
result, err = eventModel.dump(messageStoreName)
if err != nil {
t.Fatalf("%+v", err)
}
if len(result) != expectedMessages {
t.Errorf("Expected %d messages, got %d", expectedMessages, len(result))
}
}
......@@ -102,13 +102,12 @@ func v1Upgrade(db *idb.Database) error {
if err != nil {
return err
}
messageStoreMessageIndexOpts := idb.IndexOptions{
_, err = messageStore.CreateIndex(messageStoreMessageIndex,
js.ValueOf(messageStoreMessage),
idb.IndexOptions{
Unique: true,
MultiEntry: false,
}
_, err = messageStore.CreateIndex(messageStoreMessageIndex,
js.ValueOf(messageStoreMessage), messageStoreMessageIndexOpts)
})
if err != nil {
return err
}
......
......@@ -27,7 +27,6 @@ const (
messageStoreParentIndex = "parent_message_id_index"
messageStoreTimestampIndex = "timestamp_index"
messageStorePinnedIndex = "pinned_index"
messageStorePubkeyIndex = "pubkey_index"
// Message keyPath names (must match json struct tags).
messageStoreMessage = "message_id"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment