• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 14277115115

05 Apr 2025 01:43AM UTC coverage: 58.056% (-11.0%) from 69.04%
14277115115

Pull #9670

github

web-flow
Merge a7e89c130 into f0ea5bf3b
Pull Request #9670: build: bump version to v0.19.0 rc2

96191 of 165688 relevant lines covered (58.06%)

1.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.95
/batch/scheduler.go
1
package batch
2

3
import (
4
        "sync"
5
        "time"
6

7
        "github.com/lightningnetwork/lnd/kvdb"
8
)
9

10
// TimeScheduler is a batching engine that executes requests within a fixed
11
// horizon. When the first request is received, a TimeScheduler waits a
12
// configurable duration for other concurrent requests to join the batch. Once
13
// this time has elapsed, the batch is closed and executed. Subsequent requests
14
// are then added to a new batch which undergoes the same process.
15
type TimeScheduler struct {
16
        db       kvdb.Backend
17
        locker   sync.Locker
18
        duration time.Duration
19

20
        mu sync.Mutex
21
        b  *batch
22
}
23

24
// NewTimeScheduler initializes a new TimeScheduler with a fixed duration at
25
// which to schedule batches. If the operation needs to modify a higher-level
26
// cache, the cache's lock should be provided to so that external consistency
27
// can be maintained, as successful db operations will cause a request's
28
// OnCommit method to be executed while holding this lock.
29
func NewTimeScheduler(db kvdb.Backend, locker sync.Locker,
30
        duration time.Duration) *TimeScheduler {
2✔
31

2✔
32
        return &TimeScheduler{
2✔
33
                db:       db,
2✔
34
                locker:   locker,
2✔
35
                duration: duration,
2✔
36
        }
2✔
37
}
2✔
38

39
// Execute schedules the provided request for batch execution along with other
40
// concurrent requests. The request will be executed within a fixed horizon,
41
// parameterizeed by the duration of the scheduler. The error from the
42
// underlying operation is returned to the caller.
43
//
44
// NOTE: Part of the Scheduler interface.
45
func (s *TimeScheduler) Execute(r *Request) error {
2✔
46
        req := request{
2✔
47
                Request: r,
2✔
48
                errChan: make(chan error, 1),
2✔
49
        }
2✔
50

2✔
51
        // Add the request to the current batch. If the batch has been cleared
2✔
52
        // or no batch exists, create a new one.
2✔
53
        s.mu.Lock()
2✔
54
        if s.b == nil {
4✔
55
                s.b = &batch{
2✔
56
                        db:     s.db,
2✔
57
                        clear:  s.clear,
2✔
58
                        locker: s.locker,
2✔
59
                }
2✔
60
                time.AfterFunc(s.duration, s.b.trigger)
2✔
61
        }
2✔
62
        s.b.reqs = append(s.b.reqs, &req)
2✔
63

2✔
64
        // If this is a non-lazy request, we'll execute the batch immediately.
2✔
65
        if !r.lazy {
4✔
66
                go s.b.trigger()
2✔
67
        }
2✔
68

69
        s.mu.Unlock()
2✔
70

2✔
71
        // Wait for the batch to process the request. If the batch didn't
2✔
72
        // ask us to execute the request individually, simply return the error.
2✔
73
        err := <-req.errChan
2✔
74
        if err != errSolo {
4✔
75
                return err
2✔
76
        }
2✔
77

78
        // Obtain exclusive access to the cache if this scheduler needs to
79
        // modify the cache in OnCommit.
80
        if s.locker != nil {
×
81
                s.locker.Lock()
×
82
                defer s.locker.Unlock()
×
83
        }
×
84

85
        // Otherwise, run the request on its own.
86
        commitErr := kvdb.Update(s.db, req.Update, func() {
×
87
                if req.Reset != nil {
×
88
                        req.Reset()
×
89
                }
×
90
        })
91

92
        // Finally, return the commit error directly or execute the OnCommit
93
        // closure with the commit error if present.
94
        if req.OnCommit != nil {
×
95
                return req.OnCommit(commitErr)
×
96
        }
×
97

98
        return commitErr
×
99
}
100

101
// clear resets the scheduler's batch to nil so that no more requests can be
102
// added.
103
func (s *TimeScheduler) clear(b *batch) {
2✔
104
        s.mu.Lock()
2✔
105
        if s.b == b {
4✔
106
                s.b = nil
2✔
107
        }
2✔
108
        s.mu.Unlock()
2✔
109
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc