func (k *kvChannelIndex) pollForChanges(stableClock base.SequenceClock, newChannelClock base.SequenceClock) (hasChanges bool, cancelPolling bool) {

	changeCacheExpvars.Add(fmt.Sprintf("pollCount-%s", k.channelName), 1)
	// Increment the overall poll count since a changes request (regardless of whether there have been polled changes)
	totalPollCount := atomic.AddUint32(&k.pollCount, 1)
	unreadPollCount := atomic.LoadUint32(&k.unreadPollCount)
	if unreadPollCount > kMaxUnreadPollCount {
		// We've sent a notify, but had (kMaxUnreadPollCount) polls without anyone calling getChanges.
		// Assume nobody is listening for updates - cancel polling for this channel
		return false, true
	}

	if unreadPollCount > 0 {
		// Give listeners more time to call getChanges, but increment
		atomic.AddUint32(&k.unreadPollCount, 1)
	}

	k.lastPolledLock.Lock()
	defer k.lastPolledLock.Unlock()

	// First poll handling
	if k.lastPolledChannelClock == nil {
		k.lastPolledChannelClock = k.clock.Copy()
		k.lastPolledSince = k.clock.Copy()
		k.lastPolledValidTo = k.clock.Copy()
	}

	if !newChannelClock.AnyAfter(k.lastPolledChannelClock) {
		// No changes to channel clock - update validTo based on the new stable sequence
		k.lastPolledValidTo.SetTo(stableClock)
		// If we've exceeded empty poll count, return hasChanges=true to trigger the "is
		// anyone listening" check
		if totalPollCount > kMaxEmptyPollCount {
			return true, false
		} else {
			return false, false
		}
	}

	// The clock has changed - load the changes and store in last polled
	if err := k.updateLastPolled(stableClock, newChannelClock); err != nil {
		base.Warn("Error updating last polled for channel %s: %v", k.channelName, err)
		return false, false
	}

	// We have changes - increment unread counter if we haven't already
	if unreadPollCount == 0 {
		atomic.AddUint32(&k.unreadPollCount, 1)
	}
	return true, false
}