@@ -17,30 +17,32 @@ import (
1717 "github.com/couchbase/sync_gateway/base"
1818)
1919
20+ // resyncResumeFunc is a callback function to call to resume a resync process.
21+ type resyncResumeFunc func (ctx context.Context ) error
22+
2023type DatabaseState struct {
2124 ResyncRunning * bool `json:"resync,omitempty"`
2225}
2326
2427type DatabaseStateMgr struct {
25- CAS uint64
26- dbStateID string
27- metadataStore base.DataStore
28- pollingInterval time.Duration
29- resumeResyncFunc func ( ctx context. Context ) error
30- lock sync.Mutex
31- terminator chan struct {}
32- done chan struct {}
28+ CAS uint64
29+ dbStateID string
30+ metadataStore base.DataStore
31+ pollingInterval time.Duration
32+ resumeResync resyncResumeFunc
33+ lock sync.Mutex
34+ terminator chan struct {}
35+ done chan struct {}
3336}
3437
35- // NewDatabaseStateMgr creates a DatabaseStateMgr for the given database. resumeResyncFunc is called by the polling loop
36- // when a state change is detected with ResyncRunning set to true; it should resume the resync process.
37- func NewDatabaseStateMgr (metadataStore base.DataStore , dbStateID string , resumeResyncFunc func (ctx context.Context ) error ) * DatabaseStateMgr {
38+ // NewDatabaseStateMgr creates a DatabaseStateMgr for the given database. If resumeResync is non-nil, it will be invoked when DatabaseState.ResyncRunning is detected as changed on the bucket.
39+ func NewDatabaseStateMgr (metadataStore base.DataStore , dbStateID string , resumeResync resyncResumeFunc ) * DatabaseStateMgr {
3840 return & DatabaseStateMgr {
39- dbStateID : dbStateID ,
40- CAS : 0 ,
41- metadataStore : metadataStore ,
42- pollingInterval : 10 * time .Second ,
43- resumeResyncFunc : resumeResyncFunc ,
41+ dbStateID : dbStateID ,
42+ CAS : 0 ,
43+ metadataStore : metadataStore ,
44+ pollingInterval : 10 * time .Second ,
45+ resumeResync : resumeResync ,
4446 }
4547}
4648
@@ -112,19 +114,20 @@ func (dbMgr *DatabaseStateMgr) StartPolling(ctx context.Context) {
112114 }()
113115}
114116
115- // poll checks whether the state document has been updated and, if ResyncRunning is true, invokes
116- // resumeResyncFunc. The locally held CAS is only advanced after resumeResyncFunc succeeds (or when no handler
117- // action is required), so a transient resumeResyncFunc error leaves the CAS stale and the next tick retries.
117+ // poll checks whether the state document has been updated and calls appropriate callback functions. If the callback
118+ // functions return any errors, do not update the CAS so the next time poll runs, the callback function will rerun.
118119func (dbMgr * DatabaseStateMgr ) poll (ctx context.Context ) {
119120 newCAS , state , ok := dbMgr .isUpdated (ctx )
120121 if ! ok {
121122 return
122123 }
123- if state .ResyncRunning != nil && * state .ResyncRunning {
124- err := dbMgr .resumeResyncFunc (ctx )
125- if err != nil {
126- base .WarnfCtx (ctx , "failed to resume resync from DatabaseStateMgr: %v, will try again." , err )
127- return // leave CAS stale so next tick retries
124+ if dbMgr .resumeResync != nil {
125+ if state .ResyncRunning != nil && * state .ResyncRunning {
126+ err := dbMgr .resumeResync (ctx )
127+ if err != nil {
128+ base .WarnfCtx (ctx , "failed to resume resync from DatabaseStateMgr: %v, will try again." , err )
129+ return // leave CAS stale so next tick retries
130+ }
128131 }
129132 }
130133 dbMgr .lock .Lock ()
0 commit comments