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
No related branches found
No related tags found
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{
Unique: true,
MultiEntry: false,
}
_, err = messageStore.CreateIndex(messageStoreMessageIndex,
js.ValueOf(messageStoreMessage), messageStoreMessageIndexOpts)
js.ValueOf(messageStoreMessage),
idb.IndexOptions{
Unique: true,
MultiEntry: false,
})
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.
Finish editing this message first!
Please register or to comment