|
4 | 4 | "context"
|
5 | 5 | "errors"
|
6 | 6 | "sync"
|
| 7 | + "sync/atomic" |
7 | 8 | "time"
|
8 | 9 |
|
9 | 10 | logging "github.com/ipfs/go-log/v2"
|
@@ -42,7 +43,7 @@ type Syncer[H header.Header] struct {
|
42 | 43 | // signals to start syncing
|
43 | 44 | triggerSync chan struct{}
|
44 | 45 | // syncedHead is the latest synced header.
|
45 |
| - syncedHead H |
| 46 | + syncedHead atomic.Pointer[H] |
46 | 47 | // pending keeps ranges of valid new network headers awaiting to be appended to store
|
47 | 48 | pending ranges[H]
|
48 | 49 | // netReqLk ensures only one network head is requested at any moment
|
@@ -177,42 +178,48 @@ func (s *Syncer[H]) sync(ctx context.Context) {
|
177 | 178 | return
|
178 | 179 | }
|
179 | 180 |
|
180 |
| - if s.syncedHead.IsZero() { |
| 181 | + headPtr := s.syncedHead.Load() |
| 182 | + |
| 183 | + var header H |
| 184 | + if headPtr == nil { |
181 | 185 | head, err := s.store.Head(ctx)
|
182 | 186 | if err != nil {
|
183 | 187 | log.Errorw("getting head during sync", "err", err)
|
184 | 188 | return
|
185 | 189 | }
|
186 |
| - s.syncedHead = head |
| 190 | + header = head |
| 191 | + } else { |
| 192 | + header = *headPtr |
187 | 193 | }
|
188 |
| - if s.syncedHead.Height() >= newHead.Height() { |
| 194 | + |
| 195 | + if header.Height() >= newHead.Height() { |
189 | 196 | log.Warnw("sync attempt to an already synced header",
|
190 |
| - "synced_height", s.syncedHead.Height(), |
| 197 | + "synced_height", header.Height(), |
191 | 198 | "attempted_height", newHead.Height(),
|
192 | 199 | )
|
193 | 200 | log.Warn("PLEASE REPORT THIS AS A BUG")
|
194 | 201 | return // should never happen, but just in case
|
195 | 202 | }
|
196 | 203 |
|
197 | 204 | log.Infow("syncing headers",
|
198 |
| - "from", s.syncedHead.Height(), |
| 205 | + "from", header.Height(), |
199 | 206 | "to", newHead.Height())
|
200 |
| - err := s.doSync(ctx, s.syncedHead, newHead) |
| 207 | + err := s.doSync(ctx, header, newHead) |
201 | 208 | if err != nil {
|
202 | 209 | if errors.Is(err, context.Canceled) {
|
203 | 210 | // don't log this error as it is normal case of Syncer being stopped
|
204 | 211 | return
|
205 | 212 | }
|
206 | 213 |
|
207 | 214 | log.Errorw("syncing headers",
|
208 |
| - "from", s.syncedHead.Height(), |
| 215 | + "from", header.Height(), |
209 | 216 | "to", newHead.Height(),
|
210 | 217 | "err", err)
|
211 | 218 | return
|
212 | 219 | }
|
213 | 220 |
|
214 | 221 | log.Infow("finished syncing",
|
215 |
| - "from", s.syncedHead.Height(), |
| 222 | + "from", header.Height(), |
216 | 223 | "to", newHead.Height(),
|
217 | 224 | "elapsed time", s.state.End.Sub(s.state.Start))
|
218 | 225 | }
|
@@ -257,7 +264,7 @@ func (s *Syncer[H]) processHeaders(ctx context.Context, from, to uint64) (int, e
|
257 | 264 |
|
258 | 265 | amount, err := s.store.Append(ctx, headers...)
|
259 | 266 | if err == nil && amount > 0 {
|
260 |
| - s.syncedHead = headers[amount-1] |
| 267 | + s.syncedHead.Store(&headers[amount-1]) |
261 | 268 | }
|
262 | 269 | return amount, err
|
263 | 270 | }
|
|
0 commit comments