Example #1
0
func (w *watcher) send(wr clientv3.WatchResponse) {
	if wr.IsProgressNotify() && !w.progress {
		return
	}

	events := make([]*mvccpb.Event, 0, len(wr.Events))

	var lastRev int64
	for i := range wr.Events {
		ev := (*mvccpb.Event)(wr.Events[i])
		if ev.Kv.ModRevision <= w.rev {
			continue
		} else {
			// We cannot update w.rev here.
			// txn can have multiple events with the same rev.
			// If we update w.rev here, we would skip some events in the same txn.
			lastRev = ev.Kv.ModRevision
		}

		filtered := false
		if len(w.filters) != 0 {
			for _, filter := range w.filters {
				if filter(*ev) {
					filtered = true
					break
				}
			}
		}

		if !filtered {
			events = append(events, ev)
		}
	}

	if lastRev > w.rev {
		w.rev = lastRev
	}

	// all events are filtered out?
	if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 {
		return
	}

	pbwr := &pb.WatchResponse{
		Header:  &wr.Header,
		Created: wr.Created,
		WatchId: w.id,
		Events:  events,
	}
	select {
	case w.ch <- pbwr:
	case <-time.After(50 * time.Millisecond):
		// close the watch chan will notify the stream sender.
		// the stream will gc all its watchers.
		close(w.ch)
	}
}
Example #2
0
func (w *watcher) send(wr clientv3.WatchResponse) {
	if wr.IsProgressNotify() && !w.progress {
		return
	}

	events := make([]*mvccpb.Event, 0, len(wr.Events))

	for i := range wr.Events {
		ev := (*mvccpb.Event)(wr.Events[i])
		if ev.Kv.ModRevision <= w.rev {
			continue
		} else {
			w.rev = ev.Kv.ModRevision
		}

		filtered := false
		if len(w.filters) != 0 {
			for _, filter := range w.filters {
				if filter(*ev) {
					filtered = true
					break
				}
			}
		}

		if !filtered {
			events = append(events, ev)
		}
	}

	// all events are filtered out?
	if !wr.IsProgressNotify() && len(events) == 0 {
		return
	}

	pbwr := &pb.WatchResponse{
		Header:  &wr.Header,
		WatchId: w.id,
		Events:  events,
	}
	select {
	case w.ch <- pbwr:
	default:
		panic("handle this")
	}
}
Example #3
0
func (w *watcher) send(wr clientv3.WatchResponse) {
	if wr.IsProgressNotify() && !w.progress {
		return
	}

	// todo: filter out the events that this watcher already seen.

	evs := wr.Events
	events := make([]*mvccpb.Event, len(evs))
	for i := range evs {
		events[i] = (*mvccpb.Event)(evs[i])
	}
	pbwr := &pb.WatchResponse{
		Header:  &wr.Header,
		WatchId: w.id,
		Events:  events,
	}
	select {
	case w.ch <- pbwr:
	default:
		panic("handle this")
	}
}
Example #4
0
// send filters out repeated events by discarding revisions older
// than the last one sent over the watch channel.
func (w *watcher) send(wr clientv3.WatchResponse) {
	if wr.IsProgressNotify() && !w.progress {
		return
	}
	if w.nextrev > wr.Header.Revision && len(wr.Events) > 0 {
		return
	}
	if w.nextrev == 0 {
		// current watch; expect updates following this revision
		w.nextrev = wr.Header.Revision + 1
	}

	events := make([]*mvccpb.Event, 0, len(wr.Events))

	var lastRev int64
	for i := range wr.Events {
		ev := (*mvccpb.Event)(wr.Events[i])
		if ev.Kv.ModRevision < w.nextrev {
			continue
		} else {
			// We cannot update w.rev here.
			// txn can have multiple events with the same rev.
			// If w.nextrev updates here, it would skip events in the same txn.
			lastRev = ev.Kv.ModRevision
		}

		filtered := false
		for _, filter := range w.filters {
			if filter(*ev) {
				filtered = true
				break
			}
		}
		if filtered {
			continue
		}

		if !w.prevKV {
			evCopy := *ev
			evCopy.PrevKv = nil
			ev = &evCopy
		}
		events = append(events, ev)
	}

	if lastRev >= w.nextrev {
		w.nextrev = lastRev + 1
	}

	// all events are filtered out?
	if !wr.IsProgressNotify() && !wr.Created && len(events) == 0 {
		return
	}

	w.lastHeader = wr.Header
	w.post(&pb.WatchResponse{
		Header:  &wr.Header,
		Created: wr.Created,
		WatchId: w.id,
		Events:  events,
	})
}