Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion session/pingpong/invoice_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,24 @@ func (it *InvoiceTracker) WaitFirstInvoice(wait time.Duration) error {
}

func (it *InvoiceTracker) handlePromiseErrors(ch <-chan error) {
hadResult := false
for err := range ch {
it.promiseErrors <- err
hadResult = true
select {
case it.promiseErrors <- err:
case <-it.stop:
return
}
}

// HermesPromiseHandler closes the channel without sending a value when a
// promise request completes successfully. Propagate that completion so the
// tracker can reset its consecutive Hermes failure count.
if !hadResult {
select {
case it.promiseErrors <- nil:
case <-it.stop:
}
}
}

Expand Down
48 changes: 48 additions & 0 deletions session/pingpong/invoice_tracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,54 @@ func TestInvoiceTracker_receiveExchangeMessageOrTimeout(t *testing.T) {
}
}

func TestInvoiceTracker_handlePromiseErrorsReportsSuccessfulCompletion(t *testing.T) {
it := &InvoiceTracker{
stop: make(chan struct{}),
promiseErrors: make(chan error, 1),
}

result := make(chan error)
close(result)

it.handlePromiseErrors(result)

assert.NoError(t, <-it.promiseErrors)
}

func TestInvoiceTracker_handlePromiseErrorsDoesNotReportSuccessAfterError(t *testing.T) {
it := &InvoiceTracker{
stop: make(chan struct{}),
promiseErrors: make(chan error, 2),
}

result := make(chan error, 1)
result <- ErrHermesInternal
close(result)

it.handlePromiseErrors(result)

assert.ErrorIs(t, <-it.promiseErrors, ErrHermesInternal)
select {
case err := <-it.promiseErrors:
t.Fatalf("unexpected extra promise result: %v", err)
default:
}
}

func TestInvoiceTracker_handleHermesErrorResetsFailureCountOnSuccess(t *testing.T) {
it := &InvoiceTracker{
deps: InvoiceTrackerDeps{
MaxHermesFailureCount: 10,
},
}

assert.NoError(t, it.handleHermesError(ErrHermesInternal))
assert.Equal(t, uint64(1), it.hermesFailureCount)

assert.NoError(t, it.handleHermesError(nil))
assert.Zero(t, it.hermesFailureCount)
}

func TestInvoiceTracker_handleHermesError(t *testing.T) {
tests := []struct {
name string
Expand Down