From 86da5c7adf8785edcd5f04b948310be6fa458c23 Mon Sep 17 00:00:00 2001 From: Travis Date: Thu, 5 Mar 2020 20:52:51 -0600 Subject: [PATCH 1/2] temporary fix for int field replica sync bug --- holder.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/holder.go b/holder.go index c763df71b..dc58a8ab1 100644 --- a/holder.go +++ b/holder.go @@ -911,6 +911,16 @@ func (s *holderSyncer) syncFragment(index, field, view string, shard uint64) err return ErrFieldNotFound } + // TODO: this is a temporary fix put in place to prevent + // the syncer from trying to sync replicas of fields + // other than `set` or `time` (i.e. `int`, `mutex`, `bool`, + // `decimal`) using ImportRoaring, because ImportRoaring + // only supports `set` and `time` fields. + if f.Type() != FieldTypeSet && f.Type() != FieldTypeTime { + s.Holder.Logger.Printf("temporarily skipping fragment sync: %s/%d", field, shard) + return nil + } + // Ensure view exists locally. v, err := f.createViewIfNotExists(view) if err != nil { From 70c3cf177517082001c0375151bb10abd0dbf334 Mon Sep 17 00:00:00 2001 From: Travis Date: Thu, 5 Mar 2020 21:16:10 -0600 Subject: [PATCH 2/2] include a basic test which covers the temp fix --- holder_test.go | 37 +++++++++++++++++++++++++++++++++++++ test/holder.go | 14 ++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/holder_test.go b/holder_test.go index 2319a1f5f..f88c39e0e 100644 --- a/holder_test.go +++ b/holder_test.go @@ -523,3 +523,40 @@ func TestHolderSyncer_TimeQuantum(t *testing.T) { } } } + +// Ensure holder can sync integer views with a remote holder. +func TestHolderSyncer_IntField(t *testing.T) { + c := test.MustNewCluster(t, 2) + c[0].Config.Cluster.ReplicaN = 2 + c[0].Config.AntiEntropy.Interval = 0 + c[1].Config.Cluster.ReplicaN = 2 + c[1].Config.AntiEntropy.Interval = 0 + err := c.Start() + if err != nil { + t.Fatalf("starting cluster: %v", err) + } + defer c.Close() + + _, err = c[0].API.CreateIndex(context.Background(), "i", pilosa.IndexOptions{}) + if err != nil { + t.Fatalf("creating index i: %v", err) + } + _, err = c[0].API.CreateField(context.Background(), "i", "f", pilosa.OptFieldTypeInt(0, 100)) + if err != nil { + t.Fatalf("creating field f: %v", err) + } + + hldr0 := &test.Holder{Holder: c[0].Server.Holder()} + hldr1 := &test.Holder{Holder: c[1].Server.Holder()} + + // Set data on the local holder for node0. + hldr0.SetValue("i", "f", 1, 1) + + // Set data on node1. + hldr1.SetValue("i", "f", 2, 2) + + err = c[0].Server.SyncData() + if err != nil { + t.Fatalf("syncing node 0: %v", err) + } +} diff --git a/test/holder.go b/test/holder.go index a4399ba67..4a45f9b91 100644 --- a/test/holder.go +++ b/test/holder.go @@ -16,6 +16,7 @@ package test import ( "io/ioutil" + "math" "os" "time" @@ -165,3 +166,16 @@ func (h *Holder) MustSetBits(index, field string, rowID uint64, columnIDs ...uin h.SetBit(index, field, rowID, columnID) } } + +// SetValue sets an value on the given field. +func (h *Holder) SetValue(index, field string, columnID uint64, value int64) { + idx := h.MustCreateIndexIfNotExists(index, pilosa.IndexOptions{}) + f, err := idx.CreateFieldIfNotExists(field, pilosa.OptFieldTypeInt(math.MinInt64, math.MaxInt64)) + if err != nil { + panic(err) + } + _, err = f.SetValue(columnID, value) + if err != nil { + panic(err) + } +}