Skip to content

Commit 3c27308

Browse files
jcrossleyjenkins
authored and
jenkins
committed
finagle-core: Rename c.t.f.context.Retries to c.t.f.context.Requeues
Problem `c.t.f.context.Retries` is not an accurate name because it actually stores the number of *requeues* a request has had. Solution Rename it to `c.t.f.context.Requeues`. Differential Revision: https://phabricator.twitter.biz/D1104878
1 parent aa73d41 commit 3c27308

File tree

14 files changed

+159
-110
lines changed

14 files changed

+159
-110
lines changed

CHANGELOG.rst

+8-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ Bug Fixes
3232

3333
* finagle-core: Failed recvAddress on Linux due to the remote peer resetting connection should now
3434
be properly seen as a `c.t.f.ChannelClosedException` instead of a
35-
`c.t.f.UnknownChannelException`. ``PHAB_ID=`D1104650`
35+
`c.t.f.UnknownChannelException`. ``PHAB_ID=`D1104650``
36+
37+
Breaking API Changes
38+
~~~~~~~~~~~~~~~~~~~~
39+
40+
* finagle-core: The `c.t.f.context.Retries` context has been renamed to `c.t.f.context.Requeues` to reflect what it
41+
actually contains -- the number of requeues a request has had (on the client immediately upstream). Requeues are
42+
retries on write exceptions (i.e. the original request was never sent to the server). ``PHAB_ID=`D1104878``
3643

3744
* finagle: Deposit budget once in MethodBuilder ``PHAB_ID=D1107653``
3845

doc/src/sphinx/Contexts.rst

+5-4
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,13 @@ Current request deadline
7272
``com.twitter.finagle.context.Deadline.current`` —
7373
A broadcast ``Context`` that represents when the request should be completed by.
7474

75-
Current retry attempt
75+
Current requeue attempt
7676
~~~~~~~~~~~~~~~~~~~~~
7777

78-
``com.twitter.finagle.context.Retries.current`` —
79-
A broadcast ``Context`` that represents which retry attempt this request is.
80-
Will have ``attempt`` set to 0 if the request is not a retry.
78+
``com.twitter.finagle.context.Requeues.current`` —
79+
A broadcast ``Context`` that represents which requeue attempt this request is.
80+
Requeues are retries on write exceptions (i.e. the original request was never sent to the server).
81+
Will have ``attempt`` set to 0 if the request is not a requeue.
8182

8283
Current TLS session
8384
~~~~~~~~~~~~~~~~~~~

finagle-base-http/src/main/scala/com/twitter/finagle/http/codec/context/HttpContext.scala

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.twitter.finagle.http.codec.context
22

33
import com.twitter.finagle.context.Contexts
4-
import com.twitter.finagle.http.{HeaderMap, Message}
4+
import com.twitter.finagle.http.HeaderMap
5+
import com.twitter.finagle.http.Message
56
import com.twitter.finagle.util.LoadService
6-
import com.twitter.logging.{Level, Logger}
7-
import com.twitter.util.{Return, Throw, Try}
7+
import com.twitter.logging.Level
8+
import com.twitter.logging.Logger
9+
import com.twitter.util.Return
10+
import com.twitter.util.Throw
11+
import com.twitter.util.Try
812
import scala.collection.mutable
913
import scala.util.control.NonFatal
1014

