mirror of
https://github.com/peco/peco.git
synced 2026-09-10 07:16:29 -04:00
stop the query exec timer
This commit is contained in:
parent
6de9f7e58f
commit
eb17420fee
17
peco.go
17
peco.go
|
|
@ -512,6 +512,10 @@ func (p *Peco) Run(ctx context.Context) (err error) {
|
|||
// bail out, the context should be canceled appropriately
|
||||
<-ctx.Done()
|
||||
|
||||
// Stop any pending query exec timer to prevent the callback
|
||||
// from firing after program state is torn down.
|
||||
p.stopQueryExecTimer()
|
||||
|
||||
// ...and we return any errors that we might have been informed about.
|
||||
return p.Err()
|
||||
}
|
||||
|
|
@ -894,6 +898,19 @@ func (p *Peco) ExecQuery(nextFunc func()) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// stopQueryExecTimer stops and clears the pending query exec timer.
|
||||
// It must be called during shutdown to prevent the timer callback
|
||||
// from firing after program state is torn down.
|
||||
func (p *Peco) stopQueryExecTimer() {
|
||||
p.queryExecMutex.Lock()
|
||||
defer p.queryExecMutex.Unlock()
|
||||
|
||||
if p.queryExecTimer != nil {
|
||||
p.queryExecTimer.Stop()
|
||||
p.queryExecTimer = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Peco) PrintResults() {
|
||||
if pdebug.Enabled {
|
||||
g := pdebug.Marker("Peco.PrintResults")
|
||||
|
|
|
|||
49
peco_test.go
49
peco_test.go
|
|
@ -747,7 +747,7 @@ func TestPrintQuery(t *testing.T) {
|
|||
return
|
||||
}
|
||||
})
|
||||
t.Run("No match and print query", func(t *testing.T) {
|
||||
t.Run("No match and print query", func(t *testing.T) { //nolint:dupl
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
|
|
@ -843,3 +843,50 @@ func TestMemoryBufferMarkComplete(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestQueryExecTimerStoppedOnCancel verifies that the queryExecTimer
|
||||
// is stopped when the context is cancelled, preventing the timer
|
||||
// callback from firing after program teardown (issue 1.4 / 7.2).
|
||||
func TestQueryExecTimerStoppedOnCancel(t *testing.T) {
|
||||
p := newPeco()
|
||||
// Set a long query exec delay so the timer is still pending
|
||||
// when we cancel.
|
||||
p.queryExecDelay = 5 * time.Second
|
||||
p.Stdin = bytes.NewBufferString("foo\nbar\nbaz\n")
|
||||
var out bytes.Buffer
|
||||
p.Stdout = &out
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
waitCh := make(chan error, 1)
|
||||
go func() {
|
||||
waitCh <- p.Run(ctx)
|
||||
}()
|
||||
|
||||
// Wait for peco to be ready
|
||||
<-p.Ready()
|
||||
|
||||
// Type a character to trigger ExecQuery which will create the timer
|
||||
p.screen.SendEvent(Event{Type: EventKey, Ch: 'f'})
|
||||
|
||||
// Give the input loop time to process the keystroke and create the timer
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
// Verify the timer was created
|
||||
p.queryExecMutex.Lock()
|
||||
timerCreated := p.queryExecTimer != nil
|
||||
p.queryExecMutex.Unlock()
|
||||
require.True(t, timerCreated, "queryExecTimer should have been created")
|
||||
|
||||
// Cancel the context (simulating program exit)
|
||||
cancel()
|
||||
|
||||
// Wait for Run to return
|
||||
<-waitCh
|
||||
|
||||
// After Run returns, the timer should have been stopped.
|
||||
p.queryExecMutex.Lock()
|
||||
timerAfterCancel := p.queryExecTimer
|
||||
p.queryExecMutex.Unlock()
|
||||
require.Nil(t, timerAfterCancel, "queryExecTimer should be nil after cancellation")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue