Skip to content

Commit b2a7f4e

Browse files
yufangongjenkins
authored and
jenkins
committed
finagle-core: Make ServiceFactory#status abstract
Problem ServiceFactory#status being by default Open has been error-prone to let the wrapping service not closable. Solution Make the method abstract and always requires an implementation. JIRA Issues: CSL-12036 Differential Revision: https://phabricator.twitter.biz/D933288
1 parent 4169c63 commit b2a7f4e

File tree

32 files changed

+253
-72
lines changed

32 files changed

+253
-72
lines changed

CHANGELOG.rst

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ Breaking API Changes
4040

4141
* finagle-core: `Trace.recordLocalSpan` is `private[this]` and no longer `protected`. ``PHAB_ID=D912760``
4242

43+
* finagle-core: "ServiceFactory#status" is abstract and requires implementation in the inherited
44+
classes. ``PHAB_ID=D933288``
45+
4346
Runtime Behavior Changes
4447
~~~~~~~~~~~~~~~~~~~~~~~~
4548

finagle-benchmark/src/main/scala/com/twitter/finagle/loadbalancer/BalancerBench.scala

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ object BalancerBench {
2828
def apply(req: Unit): Future[Unit] = Future.Done
2929
})
3030
def close(when: Time): Future[Unit] = Future.Done
31+
32+
def status: Status = Status.Open
3133
}
3234

3335
def newActivity(num: Int): Activity[Vector[EndpointFactory[Unit, Unit]]] = {

finagle-benchmark/src/main/scala/com/twitter/finagle/loadbalancer/ServerFactory.scala

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package com.twitter.finagle.loadbalancer
22

3-
import com.twitter.finagle.{Address, ClientConnection, Service, Failure}
3+
import com.twitter.finagle.Address
4+
import com.twitter.finagle.ClientConnection
5+
import com.twitter.finagle.Service
6+
import com.twitter.finagle.Failure
7+
import com.twitter.finagle.Status
48
import com.twitter.finagle.stats.StatsReceiver
59
import com.twitter.finagle.util.DefaultTimer
6-
import com.twitter.util.{Duration, Future, Time}
10+
import com.twitter.util.Duration
11+
import com.twitter.util.Future
12+
import com.twitter.util.Time
713
import java.util.concurrent.atomic.AtomicInteger
814

915
private trait Server extends EndpointFactory[Unit, Unit] {
@@ -81,6 +87,7 @@ private object ServerFactory {
8187
def count: Long = _numRequests.get().toLong
8288
def apply(conn: ClientConnection): Future[Service[Unit, Unit]] = Future.value(service)
8389
def close(deadline: Time): Future[Unit] = Future.Done
90+
def status: Status = service.status
8491
override def toString: String = id
8592
}
8693
}

finagle-core/src/main/scala/com/twitter/finagle/ServiceFactory.scala

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package com.twitter.finagle
22

3-
import com.twitter.util.{Closable, Future, Return, Throw, Time}
3+
import com.twitter.util.Closable
4+
import com.twitter.util.Future
5+
import com.twitter.util.Return
6+
import com.twitter.util.Throw
7+
import com.twitter.util.Time
48

59
abstract class ServiceFactory[-Req, +Rep]
610
extends (ClientConnection => Future[Service[Req, Rep]])
@@ -66,7 +70,7 @@ abstract class ServiceFactory[-Req, +Rep]
6670
/**
6771
* The current availability [[Status]] of this ServiceFactory
6872
*/
69-
def status: Status = Status.Open
73+
def status: Status
7074

7175
/**
7276
* Return `true` if and only if [[status]] is currently [[Status.Open]].
@@ -104,6 +108,7 @@ object ServiceFactory {
104108
new ServiceFactory[Req, Rep] {
105109
def apply(_conn: ClientConnection): Future[Service[Req, Rep]] = f()
106110
def close(deadline: Time): Future[Unit] = Future.Done
111+
def status: Status = Status.Open
107112

108113
override def toString: String = s"${getClass.getName}(${f.toString()})"
109114
}

finagle-core/src/main/scala/com/twitter/finagle/pool/BalancingPool.scala

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ private[finagle] object BalancingPool {
101101
params)
102102

103103
def apply(conn: ClientConnection): Future[Service[Req, Rep]] = balancer()
104+
def status: Status = balancer.status
104105

105106
def close(deadline: Time): Future[Unit] =
106107
balancer

finagle-core/src/test/scala/com/twitter/finagle/FilterTest.scala

+13-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package com.twitter.finagle
22

33
import com.twitter.conversions.DurationOps._
4-
import com.twitter.finagle.service.{ConstantService, NilService}
5-
import com.twitter.util.{Await, Future, Promise, Time}
6-
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger}
4+
import com.twitter.finagle.service.ConstantService
5+
import com.twitter.finagle.service.NilService
6+
import com.twitter.util.Await
7+
import com.twitter.util.Future
8+
import com.twitter.util.Promise
9+
import com.twitter.util.Time
10+
import java.util.concurrent.atomic.AtomicBoolean
11+
import java.util.concurrent.atomic.AtomicInteger
712
import org.mockito.Matchers._
8-
import org.mockito.Mockito.{never, spy, times, verify}
13+
import org.mockito.Mockito.never
14+
import org.mockito.Mockito.spy
15+
import org.mockito.Mockito.times
16+
import org.mockito.Mockito.verify
917
import org.scalatest.funsuite.AnyFunSuite
1018

1119
class FilterTest extends AnyFunSuite {
@@ -24,6 +32,7 @@ class FilterTest extends AnyFunSuite {
2432
class PassThruServiceFactory extends ServiceFactory[Int, Int] {
2533
def apply(conn: ClientConnection): Future[Service[Int, Int]] = Future.value(constSvc)
2634
def close(deadline: Time): Future[Unit] = Future.Done
35+
def status: Status = Status.Open
2736
}
2837

2938
val constSvc = new ConstantService[Int, Int](Future.value(2))

finagle-core/src/test/scala/com/twitter/finagle/ResolverTest.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package com.twitter.finagle
22

3-
import com.twitter.util.{Future, Time, Var}
3+
import com.twitter.util.Future
4+
import com.twitter.util.Time
5+
import com.twitter.util.Var
46
import org.scalatest.funsuite.AnyFunSuite
57

68
object TestAddr {
79
case class StringFactory(s: String) extends ServiceFactory[Any, String] {
810
val svc = Service.const(Future.value(s))
911
override def apply(conn: ClientConnection) = Future.value(svc)
1012
override def close(deadline: Time) = Future.Done
13+
def status: Status = svc.status
1114
}
1215

1316
def apply(arg: String): Address = {

finagle-core/src/test/scala/com/twitter/finagle/ServiceFactoryTest.scala

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.twitter.finagle
22

3-
import com.twitter.finagle.service.{ConstantService, ServiceFactoryRef}
4-
import com.twitter.util.{Future, Time}
3+
import com.twitter.finagle.service.ConstantService
4+
import com.twitter.finagle.service.ServiceFactoryRef
5+
import com.twitter.util.Future
6+
import com.twitter.util.Time
57
import org.scalatest.funsuite.AnyFunSuite
68

79
class ServiceFactoryTest extends AnyFunSuite {
@@ -11,6 +13,8 @@ class ServiceFactoryTest extends AnyFunSuite {
1113
Future.value(new ConstantService[Int, Int](Future.value(7)))
1214

1315
def close(deadline: Time): Future[Unit] = Future.Done
16+
17+
def status: Status = Status.Open
1418
}
1519

1620
case class TestProxy(_self: ServiceFactory[Int, Int]) extends ServiceFactoryProxy(_self)

finagle-core/src/test/scala/com/twitter/finagle/ServiceTest.scala

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.twitter.finagle
22

33
import com.twitter.conversions.DurationOps._
4-
import com.twitter.finagle.service.{ConstantService, FailedService, NilService}
4+
import com.twitter.finagle.service.ConstantService
5+
import com.twitter.finagle.service.FailedService
6+
import com.twitter.finagle.service.NilService
57
import com.twitter.util._
68
import org.mockito.Matchers._
7-
import org.mockito.Mockito.{times, verify, when}
9+
import org.mockito.Mockito.times
10+
import org.mockito.Mockito.verify
11+
import org.mockito.Mockito.when
812
import org.mockito.invocation.InvocationOnMock
913
import org.mockito.stubbing.Answer
1014
import org.scalatestplus.mockito.MockitoSugar
@@ -17,6 +21,8 @@ object ServiceTest {
1721
Future.value(new ConstantService[Int, Int](Future.value(2)))
1822

1923
def close(deadline: Time): Future[Unit] = Future.Done
24+
25+
def status: Status = Status.Open
2026
}
2127

2228
def await[A](fa: Future[A], timeout: Duration = 5.seconds): A =
@@ -110,6 +116,7 @@ class ServiceTest extends AnyFunSuite with MockitoSugar {
110116
def apply(conn: ClientConnection): Future[Service[Int, Int]] = Future.value(constSvc)
111117
def close(deadline: Time): Future[Unit] = Future.Done
112118
override def toString: String = "ServiceFactory"
119+
def status: Status = constSvc.status
113120
}
114121
assert(svcFactoryWithToString.toString == "ServiceFactory")
115122
}
@@ -157,6 +164,7 @@ class ServiceTest extends AnyFunSuite with MockitoSugar {
157164
val factory = new ServiceFactory[String, String] {
158165
def apply(conn: ClientConnection) = Future.value(service)
159166
def close(deadline: Time) = Future.Done
167+
def status: Status = service.status
160168
}
161169

162170
verify(service, times(0)).close(any)

finagle-core/src/test/scala/com/twitter/finagle/client/DefaultPoolTest.scala

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
package com.twitter.finagle.client
22

3-
import com.twitter.finagle.{Status, ClientConnection, Service, ServiceFactory}
3+
import com.twitter.finagle.Status
4+
import com.twitter.finagle.ClientConnection
5+
import com.twitter.finagle.Service
6+
import com.twitter.finagle.ServiceFactory
47
import com.twitter.finagle.stats.InMemoryStatsReceiver
5-
import com.twitter.util.{Return, Await, Future, Time}
8+
import com.twitter.util.Return
9+
import com.twitter.util.Await
10+
import com.twitter.util.Future
11+
import com.twitter.util.Time
612
import org.scalatest.funsuite.AnyFunSuite
713

814
class DefaultPoolTest extends AnyFunSuite {
@@ -11,6 +17,8 @@ class DefaultPoolTest extends AnyFunSuite {
1117
Future.value(new MockService())
1218

1319
override def close(deadline: Time): Future[Unit] = Future.Done
20+
21+
def status: Status = Status.Open
1422
}
1523

1624
class MockService extends Service[Unit, Unit] {

finagle-core/src/test/scala/com/twitter/finagle/client/ExceptionRemoteInfoFactoryTest.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import com.twitter.finagle._
55
import com.twitter.finagle.context.RemoteInfo
66
import com.twitter.finagle.service.FailedService
77
import com.twitter.finagle.tracing.Trace
8-
import com.twitter.util.{Await, Future, Time}
8+
import com.twitter.util.Await
9+
import com.twitter.util.Future
10+
import com.twitter.util.Time
911
import java.net.InetSocketAddress
1012
import org.scalatestplus.mockito.MockitoSugar
1113
import org.scalatest.funsuite.AnyFunSuite
@@ -17,6 +19,7 @@ class ExceptionRemoteInfoFactoryTest extends AnyFunSuite with MockitoSugar {
1719
val failingFactory = new ServiceFactory[String, String] {
1820
def apply(conn: ClientConnection): Future[Nothing] = Future.exception(new HasRemoteInfo {})
1921
def close(deadline: Time): Future[Unit] = Future.Done
22+
def status: Status = Status.Open
2023
}
2124

2225
val downstreamAddr = new InetSocketAddress("1.2.3.4", 100)

finagle-core/src/test/scala/com/twitter/finagle/client/MethodBuilderTest.scala

+1
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ class MethodBuilderTest
611611
Future.value(svc)
612612
def close(deadline: Time): Future[Unit] =
613613
svc.close(deadline)
614+
def status: Status = Status.Open
614615
}
615616
val stk = Stack.leaf(Stack.Role("test"), svcFac)
616617
val stackClient = TestStackClient(stk, Stack.Params.empty)

finagle-core/src/test/scala/com/twitter/finagle/client/StackClientTest.scala

+6
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ abstract class AbstractStackClientTest
256256
})
257257

258258
def close(deadline: Time) = Future.Done
259+
def status: Status = Status.Open
259260
}
260261

261262
val stack = StackClient
@@ -300,6 +301,7 @@ abstract class AbstractStackClientTest
300301
})
301302

302303
def close(deadline: Time) = Future.Done
304+
def status: Status = Status.Open
303305
}
304306

305307
val stack = StackClient
@@ -419,6 +421,7 @@ abstract class AbstractStackClientTest
419421
Failure.rejected("unable to establish session")
420422
)
421423
def close(deadline: Time) = Future.Done
424+
def status: Status = Status.Open
422425
}
423426

424427
intercept[Failure] { await(cl()) }
@@ -432,6 +435,7 @@ abstract class AbstractStackClientTest
432435
Failure("don't restart this!")
433436
)
434437
def close(deadline: Time) = Future.Done
438+
def status: Status = Status.Open
435439
}
436440

437441
intercept[Failure] { await(cl()) }
@@ -474,6 +478,7 @@ abstract class AbstractStackClientTest
474478

475479
def apply(conn: ClientConnection): Future[Service[Unit, Unit]] = Future.value(service)
476480
def close(deadline: Time): Future[Unit] = Future.Done
481+
def status: Status = service.status
477482
}
478483

479484
val fac1 = new CountFactory
@@ -635,6 +640,7 @@ abstract class AbstractStackClientTest
635640
}
636641

637642
def close(deadline: Time): Future[Unit] = Future.Done
643+
def status: Status = Status.worst(endpoint1.status, endpoint2.status)
638644
}
639645
)
640646
)

finagle-core/src/test/scala/com/twitter/finagle/factory/ServiceFactoryCacheTest.scala

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ package com.twitter.finagle.factory
22

33
import com.twitter.conversions.DurationOps._
44
import com.twitter.finagle._
5-
import com.twitter.util.{Future, MockTimer, Time, Timer, Await}
5+
import com.twitter.util.Future
6+
import com.twitter.util.MockTimer
7+
import com.twitter.util.Time
8+
import com.twitter.util.Timer
9+
import com.twitter.util.Await
610
import org.scalatestplus.mockito.MockitoSugar
711
import org.scalatest.funsuite.AnyFunSuite
812

@@ -31,6 +35,8 @@ class ServiceFactoryCacheTest extends AnyFunSuite with MockitoSugar {
3135
factories -= i
3236
Future.Done
3337
}
38+
39+
def status: Status = Status.Open
3440
}
3541
}
3642

finagle-core/src/test/scala/com/twitter/finagle/loadbalancer/aperture/WeightedApertureTest.scala

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ abstract class BaseWeightedApertureTest(manageWeights: Boolean)
6464
})
6565

6666
def close(when: Time): Future[Unit] = Future.Done
67+
def status: Status = Status.Open
6768
}
6869
}
6970

finagle-core/src/test/scala/com/twitter/finagle/naming/BindingFactoryTest.scala

+3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ case class Factory(i: Int) extends EndpointFactory[String, String] {
6262
override def close(deadline: Time): Future[Unit] = {
6363
Future.Done
6464
}
65+
def status: Status = Status.Open
6566
}
6667

6768
class BindingFactoryTest extends AnyFunSuite with MockitoSugar with BeforeAndAfter {
@@ -112,6 +113,7 @@ class BindingFactoryTest extends AnyFunSuite with MockitoSugar with BeforeAndAft
112113
tcOpt.foreach(_.advance(1234.microseconds))
113114
Future.value(Service.mk { _ => Future.value(bound.addr) })
114115
}
116+
def status: Status = Status.Open
115117

116118
def close(deadline: Time) = {
117119
closes += 1
@@ -237,6 +239,7 @@ class BindingFactoryTest extends AnyFunSuite with MockitoSugar with BeforeAndAft
237239
Future.exception(new NoBrokersAvailableException("/foo/bar"))
238240

239241
def close(deadline: Time) = Future.Done
242+
def status: Status = Status.Open
240243
}
241244
},
242245
Timer.Nil

finagle-core/src/test/scala/com/twitter/finagle/naming/NameTreeFactoryTest.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class NameTreeFactoryTest
3232
Future.value(null)
3333
}
3434
def close(deadline: Time) = Future.Done
35+
36+
def status: Status = Status.Open
3537
},
3638
Timer.Nil
3739
)
@@ -295,7 +297,7 @@ class NameTreeFactoryTest
295297
def apply(conn: ClientConnection): Future[Service[Unit, Unit]] =
296298
Future.value(Service.const(Future.Done))
297299
def close(deadline: Time) = Future.Done
298-
override def status = Status.Open
300+
def status = Status.Open
299301
},
300302
Timer.Nil
301303
)

finagle-core/src/test/scala/com/twitter/finagle/pool/BalancingPoolTest.scala

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import com.twitter.conversions.DurationOps._
44
import com.twitter.finagle._
55
import com.twitter.finagle.client.Transporter
66
import com.twitter.finagle.service.FailingFactory
7-
import com.twitter.util.{Await, Awaitable, Future, Time}
8-
import java.net.{InetAddress, InetSocketAddress}
7+
import com.twitter.util.Await
8+
import com.twitter.util.Awaitable
9+
import com.twitter.util.Future
10+
import com.twitter.util.Time
11+
import java.net.InetAddress
12+
import java.net.InetSocketAddress
913
import org.scalatest.funsuite.AnyFunSuite
1014

1115
object BalancingPoolTest {
@@ -39,6 +43,7 @@ object BalancingPoolTest {
3943
closes += 1
4044
Future.Done
4145
}
46+
def status: Status = Status.Open
4247
}
4348
}
4449
}

0 commit comments

Comments
 (0)