@@ -47,7 +51,7 @@ object HttpContext {
4751
private[this] val knownContextTypes: Array[HttpContext] = {
4852
Array[HttpContext](
4953
HttpDeadline,
50-
HttpRetries,
54+
HttpRequeues,
5155
HttpBackupRequest
5256
)
5357
}
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
package com.twitter.finagle.http.codec.context
22

3-
import com.twitter.finagle.context.{Contexts, Retries}
4-
import com.twitter.util.{Return, Throw, Try}
3+
import com.twitter.finagle.context.Contexts
4+
import com.twitter.finagle.context.Requeues
5+
import com.twitter.util.Return
6+
import com.twitter.util.Throw
7+
import com.twitter.util.Try
58
import scala.util.control.NonFatal
69

7-
private object HttpRetries extends HttpContext {
10+
private object HttpRequeues extends HttpContext {
811

9-
type ContextKeyType = Retries
10-
val key: Contexts.broadcast.Key[Retries] = Retries
12+
type ContextKeyType = Requeues
13+
val key: Contexts.broadcast.Key[Requeues] = Requeues
1114

12-
def toHeader(retries: Retries): String = {
13-
retries.attempt.toString
15+
def toHeader(requeues: Requeues): String = {
16+
requeues.attempt.toString
1417
}
1518

16-
def fromHeader(header: String): Try[Retries] = {
19+
def fromHeader(header: String): Try[Requeues] = {
1720
try {
18-
Return(Retries(header.toInt))
21+
Return(Requeues(header.toInt))
1922
} catch {
20-
case NonFatal(e) => Throw(new NumberFormatException)
23+
case NonFatal(_) => Throw(new NumberFormatException)
2124
}
2225
}
2326
}

finagle-base-http/src/test/scala/com/twitter/finagle/http/codec/context/HttpContextTest.scala

+23-17
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.twitter.finagle.http.codec.context
22

33
import com.twitter.conversions.DurationOps._
4-
import com.twitter.finagle.context.{BackupRequest, Contexts, Deadline, Retries}
5-
import com.twitter.finagle.http.{Message, Method, Request, Version}
4+
import com.twitter.finagle.context.BackupRequest
5+
import com.twitter.finagle.context.Contexts
6+
import com.twitter.finagle.context.Deadline
7+
import com.twitter.finagle.context.Requeues
8+
import com.twitter.finagle.http.Message
9+
import com.twitter.finagle.http.Method
10+
import com.twitter.finagle.http.Request
11+
import com.twitter.finagle.http.Version
612
import com.twitter.io.Buf
713
import com.twitter.util.Try
814
import org.scalatest.funsuite.AnyFunSuite
@@ -89,48 +95,48 @@ class HttpContextTest extends AnyFunSuite {
8995
}
9096
}
9197

92-
test("written request retries matches read request retries") {
98+
test("written request requeues matches read request requeues") {
9399
val m = newMsg()
94-
val writtenRetries = Retries(5)
95-
Contexts.broadcast.let(Retries, writtenRetries) {
100+
val writtenRequeues = Requeues(5)
101+
Contexts.broadcast.let(Requeues, writtenRequeues) {
96102
HttpContext.write(m)
97103

98-
// Clear Retries in the Context
99-
Contexts.broadcast.letClear(Retries) {
104+
// Clear Requeues in the Context
105+
Contexts.broadcast.letClear(Requeues) {
100106

101-
// Ensure the Retries was cleared
102-
assert(Retries.current == None)
107+
// Ensure the Requeues was cleared
108+
assert(Requeues.current == None)
103109

104110
HttpContext.read(m) {
105-
val readRetries = Retries.current.get
106-
assert(writtenRetries == readRetries)
111+
val readRequeues = Requeues.current.get
112+
assert(writtenRequeues == readRequeues)
107113
}
108114
}
109115
}
110116
}
111117

112118
test("headers are set/replaced, not added") {
113119
val m = newMsg()
114-
Contexts.broadcast.let(Retries, Retries(5)) {
120+
Contexts.broadcast.let(Requeues, Requeues(5)) {
115121
HttpContext.write(m)
116122
}
117123

118-
assert(m.headerMap.getAll(HttpRetries.headerKey).size == 1)
124+
assert(m.headerMap.getAll(HttpRequeues.headerKey).size == 1)
119125
HttpContext.read(m) {
120-
assert(Contexts.broadcast.get(HttpRetries.key) == Some(Retries(5)))
126+
assert(Contexts.broadcast.get(HttpRequeues.key) == Some(Requeues(5)))
121127
}
122128

123129
// and again...
124-
Contexts.broadcast.let(Retries, Retries(4)) {
130+
Contexts.broadcast.let(Requeues, Requeues(4)) {
125131
HttpContext.write(m)
126132
}
127133

128134
// Still just 1...
129-
assert(m.headerMap.getAll(HttpRetries.headerKey).size == 1)
135+
assert(m.headerMap.getAll(HttpRequeues.headerKey).size == 1)
130136

131137
// Should be the last entry written
132138
HttpContext.read(m) {
133-
assert(Contexts.broadcast.get(HttpRetries.key) == Some(Retries(4)))
139+
assert(Contexts.broadcast.get(HttpRequeues.key) == Some(Requeues(4)))
134140
}
135141
}
136142

finagle-base-http/src/test/scala/com/twitter/finagle/http/filter/ContextFilterTest.scala

+14-9
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,43 @@ package com.twitter.finagle.http.filter
22

33
import com.twitter.conversions.DurationOps._
44
import com.twitter.finagle.Service
5-
import com.twitter.finagle.context.{Contexts, Deadline, Retries}
5+
import com.twitter.finagle.context.Contexts
6+
import com.twitter.finagle.context.Deadline
7+
import com.twitter.finagle.context.Requeues
68
import com.twitter.finagle.http.codec.context.HttpContext
7-
import com.twitter.finagle.http.{Request, Response, Status}
8-
import com.twitter.util.{Await, Future}
9+
import com.twitter.finagle.http.Request
10+
import com.twitter.finagle.http.Response
11+
import com.twitter.finagle.http.Status
12+
import com.twitter.util.Await
13+
import com.twitter.util.Future
914
import org.scalatest.funsuite.AnyFunSuite
1015

1116
class ContextFilterTest extends AnyFunSuite {
1217

1318
test("parses Finagle-Ctx headers") {
1419
val writtenDeadline = Deadline.ofTimeout(5.seconds)
15-
val writtenRetries = Retries(5)
20+
val writtenRequeues = Requeues(5)
1621
val service =
1722
new ClientContextFilter[Request, Response] andThen
1823
new ServerContextFilter[Request, Response] andThen
1924
Service.mk[Request, Response] { req =>
2025
assert(Deadline.current.get == writtenDeadline)
21-
assert(Retries.current.get == writtenRetries)
26+
assert(Requeues.current.get == writtenRequeues)
2227
Future.value(Response())
2328
}
2429

2530
Contexts.broadcast.let(Deadline, writtenDeadline) {
26-
Contexts.broadcast.let(Retries, writtenRetries) {
31+
Contexts.broadcast.let(Requeues, writtenRequeues) {
2732
val req = Request()
2833
HttpContext.write(req)
2934

30-
// Clear the deadline/retries values in the context
35+
// Clear the deadline/requeues values in the context
3136
Contexts.broadcast.letClearAll {
3237
// ensure the deadline was cleared
3338
assert(Deadline.current == None)
3439

35-
// ensure the retries was cleared
36-
assert(Retries.current == None)
40+
// ensure the requeues was cleared
41+
assert(Requeues.current == None)
3742

3843
val rsp = Await.result(service(req))
3944
assert(rsp.status == Status.Ok)

finagle-core/src/main/scala/com/twitter/finagle/client/StackClient.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ object StackClient {
380380
stk.push(PrepFactory.module)
381381
stk.push(FactoryToService.module)
382382
stk.push(Retries.moduleRequeueable)
383-
stk.push(ClearContextValueFilter.module(context.Retries))
383+
stk.push(ClearContextValueFilter.module(context.Requeues))
384384
stk.push(ExceptionSourceFilter.module)
385385

386386
/*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.twitter.finagle.context
2+
3+
import com.twitter.io.Buf
4+
import com.twitter.io.BufByteWriter
5+
import com.twitter.io.ByteReader
6+
import com.twitter.util.Return
7+
import com.twitter.util.Throw
8+
import com.twitter.util.Try
9+
10+
/**
11+
* Requeues contains the number of times a request has been requeued.
12+
*
13+
* @param attempt which retry attempt this is. Will be 0
14+
* if the request is not a requeue.
15+
*/
16+
case class Requeues(attempt: Int)
17+
18+
/**
19+
* Note: The context id is "c.t.f.Retries" and not "c.t.f.Requeues" because we have renamed the
20+
* Retries context to Requeues (to reflect what it actually contains, which is the requeues), but we
21+
* don't want to break existing users/deployments using this context by changing the key.
22+
*/
23+
object Requeues extends Contexts.broadcast.Key[Requeues]("com.twitter.finagle.Retries") {
24+
25+
def current: Option[Requeues] =
26+
Contexts.broadcast.get(Requeues)
27+
28+
override def marshal(requeues: Requeues): Buf = {
29+
val bw = BufByteWriter.fixed(4)
30+
bw.writeIntBE(requeues.attempt)
31+
bw.owned()
32+
}
33+
34+
override def tryUnmarshal(buf: Buf): Try[Requeues] = {
35+
if (buf.length != 4) {
36+
Throw(
37+
new IllegalArgumentException(
38+
s"Could not extract Requeues from Buf. Length ${buf.length} but required 4"
39+
)
40+
)
41+
} else {
42+
val attempt: Int = ByteReader(buf).readIntBE()
43+
Return(Requeues(attempt))
44+
}
45+
}
46+
}

finagle-core/src/main/scala/com/twitter/finagle/context/Retries.scala

-37
This file was deleted.

finagle-core/src/main/scala/com/twitter/finagle/service/RequeueFilter.scala

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package com.twitter.finagle.service
22

33
import com.twitter.finagle.context.Contexts
44
import com.twitter.finagle.stats.StatsReceiver
5-
import com.twitter.finagle.tracing.{Annotation, Trace, TraceId}
6-
import com.twitter.finagle.{context, _}
5+
import com.twitter.finagle.tracing.Annotation
6+
import com.twitter.finagle.tracing.Trace
7+
import com.twitter.finagle.tracing.TraceId
8+
import com.twitter.finagle.context
9+
import com.twitter.finagle._
710
import com.twitter.util._
811

912
/**
@@ -66,7 +69,7 @@ private[finagle] class RequeueFilter[Req, Rep](
6669
retriesRemaining: Int,
6770
backoffs: Backoff
6871
): Future[Rep] = {
69-
Contexts.broadcast.let(context.Retries, context.Retries(attempt)) {
72+
Contexts.broadcast.let(context.Requeues, context.Requeues(attempt)) {
7073
val trace = Trace()
7174
val shouldTrace = attempt > 0 && trace.isActivelyTracing
7275
if (shouldTrace) {

finagle-core/src/test/scala/com/twitter/finagle/filter/ClearContextValueFilterTest.scala

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package com.twitter.finagle.filter
22

33
import com.twitter.conversions.DurationOps._
44
import com.twitter.finagle._
5-
import com.twitter.finagle.context.{Contexts, Retries}
5+
import com.twitter.finagle.context.Contexts
6+
import com.twitter.finagle.context.Requeues
67
import com.twitter.finagle.stack.nilStack
7-
import com.twitter.util.{Promise, Await, Future}
8+
import com.twitter.util.Promise
9+
import com.twitter.util.Await
10+
import com.twitter.util.Future
811
import org.scalatest.funsuite.AnyFunSuite
912

1013
class ClearContextValueFilterTest extends AnyFunSuite {
@@ -20,16 +23,16 @@ class ClearContextValueFilterTest extends AnyFunSuite {
2023
def make(next: ServiceFactory[Unit, Unit]) =
2124
new SimpleFilter[Unit, Unit] {
2225
def apply(req: Unit, service: Service[Unit, Unit]): Future[Unit] = {
23-
Contexts.broadcast.let(Retries, Retries(5)) {
24-
assert(Retries.current == Some(Retries(5)))
26+
Contexts.broadcast.let(Requeues, Requeues(5)) {
27+
assert(Requeues.current == Some(Requeues(5)))
2528
setContextFilterCalled.setDone()
2629
service(req)
2730
}
2831
}
2932
}.andThen(next)
3033
}
3134

32-
val clearContextFilter = ClearContextValueFilter.module[Unit, Unit](Retries)
35+
val clearContextFilter = ClearContextValueFilter.module[Unit, Unit](Requeues)
3336

3437
val verifyContextClearedFilter =
3538
new Stack.Module0[ServiceFactory[Unit, Unit]] {
@@ -38,7 +41,7 @@ class ClearContextValueFilterTest extends AnyFunSuite {
3841
def make(next: ServiceFactory[Unit, Unit]) =
3942
new SimpleFilter[Unit, Unit] {
4043
def apply(req: Unit, service: Service[Unit, Unit]): Future[Unit] = {
41-
assert(Retries.current == None)
44+
assert(Requeues.current == None)
4245
verifyContextClearedFilterCalled.setDone()
4346
service(req)
4447
}

0 commit comments

Comments
 (0)