| 147 | } |
| 148 | |
| 149 | func (f *folder) Serve(ctx context.Context) error { |
| 150 | f.model.foldersRunning.Add(1) |
| 151 | defer f.model.foldersRunning.Add(-1) |
| 152 | |
| 153 | f.sl.DebugContext(ctx, "Folder starting") |
| 154 | defer f.sl.DebugContext(ctx, "Folder exiting") |
| 155 | |
| 156 | f.setState(FolderStarting) |
| 157 | |
| 158 | defer func() { |
| 159 | f.scanTimer.Stop() |
| 160 | f.versionCleanupTimer.Stop() |
| 161 | f.setState(FolderIdle) |
| 162 | }() |
| 163 | |
| 164 | if err := f.reconcileBlockIndex(ctx); err != nil { |
| 165 | f.setError(ctx, err) |
| 166 | return err // will get restarted by suture |
| 167 | } |
| 168 | |
| 169 | if f.FSWatcherEnabled && f.getHealthErrorAndLoadIgnores() == nil { |
| 170 | f.startWatch(ctx) |
| 171 | } |
| 172 | |
| 173 | // If we're configured to not do version cleanup, or we don't have a |
| 174 | // versioner, cancel and drain that timer now. |
| 175 | if f.versionCleanupInterval == 0 || f.versioner == nil { |
| 176 | if !f.versionCleanupTimer.Stop() { |
| 177 | <-f.versionCleanupTimer.C |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | initialCompleted := f.initialScanFinished |
| 182 | pullTimer := time.NewTimer(0) |
| 183 | pullTimer.Stop() |
| 184 | |
| 185 | f.setState(FolderIdle) |
| 186 | |
| 187 | for { |
| 188 | var err error |
| 189 | |
| 190 | select { |
| 191 | case <-ctx.Done(): |
| 192 | close(f.done) |
| 193 | return nil |
| 194 | |
| 195 | case <-f.pullScheduled: |
| 196 | if f.PullerDelayS > 0 { |
| 197 | // Wait for incoming updates to settle before doing the |
| 198 | // actual pull. Only set the state to SyncWaiting if we have |
| 199 | // reason to believe there is something to sync, to avoid |
| 200 | // unnecessary flashing in the GUI. |
| 201 | if needCount, err := f.db.CountNeed(f.folderID, protocol.LocalDeviceID); err == nil && needCount.TotalItems() > 0 { |
| 202 | f.setState(FolderSyncWaiting) |
| 203 | } |
| 204 | pullTimer.Reset(time.Duration(float64(time.Second) * f.PullerDelayS)) |
| 205 | } else { |
| 206 | _, err = f.pull(ctx) |