fix race conditions
parent
7000b93d4e
commit
a491f7c77e
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.Flash().SetMessage(l, msg)
|
a.QueueUpdateDraw(func() {
|
||||||
a.setIndicator(l, msg)
|
a.Flash().SetMessage(l, msg)
|
||||||
a.setLogo(l, msg)
|
a.setIndicator(l, msg)
|
||||||
a.Draw()
|
a.setLogo(l, msg)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.Logo().Reset()
|
a.QueueUpdateDraw(func() {
|
||||||
if flash {
|
a.Logo().Reset()
|
||||||
a.Flash().Clear()
|
if flash {
|
||||||
}
|
a.Flash().Clear()
|
||||||
a.Draw()
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) setLogo(l ui.FlashLevel, msg string) {
|
func (a *App) setLogo(l ui.FlashLevel, msg string) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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{}) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue