fix race conditions

mine
derailed 2020-02-12 08:33:56 -07:00
parent 7000b93d4e
commit a491f7c77e
9 changed files with 29 additions and 30 deletions

View File

@ -46,7 +46,6 @@ func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) {
// List all Resources in a given namespace. // List all Resources in a given namespace.
func (t *Table) List(ctx context.Context, ns string) ([]runtime.Object, error) { func (t *Table) List(ctx context.Context, ns string) ([]runtime.Object, error) {
log.Debug().Msgf("TABLE-LIST %q:%q", ns, t.gvr)
a := fmt.Sprintf(gvFmt, metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName) a := fmt.Sprintf(gvFmt, metav1beta1.SchemeGroupVersion.Version, metav1beta1.GroupName)
_, codec := t.codec() _, codec := t.codec()

View File

@ -2,7 +2,6 @@ package model
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -186,7 +185,6 @@ func (t *Table) updater(ctx context.Context) {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
t.fireTableLoadFailed(errors.New("operation canceled"))
return return
case <-time.After(rate): case <-time.After(rate):
rate = t.refreshRate rate = t.refreshRate
@ -207,7 +205,7 @@ func (t *Table) refresh(ctx context.Context) {
t.fireTableLoadFailed(err) t.fireTableLoadFailed(err)
return return
} }
t.fireTableChanged() t.fireTableChanged(t.Peek())
} }
func (t *Table) list(ctx context.Context, a dao.Accessor) ([]runtime.Object, error) { func (t *Table) list(ctx context.Context, a dao.Accessor) ([]runtime.Object, error) {
@ -261,7 +259,6 @@ func (t *Table) reconcile(ctx context.Context) error {
t.mx.Lock() t.mx.Lock()
defer t.mx.Unlock() defer t.mx.Unlock()
// if labelSelector in place might as well clear the model data. // if labelSelector in place might as well clear the model data.
sel, ok := ctx.Value(internal.KeyLabels).(string) sel, ok := ctx.Value(internal.KeyLabels).(string)
if ok && sel != "" { if ok && sel != "" {
@ -300,8 +297,7 @@ func (t *Table) resourceMeta() ResourceMeta {
return meta return meta
} }
func (t *Table) fireTableChanged() { func (t *Table) fireTableChanged(data render.TableData) {
data := t.Peek()
for _, l := range t.listeners { for _, l := range t.listeners {
l.TableDataChanged(data) l.TableDataChanged(data)
} }

View File

@ -13,9 +13,8 @@ type Fields []string
// Clone returns a copy of the fields. // Clone returns a copy of the fields.
func (f Fields) Clone() Fields { func (f Fields) Clone() Fields {
cp := make(Fields, len(f)) cp := make(Fields, len(f))
for i, v := range f { copy(cp, f)
cp[i] = v
}
return cp return cp
} }

View File

@ -19,11 +19,11 @@ func (t *TableData) Clear() {
// Clone returns a copy of the table // Clone returns a copy of the table
func (t *TableData) Clone() TableData { func (t *TableData) Clone() TableData {
return cloneTable(*t) return TableData{
} Header: t.Header.Clone(),
RowEvents: t.RowEvents.Clone(),
func cloneTable(t TableData) TableData { Namespace: t.Namespace,
return t }
} }
// SetHeader sets table header. // SetHeader sets table header.

View File

@ -134,8 +134,7 @@ func (f *Flash) SetMessage(level FlashLevel, msg ...string) {
} }
var ctx context.Context var ctx context.Context
ctx, f.cancel = context.WithCancel(context.TODO()) ctx, f.cancel = context.WithTimeout(context.Background(), flashDelay)
ctx, f.cancel = context.WithTimeout(ctx, flashDelay)
go f.refresh(ctx) go f.refresh(ctx)
} }

View File

@ -3,8 +3,6 @@ package ui
import ( import (
"fmt" "fmt"
"github.com/gdamore/tcell"
"github.com/derailed/k9s/internal/config" "github.com/derailed/k9s/internal/config"
"github.com/derailed/tview" "github.com/derailed/tview"
) )
@ -29,6 +27,7 @@ func NewLogo(styles *config.Styles) *Logo {
l.AddItem(l.logo, 0, 6, false) l.AddItem(l.logo, 0, 6, false)
l.AddItem(l.status, 0, 1, false) l.AddItem(l.status, 0, 1, false)
l.refreshLogo(styles.Body().LogoColor) l.refreshLogo(styles.Body().LogoColor)
l.SetBackgroundColor(styles.BgColor())
styles.AddListener(&l) styles.AddListener(&l)
return &l return &l
@ -96,7 +95,6 @@ func (l *Logo) refreshLogo(c string) {
func logo() *tview.TextView { func logo() *tview.TextView {
v := tview.NewTextView() v := tview.NewTextView()
v.SetBackgroundColor(tcell.ColorDefault)
v.SetWordWrap(false) v.SetWordWrap(false)
v.SetWrap(false) v.SetWrap(false)
v.SetTextAlign(tview.AlignLeft) v.SetTextAlign(tview.AlignLeft)
@ -107,7 +105,6 @@ func logo() *tview.TextView {
func status() *tview.TextView { func status() *tview.TextView {
v := tview.NewTextView() v := tview.NewTextView()
v.SetBackgroundColor(tcell.ColorDefault)
v.SetWordWrap(false) v.SetWordWrap(false)
v.SetWrap(false) v.SetWrap(false)
v.SetTextAlign(tview.AlignCenter) v.SetTextAlign(tview.AlignCenter)

View File

@ -169,6 +169,7 @@ func (a *App) buildHeader() tview.Primitive {
func (a *App) Halt() { func (a *App) Halt() {
if a.cancelFn != nil { if a.cancelFn != nil {
a.cancelFn() a.cancelFn()
a.cancelFn = nil
} }
} }
@ -311,19 +312,21 @@ func (a *App) Run() error {
// Status reports a new app status for display. // Status reports a new app status for display.
func (a *App) Status(l ui.FlashLevel, msg string) { func (a *App) Status(l ui.FlashLevel, msg string) {
a.QueueUpdateDraw(func() {
a.Flash().SetMessage(l, msg) a.Flash().SetMessage(l, msg)
a.setIndicator(l, msg) a.setIndicator(l, msg)
a.setLogo(l, msg) a.setLogo(l, msg)
a.Draw() })
} }
// ClearStatus reset logo back to normal. // ClearStatus reset logo back to normal.
func (a *App) ClearStatus(flash bool) { func (a *App) ClearStatus(flash bool) {
a.QueueUpdateDraw(func() {
a.Logo().Reset() a.Logo().Reset()
if flash { if flash {
a.Flash().Clear() a.Flash().Clear()
} }
a.Draw() })
} }
func (a *App) setLogo(l ui.FlashLevel, msg string) { func (a *App) setLogo(l ui.FlashLevel, msg string) {

View File

@ -160,6 +160,8 @@ func (x *Xray) refreshActions() {
} }
switch gvr { switch gvr {
case "v1/namespaces":
x.Actions().Delete(tcell.KeyEnter)
case "containers": case "containers":
x.Actions().Delete(tcell.KeyEnter) x.Actions().Delete(tcell.KeyEnter)
aa[ui.KeyS] = ui.NewKeyAction("Shell", x.shellCmd, true) aa[ui.KeyS] = ui.NewKeyAction("Shell", x.shellCmd, true)

View File

@ -109,10 +109,14 @@ func (f *Factory) waitForCacheSync(ns string) {
if f.isClusterWide() { if f.isClusterWide() {
ns = client.AllNamespaces ns = client.AllNamespaces
} }
f.mx.RLock()
defer f.mx.RUnlock()
fac, ok := f.factories[ns] fac, ok := f.factories[ns]
if !ok { if !ok {
return return
} }
// Hang for a sec for the cache to refresh if still not done bail out! // Hang for a sec for the cache to refresh if still not done bail out!
c := make(chan struct{}) c := make(chan struct{})
go func(c chan struct{}) { go func(c chan struct{}) {