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

Skip to content

Conversation

@hawkw
Copy link
Contributor

@hawkw hawkw commented Oct 16, 2017

As discussed in #1664 (comment), the New Relic request queue uses a X-Request-Start header with a timestamp to measure latency. I've added a filter that allows Linkerd to add such a header to outbound requests. I've added unit and end-to-end tests for this feature, and added the header configuration to the config docs.

@hawkw hawkw self-assigned this Oct 16, 2017
@hawkw hawkw requested a review from adleong October 16, 2017 23:55
}

/**
* Returns the target service requested based on the supplied [[Path]].
Copy link
Contributor Author

Choose a reason for hiding this comment

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

looks like Scalariform modified this and I committed it by mistake. will fix.

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.

I'm a bit confused about request header vs response header and how that end-to-end test passes.


val downstream = Downstream.mk("dog") {
req =>
req.headerMap.keys must contain ("x-request-start")
Copy link
Member

Choose a reason for hiding this comment

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

maybe also check that the value can be parsed as a long?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I originally had wanted to test using Time.withCurrentTimeAt but that wasn't practical in the e2e test; that seems like a good compromise.


val DefaultHeader: String = "X-Request-Start"

case class Param(header: String) {
Copy link
Member

Choose a reason for hiding this comment

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

I think this param should contain an Option[String] so that this filter can be disabled. (and it should be disabled by default)

*/
object TimestampHeaderFilter {

val DefaultHeader: String = "X-Request-Start"
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 we need this since this should be disabled by default

next: ServiceFactory[Request, Response]
): ServiceFactory[Request, Response] = {
val Param(header) = param
filter(header) andThen next
Copy link
Member

Choose a reason for hiding this comment

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

prefer to avoid infix notation

}

def filter(header: String): Filter[Request, Response, Request, Response] =
(req: Request, svc: Service[Request, Response]) => {
Copy link
Member

Choose a reason for hiding this comment

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

prefer Filter.mk or new Filter


val c = upstream(s)
try {
val resp = await(c(req))
Copy link
Member

Choose a reason for hiding this comment

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

to ensure that this request was even routed to the downstream correctly, should assert the status code is ok

val resp = await(c(req))
} finally {
await(c.close())
await(s.close())
Copy link
Member

Choose a reason for hiding this comment

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

close the downstream server too

def filter(header: String): Filter[Request, Response, Request, Response] =
(req: Request, svc: Service[Request, Response]) => {
val reqT = Time.now
svc(req).map { rsp =>
Copy link
Member

Choose a reason for hiding this comment

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

it looks like this puts the header on the response, not the request?

}

test("timestampHeader adds header") {
var headers: Option[HeaderMap] = None
Copy link
Member

Choose a reason for hiding this comment

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

I think this might have to be @volatile since it's shared across threads

/**
* Adds a timestamp header to a message.
*
* This is intended to be used for the New Relic request queue's
Copy link
Member

Choose a reason for hiding this comment

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

I think we can remove lines 10-11

import com.twitter.util.{Future, Time}

/**
* Adds a timestamp header to a message.
Copy link
Member

Choose a reason for hiding this comment

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

s/message/request

@hawkw
Copy link
Contributor Author

hawkw commented Oct 18, 2017

@adleong I think I've addressed all requested changes?

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.

⏲ 🚛 🖲

@hawkw hawkw merged commit 5cc68f1 into master Oct 18, 2017
@hawkw hawkw mentioned this pull request Oct 18, 2017
@hawkw hawkw added this to the 1.3.1 milestone Oct 20, 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).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants