@@ -101,6 +101,9 @@ func (r *htlcReleaseEvent) Less(other queue.PriorityQueueItem) bool {
101101// created by the daemon. The registry is a thin wrapper around a map in order
102102// to ensure that all updates/reads are thread safe.
103103type InvoiceRegistry struct {
104+ started atomic.Bool
105+ stopped atomic.Bool
106+
104107 sync.RWMutex
105108
106109 nextClientID uint32 // must be used atomically
@@ -213,42 +216,66 @@ func (i *InvoiceRegistry) scanInvoicesOnStart(ctx context.Context) error {
213216
214217// Start starts the registry and all goroutines it needs to carry out its task.
215218func (i * InvoiceRegistry ) Start () error {
216- // Start InvoiceExpiryWatcher and prepopulate it with existing active
217- // invoices.
218- err := i .expiryWatcher .Start (func (hash lntypes.Hash , force bool ) error {
219- return i .cancelInvoiceImpl (context .Background (), hash , force )
220- })
219+ var err error
220+
221+ log .Info ("InvoiceRegistry starting..." )
222+
223+ if i .started .Swap (true ) {
224+ return fmt .Errorf ("InvoiceRegistry started more than once" )
225+ }
226+ // Start InvoiceExpiryWatcher and prepopulate it with existing
227+ // active invoices.
228+ err = i .expiryWatcher .Start (
229+ func (hash lntypes.Hash , force bool ) error {
230+ return i .cancelInvoiceImpl (
231+ context .Background (), hash , force ,
232+ )
233+ })
221234 if err != nil {
222235 return err
223236 }
224237
225- log .Info ("InvoiceRegistry starting" )
226-
227238 i .wg .Add (1 )
228239 go i .invoiceEventLoop ()
229240
230- // Now scan all pending and removable invoices to the expiry watcher or
231- // delete them.
241+ // Now scan all pending and removable invoices to the expiry
242+ // watcher or delete them.
232243 err = i .scanInvoicesOnStart (context .Background ())
233244 if err != nil {
234245 _ = i .Stop ()
235- return err
236246 }
237247
238- return nil
248+ log .Debug ("InvoiceRegistry started" )
249+
250+ return err
239251}
240252
241253// Stop signals the registry for a graceful shutdown.
242254func (i * InvoiceRegistry ) Stop () error {
255+ log .Info ("InvoiceRegistry shutting down..." )
256+
257+ if i .stopped .Swap (true ) {
258+ return fmt .Errorf ("InvoiceRegistry stopped more than once" )
259+ }
260+
243261 log .Info ("InvoiceRegistry shutting down..." )
244262 defer log .Debug ("InvoiceRegistry shutdown complete" )
245263
246- i .expiryWatcher .Stop ()
264+ var err error
265+ if i .expiryWatcher == nil {
266+ err = fmt .Errorf ("InvoiceRegistry expiryWatcher is not " +
267+ "initialized" )
268+ } else {
269+ i .expiryWatcher .Stop ()
270+ }
247271
248272 close (i .quit )
249273
250274 i .wg .Wait ()
251- return nil
275+
276+ log .Debug ("InvoiceRegistry shutdown complete" )
277+
278+ return err
252279}
253280
254281// invoiceEvent represents a new event that has modified on invoice on disk.
0 commit comments