// Creates a new Shadower. func NewShadower(context *DatabaseContext, bucket base.Bucket, docIDPattern *regexp.Regexp) (*Shadower, error) { tapFeed, err := bucket.StartTapFeed(sgbucket.TapArguments{Backfill: 0}) if err != nil { return nil, err } s := &Shadower{context: context, bucket: bucket, tapFeed: tapFeed, docIDPattern: docIDPattern} go s.readTapFeed() return s, nil }
// Creates a new Shadower. func NewShadower(context *DatabaseContext, bucket base.Bucket, docIDPattern *regexp.Regexp) (*Shadower, error) { tapFeed, err := bucket.StartTapFeed(sgbucket.TapArguments{Backfill: 0, Notify: func(bucket string, err error) { context.TakeDbOffline("Lost shadower TAP Feed") }}) if err != nil { return nil, err } s := &Shadower{context: context, bucket: bucket, tapFeed: tapFeed, docIDPattern: docIDPattern} go s.readTapFeed() return s, nil }
// Starts a changeListener on a given Bucket. func (listener *changeListener) Start(bucket base.Bucket, trackDocs bool, notify sgbucket.BucketNotifyFn) error { listener.bucket = bucket listener.TapArgs = sgbucket.TapArguments{ Backfill: sgbucket.TapNoBackfill, Notify: notify, } tapFeed, err := bucket.StartTapFeed(listener.TapArgs) if err != nil { return err } listener.tapFeed = tapFeed listener.counter = 1 listener.terminateCheckCounter = 0 listener.keyCounts = map[string]uint64{} listener.tapNotifier = sync.NewCond(&sync.Mutex{}) if trackDocs { listener.DocChannel = make(chan sgbucket.TapEvent, 100) } // Start a goroutine to broadcast to the tapNotifier whenever a channel or user/role changes: go func() { defer func() { listener.notifyStopping() if listener.DocChannel != nil { close(listener.DocChannel) } }() for event := range tapFeed.Events() { if event.Opcode == sgbucket.TapMutation || event.Opcode == sgbucket.TapDeletion { key := string(event.Key) if strings.HasPrefix(key, auth.UserKeyPrefix) || strings.HasPrefix(key, auth.RoleKeyPrefix) { if listener.OnDocChanged != nil { listener.OnDocChanged(key, event.Value, event.Sequence, event.VbNo) } listener.Notify(base.SetOf(key)) } else if trackDocs && !strings.HasPrefix(key, KSyncKeyPrefix) && !strings.HasPrefix(key, kIndexPrefix) { if listener.OnDocChanged != nil { listener.OnDocChanged(key, event.Value, event.Sequence, event.VbNo) } listener.DocChannel <- event } } } }() return nil }