From 59443d140bf99fbf3a841fe70b444572d50b1473 Mon Sep 17 00:00:00 2001 From: Furkan Date: Sat, 1 Feb 2025 22:21:01 +0300 Subject: [PATCH 1/2] feat(transaction-is-ended): add IsEnded() method (#995) --- v3/newrelic/transaction.go | 10 ++++++++++ v3/newrelic/transaction_test.go | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/v3/newrelic/transaction.go b/v3/newrelic/transaction.go index ccdf274ac..7d2f8ff76 100644 --- a/v3/newrelic/transaction.go +++ b/v3/newrelic/transaction.go @@ -239,6 +239,16 @@ func (txn *Transaction) SetWebRequestHTTP(r *http.Request) { txn.SetWebRequest(wr) } +// IsEnded returns transaction end status. +// If the transaction is nil, the thread is nil, or the transaction is finished, it returns true. +// Otherwise, it returns thread.finished value. +func (txn *Transaction) IsEnded() bool { + if txn == nil || txn.thread == nil || txn.thread.txn == nil { + return true + } + return txn.thread.txn.finished +} + func transport(r *http.Request) TransportType { if strings.HasPrefix(r.Proto, "HTTP") { if r.TLS != nil { diff --git a/v3/newrelic/transaction_test.go b/v3/newrelic/transaction_test.go index e5dd70f27..d10fc69c8 100644 --- a/v3/newrelic/transaction_test.go +++ b/v3/newrelic/transaction_test.go @@ -6,6 +6,29 @@ import ( "testing" ) +func TestIsEnded(t *testing.T) { + tests := []struct { + name string + txn *Transaction + expected bool + }{ + {"txn is nil", nil, true}, + {"thread is nil", &Transaction{thread: nil}, true}, + {"txn.thread.txn is nil", &Transaction{thread: &thread{}}, true}, + {"txn.thread.txn.finished is true", &Transaction{thread: &thread{txn: &txn{finished: true}}}, true}, + {"txn.thread.txn.finished is false", &Transaction{thread: &thread{txn: &txn{finished: false}}}, false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.txn.IsEnded() + if result != tt.expected { + t.Errorf("IsEnded() = %v; want %v", result, tt.expected) + } + }) + } +} + func TestTransaction_MethodsWithNilTransaction(t *testing.T) { var nilTxn *Transaction From 73b5bba4806b4902bcf857bb4e9828214a4380f3 Mon Sep 17 00:00:00 2001 From: Furkan Date: Tue, 25 Feb 2025 15:22:46 +0300 Subject: [PATCH 2/2] feat(transaction-is-ended): add IsEnded() method to thread --- v3/newrelic/internal_txn.go | 8 ++++++++ v3/newrelic/internal_txn_test.go | 29 +++++++++++++++++++++++++++++ v3/newrelic/transaction.go | 4 ++-- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/v3/newrelic/internal_txn.go b/v3/newrelic/internal_txn.go index 25468ddd8..8adf35d50 100644 --- a/v3/newrelic/internal_txn.go +++ b/v3/newrelic/internal_txn.go @@ -54,6 +54,14 @@ type thread struct { thread *tracingThread } +func (thd *thread) IsEnded() bool { + txn := thd.txn + txn.Lock() + defer txn.Unlock() + + return txn.finished +} + func (txn *txn) markStart(now time.Time) { txn.Start = now // The mainThread is considered active now. diff --git a/v3/newrelic/internal_txn_test.go b/v3/newrelic/internal_txn_test.go index 04d37bc28..5aca377a3 100644 --- a/v3/newrelic/internal_txn_test.go +++ b/v3/newrelic/internal_txn_test.go @@ -1018,3 +1018,32 @@ func TestPanicNilRecovery(t *testing.T) { }, }) } + +func TestIsEndedInternal(t *testing.T) { + tests := []struct { + name string + txn *txn + expected bool + }{ + { + name: "finished transaction", + txn: &txn{finished: true}, + expected: true, + }, + { + name: "unfinished transaction", + txn: &txn{finished: false}, + expected: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + thread := &thread{txn: tt.txn} + result := thread.IsEnded() + if result != tt.expected { + t.Errorf("IsEnded() = %v; want %v", result, tt.expected) + } + }) + } +} diff --git a/v3/newrelic/transaction.go b/v3/newrelic/transaction.go index 7d2f8ff76..d4f06466f 100644 --- a/v3/newrelic/transaction.go +++ b/v3/newrelic/transaction.go @@ -243,10 +243,10 @@ func (txn *Transaction) SetWebRequestHTTP(r *http.Request) { // If the transaction is nil, the thread is nil, or the transaction is finished, it returns true. // Otherwise, it returns thread.finished value. func (txn *Transaction) IsEnded() bool { - if txn == nil || txn.thread == nil || txn.thread.txn == nil { + if nilTransaction(txn) { return true } - return txn.thread.txn.finished + return txn.thread.IsEnded() } func transport(r *http.Request) TransportType {