From 41c59b77fd7a96fdb929ed3f004d92a7ad1b3946 Mon Sep 17 00:00:00 2001 From: hphamMolecula <89804723+hphamMolecula@users.noreply.github.com> Date: Mon, 18 Jul 2022 17:35:34 -0500 Subject: [PATCH] FB-1548 - Added a fix for panic error that could happen when a view is opened by the ingest process but at the same time, was also deleted by TTL (#2147) --- field.go | 4 +++- roaring/roaring.go | 3 +++ view.go | 13 +++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/field.go b/field.go index d2bd17223..0927146d4 100644 --- a/field.go +++ b/field.go @@ -1110,7 +1110,7 @@ func (f *Field) createViewIfNotExistsBase(cvm *CreateViewMessage) (*view, bool, // If we already have this view, we can probably assume etcd already // has it. - if view := f.viewMap[cvm.View]; view != nil { + if view := f.viewMap[cvm.View]; view != nil && !view.isClosing() { return view, false, nil } @@ -1142,6 +1142,8 @@ func (f *Field) newView(path, name string) *view { // deleteView removes the view from the field. func (f *Field) deleteView(name string) error { + f.mu.Lock() + defer f.mu.Unlock() view := f.viewMap[name] if view == nil { return ErrInvalidView diff --git a/roaring/roaring.go b/roaring/roaring.go index 78071f505..4d9079d5b 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -444,6 +444,9 @@ func (b *Bitmap) DirectAdd(v uint64) bool { // Contains returns true if v is in the bitmap. func (b *Bitmap) Contains(v uint64) bool { + if b == nil { + return false + } c := b.Containers.Get(highbits(v)) if c == nil { return false diff --git a/view.go b/view.go index 331ef714a..36fa0ba82 100644 --- a/view.go +++ b/view.go @@ -331,11 +331,24 @@ func (v *view) Name() string { return v.name } +func (v *view) isClosing() bool { + select { + case <-v.closing: + return true + default: + return false + } +} + // CreateFragmentIfNotExists returns a fragment in the view by shard. func (v *view) CreateFragmentIfNotExists(shard uint64) (*fragment, error) { v.mu.Lock() defer v.mu.Unlock() + if v.isClosing() { + return nil, fmt.Errorf("cannot create fragment, view is closed") + } + // Find fragment in cache first. if frag := v.fragments[shard]; frag != nil { return frag, nil