Skip to content

Commit ce1046b

Browse files
authored
Merge pull request #1380 from lightninglabs/context-guard-go
Proof of Concept: Simplifying Concurrency with `ContextGuard.Goroutine`
2 parents 28c4ea8 + eef7461 commit ce1046b

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

fn/context_guard.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,29 @@ func (g *ContextGuard) WithCtxQuitNoTimeout() (context.Context, func()) {
9999

100100
return ctx, cancel
101101
}
102+
103+
// Goroutine runs the given function in a separate goroutine and ensures proper
104+
// error handling. If the object function returns an error, the provided error
105+
// handler is called.
106+
//
107+
// This method also manages the context guard wait group when spawning the
108+
// goroutine.
109+
func (g *ContextGuard) Goroutine(f func() error, errHandler func(error)) {
110+
if f == nil {
111+
panic("no function provided")
112+
}
113+
114+
if errHandler == nil {
115+
panic("no error handler provided")
116+
}
117+
118+
g.Wg.Add(1)
119+
go func() {
120+
defer g.Wg.Done()
121+
122+
err := f()
123+
if err != nil {
124+
errHandler(err)
125+
}
126+
}()
127+
}

rfq/negotiator.go

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -756,10 +756,7 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
756756
}
757757

758758
// Query the price oracle asynchronously using a separate goroutine.
759-
n.Wg.Add(1)
760-
go func() {
761-
defer n.Wg.Done()
762-
759+
n.ContextGuard.Goroutine(func() error {
763760
// The sell accept message includes a bid price, which
764761
// represents the amount the peer is willing to pay for the
765762
// asset we are selling.
@@ -778,14 +775,8 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
778775
fn.Some(msg.AssetRate),
779776
)
780777
if err != nil {
781-
// The price oracle returned an error. We will return
782-
// without calling the quote accept callback.
783-
err = fmt.Errorf("negotiator failed to query price "+
784-
"oracle when handling incoming sell accept "+
785-
"message: %w", err)
786-
log.Errorf("Error calling price oracle: %v", err)
787-
n.cfg.ErrChan <- err
788-
778+
// The price oracle returned an error.
779+
//
789780
// Construct an invalid quote response event so that we
790781
// can inform the peer that the quote response has not
791782
// validated successfully.
@@ -798,7 +789,9 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
798789
),
799790
)
800791

801-
return
792+
return fmt.Errorf("negotiator failed to query price "+
793+
"oracle when handling incoming sell accept "+
794+
"message: %w", err)
802795
}
803796

804797
// The price returned by the oracle may not always align with
@@ -816,11 +809,8 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
816809
assetRate.Rate, tolerance,
817810
)
818811
if err != nil {
819-
// The tolerance check failed. We will return without
820-
// calling the quote accept callback.
821-
err = fmt.Errorf("failed to check tolerance: %w", err)
822-
log.Errorf("Error checking tolerance: %v", err)
823-
812+
// The tolerance check failed.
813+
//
824814
// Construct an invalid quote response event so that we
825815
// can inform the peer that the quote response has not
826816
// validated successfully.
@@ -833,7 +823,7 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
833823
),
834824
)
835825

836-
return
826+
return fmt.Errorf("failed to check tolerance: %w", err)
837827
}
838828

839829
if !acceptablePrice {
@@ -857,11 +847,17 @@ func (n *Negotiator) HandleIncomingSellAccept(msg rfqmsg.SellAccept,
857847
),
858848
)
859849

860-
return
850+
return nil
861851
}
862852

863853
finalise(msg, fn.None[InvalidQuoteRespEvent]())
864-
}()
854+
return nil
855+
}, func(err error) {
856+
log.Errorf("Error checking incoming sell accept asset rate: %v",
857+
err)
858+
859+
n.cfg.ErrChan <- err
860+
})
865861
}
866862

867863
// SellOffer is a struct that represents an asset sell offer. This

0 commit comments

Comments
 (0)