Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@hawkw
Copy link
Contributor

@hawkw hawkw commented Oct 21, 2017

I've modified our code for watching Kubernetes resources so that it will ignore events whose resource versions are older than the resource version of the previous event. We do this by creating a two-item sliding window over the stream of watch events, and filtering out those tuples where the first item (the previous event) is older than the second item (the received event). This should ensure that we never travel back in time when the Kubernetes API is out of sync.

I've added a test for EndpointsNamer and ServiceNamer that assert that the namer's state does not update when receiving events in reverse order. Furthermore, a number of existing tests had to be modified to ensure all resource versions were sequential – we probably had been lazy in the past about copying and pasting JSON strings in tests without updating their resource versions.

Closes #1680

@hawkw hawkw added this to the 1.3.1 milestone Oct 21, 2017
@hawkw hawkw self-assigned this Oct 21, 2017
@hawkw hawkw requested review from adleong and klingerf October 21, 2017 00:06
@hawkw hawkw changed the title Make k8s watch code ignore events older than the previous event Stop k8s watches from time travelling Oct 21, 2017
// Ignore any cases where we receive a resource version lower
// than the last received resource version, by creating a sliding
// two-item window over the stream of watch events.
stream.paired
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works. Consider:

stream = [3, 1, 2]
paired = [(x,3), (3,1), (1,2)]
filtered = [(x,3), (1,2)]
mapped = [3,2]

I think you could probably accomplish this with a scanLeft...

stream.scanLeft[(W, Boolean)]((Zero, false)) { case ((largest, incr), w) =>
  if (w > largest) (w, true)
  else (largest, false)
}.filter(_._2).map(_._1)

or something like that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right; 0208ec4 should be more correct.

Copy link
Member

@adleong adleong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIOLI about factoring and testability

AsyncStream.fromFuture(f)
}
}
// Ignore any cases where we receive a resource version lower
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defining this as a method def increasingSubsequence[T <: Ordered[T]](stream: AsyncStream[T]): AsyncStream[T] would make the logic of this method easy to test (since you can just test it on an AsyncStream of numbers).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smart!

trait Watch[O <: KubeObject] extends Ordered[Watch[O]] {
def resourceVersion: Option[String]

private[Watch] def versionNum: Option[Long] = for {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the visibility scope here? Is this just equivalent to private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i just thought that – since Scala's visibility modifiers can be confusing – it was clearer to make the scope explicit?

@hawkw hawkw merged commit 35db806 into master Oct 24, 2017
@hawkw hawkw mentioned this pull request Oct 24, 2017
hawkw added a commit that referenced this pull request Oct 24, 2017
## 1.3.1 2017-10-24
* Kubernetes 
  * Fixed a failure to update routing data after restarting watches (#1674).
  * Ensured that Kubernetes API watch events earlier than the current state are ignored (#1681).
* Added support for Istio Mixer precondition checks (#1606).
* Removed spurious error message logging from Consul namer (#1682).
* Changed DNS SRV record namer to use system DNS resolver configuration (#1679).
* Added `timestampHeader` configuration to support New Relic request queue (#1672).
Tim-Brooks pushed a commit to Tim-Brooks/linkerd that referenced this pull request Dec 20, 2018
The success rate mini chart shows a colour based on SR, and also shows the SR
via the proportion of the chart that's filled out. If the success rate is 0% (as
in the VotePoop endpoint in the emojivoto demo), the chart would be zero 
percent filled out, causing it to be entirely gray. Really, it should be entirely
red, since zero SR is pretty bad.

Fix: fully fill the bar with red if there is a zero SR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants