com.twitter.util.Duration Scala Examples
The following examples show how to use com.twitter.util.Duration.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: Settings.scala From diffy with GNU Affero General Public License v3.0 | 5 votes |
package ai.diffy.proxy import java.net.InetSocketAddress import ai.diffy.util.ResourceMatcher import ai.diffy.util.ServiceInstance import com.twitter.util.{Duration, StorageUnit, Try} case class Settings( datacenter: String, servicePort:InetSocketAddress, candidate: String, primary: String, secondary: String, protocol: String, clientId: String, pathToThriftJar: String, serviceClass: String, serviceName: String, apiRoot: String, enableThriftMux: Boolean, relativeThreshold: Double, absoluteThreshold: Double, teamEmail: String, emailDelay: Duration, rootUrl: String, allowHttpSideEffects: Boolean, excludeHttpHeadersComparison: Boolean, skipEmailsWhenNoErrors: Boolean, httpsPort: String, useFramedThriftTransport: Boolean, hostname: String = Try(java.lang.management.ManagementFactory.getRuntimeMXBean.getName.split("@")(1)).getOrElse("unknown"), user: String = Try(sys.env("USER")).getOrElse("unknown"), resourceMatcher: Option[ResourceMatcher] = None, responseMode: ServiceInstance = ServiceInstance.Primary, maxResponseSize: StorageUnit, maxHeaderSize: StorageUnit)
Example 2
Source File: Server.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.example import cats.effect.ExitCode import cats.effect.concurrent.Ref import cats.instances.list._ import cats.syntax.foldable._ import cats.syntax.semigroupk._ import com.twitter.finagle import com.twitter.finagle.http.Response import com.twitter.util.{Await, Duration} import monix.eval.{Task, TaskApp} import ru.tinkoff.tschema.example.sample.SampleModule import ru.tinkoff.tschema.finagle.RunHttp import tofu.Void object Server extends TaskApp { def modules[H[_]]: List[ExampleModule[Http]] = List( new Greeting[Http, Example](), new SampleModule[Http, Example](), new FiltersModule(), new FormFieldsModule(), new MultiParameters(), new ProxyModule(), new VersionModule(), new Authorize ) val svc: Http[Response] = modules.foldMapK(_.route) <+> ExampleSwagger.route val server = for { srv <- RunHttp.run[Example](svc) list <- Example.delay(finagle.Http.serve("0.0.0.0:9191", srv)) _ <- Example.delay(println(s"started at ${list.boundAddress}")) _ <- Example.delay(Await.ready(list, Duration.Top)).fork res <- Example.fromTask(Task.never[Void]) } yield res def run(args: List[String]): Task[ExitCode] = for { ref <- Ref[Task].of(0) _ <- server .onErrorHandle(ex => println(ex.getMessage)) .run(ExampleEnv("lol", ref)) } yield ExitCode.Success }
Example 3
Source File: Server.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.example import Swagger._ import cats.effect.ExitCode import cats.effect.concurrent.Ref import cats.instances.list._ import cats.syntax.foldable._ import cats.syntax.semigroupk._ import com.twitter.finagle import finagle.{Http, http} import com.twitter.finagle.http.Response import com.twitter.util.{Await, Duration} import monix.eval.{Task, TaskApp} import ru.tinkoff.tschema.finagle.Runnable import tofu.Void object Server extends TaskApp { implicit val greeting: Greeting[Example] = Greeting[Example] val modules: List[ExampleModule] = List(GreetingModule[Example, Http](), TestModule, FiltersModule, FormFieldsModule, MultiParameters, ProxyModule, VersionModule, Authorize) val svc: Http[Response] = modules.foldMapK(_.route) <+> Swagger.route val server = for { srv <- Runnable.run[Example](svc) list <- Example.delay(finagle.Http.serve("0.0.0.0:9191", srv)) _ <- Example.delay(println(s"started at ${list.boundAddress}")) _ <- Example.delay(Await.ready(list, Duration.Top)).fork res <- Example.fromTask(Task.never[Void]) } yield res def run(args: List[String]): Task[ExitCode] = for { ref <- Ref[Task].of(0) _ <- server .onErrorHandle(ex => println(ex.getMessage)) .run(ExampleEnv("lol", ref)) } yield ExitCode.Success }
Example 4
Source File: Server.scala From typed-schema with Apache License 2.0 | 5 votes |
package ru.tinkoff.tschema.example import ExampleSwagger._ import cats.instances.list._ import cats.syntax.foldable._ import cats.syntax.semigroupk._ import com.twitter.finagle.{Http => FHttp} import com.twitter.finagle.http.Response import com.twitter.util.{Await, Duration} import ru.tinkoff.tschema.finagle.RunHttp import zio.blocking.Blocking import zio.console._ import zio.{blocking => _, _} object Server extends App { val modules: List[ExampleModule] = List( Greeting, TestModule, FiltersModule, FormFieldsModule, MultiParameters, ProxyModule, VersionModule, Authorize, ReceiveModule ) val svc: Http[Response] = modules.foldMapK(_.route) <+> ExampleSwagger.route val server = for { srv <- RunHttp.run[Example](svc) list <- ZIO.effect(FHttp.serve("0.0.0.0:9191", srv)) _ <- putStr(s"started at ${list.boundAddress}") _ <- ZIO.effect(Await.ready(list, Duration.Top)).fork res <- ZIO.never } yield res val layer: URLayer[Blocking with Console, FullEnv] = ZLayer.identity[Blocking with Console] ++ ExampleEnv.live def run(args: List[String]): URIO[Blocking with Console, Int] = layer.build.use(r => server.catchAll(ex => putStr(ex.getMessage)).provide(r)) as 0 }
Example 5
Source File: HttpFeatureTest.scala From diffy with GNU Affero General Public License v3.0 | 5 votes |
package ai.diffy import java.net.ServerSocket import ai.diffy.examples.http.ExampleServers import ai.diffy.proxy.DifferenceProxy import com.google.common.collect.ImmutableMap import com.google.inject.Stage import com.twitter.finagle.Http import com.twitter.finagle.http.Status import com.twitter.finagle.util.DefaultTimer import com.twitter.finatra.http.EmbeddedHttpServer import com.twitter.inject.Test import com.twitter.util.{Await, Duration, Future, FuturePool} class HttpFeatureTest extends Test { def getPort(): Int = { val s = new ServerSocket(0) val port = s.getLocalPort s.close() port } val env@Seq(p,s,c,d) = Seq.fill(4)(getPort()) val environment = FuturePool.unboundedPool(ExampleServers.main(env.take(3).map(_.toString).toArray)) val diffy = new MainService lazy val differenceProxy = diffy.injector.instance[DifferenceProxy] val server = new EmbeddedHttpServer( twitterServer = diffy, flags = Map( "proxy.port" -> s":$d", "candidate" -> s"localhost:$c", "master.primary" -> s"localhost:$p", "master.secondary" -> s"localhost:$s", "serviceName" -> "myHttpService", "service.protocol" -> "http", "summary.email" ->"test" ), stage = Stage.PRODUCTION ) test("verify startup") { server.assertHealthy() } test("verify DifferenceCollector") { assert(differenceProxy.collector.fields.isEmpty) Await.result(Http.fetchUrl(s"http://localhost:$d/json?Twitter").liftToTry) var tries = 0 while(differenceProxy.outstandingRequests.get() > 0 && tries < 10) { Await.result(Future.sleep(Duration.fromSeconds(1))(DefaultTimer.twitter)) tries = tries + 1 } assert(!differenceProxy.collector.fields.isEmpty) } test("verify present differences via API") { val response = Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/undefined_endpoint/stats")) assertResult(Status.Ok)(response.status) assert(response.getContentString().contains(""""differences":1""")) } test("verify absent endpoint in API") { val response = Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/json/stats")) assertResult(Status.Ok)(response.status) assertResult("""{"error":"key not found: json"}""")(response.getContentString()) } Seq( "/api/1/overview", "/api/1/report", "/api/1/endpoints", "/api/1/endpoints/json/stats", "/api/1/endpoints/json/fields/result.200.values.value.name.PrimitiveDifference/results", "/api/1/endpoints/json/fields/result.200.values.value.name.PrimitiveDifference/results/0" ) foreach { endpoint => test(s"ping ${endpoint}") { val response = Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}${endpoint}")) assertResult(Status.Ok)(response.status) } } }
Example 6
Source File: DifferenceStatsMonitorSpec.scala From diffy with GNU Affero General Public License v3.0 | 5 votes |
package ai.diffy.workflow import ai.diffy.ParentSpec import ai.diffy.analysis.{DifferenceCounter, EndpointMetadata, RawDifferenceCounter} import com.twitter.finagle.stats.InMemoryStatsReceiver import com.twitter.util.{Duration, Future, MockTimer, Time} import org.junit.runner.RunWith import org.mockito.Mockito._ import org.scalatest.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) class DifferenceStatsMonitorSpec extends ParentSpec { describe("DifferenceStatsMonitor"){ val diffCounter = mock[DifferenceCounter] val metadata = new EndpointMetadata { override val differences = 0 override val total = 0 } val endpoints = Map("endpointName" -> metadata) when(diffCounter.endpoints) thenReturn Future.value(endpoints) val stats = new InMemoryStatsReceiver val timer = new MockTimer val monitor = new DifferenceStatsMonitor(RawDifferenceCounter(diffCounter), stats, timer) it("must add gauges after waiting a minute"){ Time.withCurrentTimeFrozen { tc => monitor.schedule() timer.tasks.size must be(1) stats.gauges.size must be(0) tc.advance(Duration.fromMinutes(1)) timer.tick() timer.tasks.size must be(1) stats.gauges.size must be(2) stats.gauges.keySet map { _.takeRight(2) } must be(Set(Seq("endpointName", "total"), Seq("endpointName", "differences"))) } } } }
Example 7
Source File: TestHelper.scala From diffy with GNU Affero General Public License v3.0 | 5 votes |
package ai.diffy import java.net.InetSocketAddress import ai.diffy.analysis._ import ai.diffy.compare.Difference import ai.diffy.proxy._ import ai.diffy.util.ServiceInstance import com.twitter.util.{Duration, StorageUnit} import org.scalatest.mock.MockitoSugar object TestHelper extends MockitoSugar { lazy val testSettings = Settings( datacenter = "test", servicePort = new InetSocketAddress(9999), candidate = "candidate", primary = "primary", secondary = "secondary", protocol = "test", clientId = "test", pathToThriftJar = "test", serviceClass = "test", serviceName = "test", apiRoot = "test", enableThriftMux = false, relativeThreshold = 0.0, absoluteThreshold = 0.0, teamEmail = "test", emailDelay = Duration.fromSeconds(0), rootUrl = "test", allowHttpSideEffects = true, excludeHttpHeadersComparison = true, skipEmailsWhenNoErrors = false, httpsPort = "443", useFramedThriftTransport = false, responseMode = ServiceInstance.Primary, maxHeaderSize = StorageUnit.fromKilobytes(32), maxResponseSize = StorageUnit.fromMegabytes(5) ) def makeEmptyJoinedDifferences = { val rawCounter = RawDifferenceCounter(new InMemoryDifferenceCounter()) val noiseCounter = NoiseDifferenceCounter(new InMemoryDifferenceCounter()) JoinedDifferences(rawCounter, noiseCounter) } def makePopulatedJoinedDifferences(endpoint : String, diffs : Map[String, Difference]) = { val rawCounter = RawDifferenceCounter(new InMemoryDifferenceCounter()) val noiseCounter = NoiseDifferenceCounter(new InMemoryDifferenceCounter()) val data = new InMemoryEndpointMetadata() data.add(diffs) rawCounter.counter.asInstanceOf[InMemoryDifferenceCounter].endpointsMap += (endpoint -> data) JoinedDifferences(rawCounter, noiseCounter) } }
Example 8
Source File: ThriftFeatureTest.scala From diffy with GNU Affero General Public License v3.0 | 5 votes |
package ai.diffy import java.io.{File, FileOutputStream} import java.net.ServerSocket import java.nio.file.Files import java.util.zip.{ZipEntry, ZipOutputStream} import ai.diffy.examples.thrift.ExampleServers import ai.diffy.proxy.DifferenceProxy import ai.diffy.thriftscala.Adder import com.google.inject.Stage import com.twitter.finagle.http.Status import com.twitter.finagle.util.DefaultTimer import com.twitter.finagle.{Http, ThriftMux} import com.twitter.finatra.http.EmbeddedHttpServer import com.twitter.inject.Test import com.twitter.util.{Await, Duration, Future, FuturePool} import scala.io.Source class ThriftFeatureTest extends Test { def getPort(): Int = { val s = new ServerSocket(0) val port = s.getLocalPort s.close() port } val env@Seq(p,s,c,d) = Seq.fill(4)(getPort()) val environment = FuturePool.unboundedPool(ExampleServers.main(env.take(3).map(_.toString).toArray)) val diffy = new MainService lazy val differenceProxy = diffy.injector.instance[DifferenceProxy] val thriftFile = new File("src/test/thrift/example.thrift") val data = Source.fromInputStream(Files.newInputStream(thriftFile.toPath), "UTF-8").mkString val thriftJar = Files.createTempFile("thrift", "jar") thriftJar.toFile.deleteOnExit() val out = new ZipOutputStream(new FileOutputStream(thriftJar.toFile)) out.putNextEntry(new ZipEntry(thriftFile.getAbsolutePath)) out.write(data.getBytes) out.closeEntry() out.close() val server = new EmbeddedHttpServer( twitterServer = diffy, flags = Map( "proxy.port" -> s":$d", "candidate" -> s"localhost:$c", "master.primary" -> s"localhost:$p", "master.secondary" -> s"localhost:$s", "serviceName" -> "myThriftService", "service.protocol" -> "thrift", "thrift.jar" -> thriftJar.toAbsolutePath.toString, "thrift.serviceClass" -> "Adder", "summary.email" -> "test" ), stage = Stage.PRODUCTION ) val client = ThriftMux.client.build[Adder.MethodPerEndpoint](s"localhost:$d") test("verify startup") { server.assertHealthy() } test("verify DifferenceCollector") { assert(differenceProxy.collector.fields.isEmpty) Await.result(client.add(1, 1).liftToTry) var tries = 0 while(differenceProxy.outstandingRequests.get() > 0 && tries < 10) { Await.result(Future.sleep(Duration.fromSeconds(1))(DefaultTimer)) tries = tries + 1 } assert(!differenceProxy.collector.fields.isEmpty) } test("verify present differences via API") { val response = Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/add/stats")) assertResult(Status.Ok)(response.status) assert(response.getContentString().contains(""""differences":1""")) } test("verify absent endpoint in API") { val response = Await.result(Http.fetchUrl(s"http://${server.externalHttpHostAndPort}/api/1/endpoints/subtract/stats")) assertResult(Status.Ok)(response.status) assertResult("""{"error":"key not found: subtract"}""")(response.getContentString()) } }
Example 9
Source File: Workflow.scala From diffy with GNU Affero General Public License v3.0 | 5 votes |
package ai.diffy.workflow import ai.diffy.analysis.{EndpointMetadata, RawDifferenceCounter} import ai.diffy.util.EmailSender import com.twitter.finagle.stats.StatsReceiver import com.twitter.finagle.util.DefaultTimer import com.twitter.logging.Logger import com.twitter.util.{Duration, Memoize, Time, Timer} import javax.inject.Inject trait Workflow { val log: Logger = Logger(classOf[Workflow]) val emailSender = new EmailSender(log) val delay: Duration val timer: Timer def run(start: Time): Unit def schedule(): Unit = { val start = Time.now log.info(s"Scheduling ${getClass.getName} at $start") timer.doLater(delay) { run(start) } } } class DifferenceStatsMonitor @Inject()( diffCounter: RawDifferenceCounter, stats: StatsReceiver, override val timer: Timer = DefaultTimer.twitter) extends Workflow { val delay = Duration.fromMinutes(1) val scope = stats.scope("raw").scope("endpoints") private[this] val addGauges = Memoize[(String, EndpointMetadata), Unit] { case (endpoint, meta) => scope.scope(endpoint).provideGauge("total"){ meta.total } scope.scope(endpoint).provideGauge("differences"){ meta.differences } } override def run(start: Time) = { diffCounter.counter.endpoints foreach { endPoints => endPoints map { addGauges } } } override def schedule() = { val start = Time.now timer.schedule(delay) { run(start) } } }
Example 10
Source File: ConstFuture.scala From arrows with Apache License 2.0 | 5 votes |
package arrows.twitter import com.twitter.util.Future import com.twitter.util.Try import com.twitter.util.Awaitable import com.twitter.util.Duration import com.twitter.util.Return import scala.runtime.NonLocalReturnControl import com.twitter.concurrent.Scheduler import com.twitter.util.FutureNonLocalReturnControl import com.twitter.util.Local import com.twitter.util.Monitor import scala.util.control.NonFatal import com.twitter.util.Promise import com.twitter.util.Throw trait ConstFuture[T] extends Future[T] { final def isReady(implicit permit: Awaitable.CanAwait): Boolean = true override final def ready(timeout: Duration)(implicit permit: Awaitable.CanAwait) = this final def poll: Option[com.twitter.util.Try[T]] = Some(toTry) protected def toTry: Try[T] final def respond(k: Try[T] => Unit): Future[T] = { val saved = Local.save() Scheduler.submit(new Runnable { def run(): Unit = { val current = Local.save() Local.restore(saved) try k(toTry) catch Monitor.catcher finally Local.restore(current) } }) this } final def raise(interrupt: Throwable): Unit = () final def transform[B](f: Try[T] => Future[B]): Future[B] = { val p = new Promise[B] // see the note on `respond` for an explanation of why `Scheduler` is used. val saved = Local.save() Scheduler.submit(new Runnable { def run(): Unit = { val current = Local.save() Local.restore(saved) val computed = try f(toTry) catch { case e: NonLocalReturnControl[_] => Future.exception(new FutureNonLocalReturnControl(e)) case NonFatal(e) => Future.exception(e) case t: Throwable => Monitor.handle(t) throw t } finally Local.restore(current) p.become(computed) } }) p } } class ReturnFuture[T](r: T) extends ConstFuture[T] { override final def result(timeout: Duration)(implicit permit: Awaitable.CanAwait): T = r override final def toTry = Return(r) } class ThrowFuture[T](ex: Throwable) extends ConstFuture[T] { override final def result(timeout: Duration)(implicit permit: Awaitable.CanAwait): T = throw ex override final def toTry = Throw(ex) }
Example 11
Source File: TimeoutError.scala From cosmos with Apache License 2.0 | 5 votes |
package com.mesosphere.cosmos.error import com.twitter.util.Duration import io.circe.Encoder import io.circe.JsonObject import io.circe.generic.semiauto.deriveEncoder import com.mesosphere.cosmos.circe.Encoders._ final case class TimeoutError( operation: String, destination: String, timeout: Duration ) extends CosmosError { override def data: Option[JsonObject] = CosmosError.deriveData(this) override def message: String = s"$operation timed out on $destination" + s" after ${timeout.inSeconds} seconds" } object TimeoutError { implicit val encoder: Encoder[TimeoutError] = deriveEncoder }
Example 12
Source File: RpcChannelImpl.scala From finagle-protobuf with Apache License 2.0 | 5 votes |
package com.twitter.finagle.protobuf.rpc.impl import java.net.InetSocketAddress import com.google.protobuf.Descriptors.MethodDescriptor import com.google.protobuf.RpcCallback import com.google.protobuf.Message import com.google.protobuf.RpcChannel import com.google.protobuf.RpcController import com.google.protobuf.Service import java.util.logging.Logger import com.twitter.util.Duration import com.twitter.util.FuturePool import com.twitter.finagle.builder.ClientBuilder import java.util.concurrent.ExecutorService import com.twitter.finagle.protobuf.rpc.RpcControllerWithOnFailureCallback import com.twitter.finagle.protobuf.rpc.channel.ProtoBufCodec import com.twitter.finagle.ChannelClosedException import com.twitter.finagle.protobuf.rpc.Util import com.twitter.finagle.protobuf.rpc.ExceptionResponseHandler class RpcChannelImpl(cb: ClientBuilder[(String, Message), (String, Message), Any, Any, Any], s: Service, handler: ExceptionResponseHandler[Message], executorService: ExecutorService) extends RpcChannel { private val log = Logger.getLogger(getClass.toString) private val futurePool = FuturePool(executorService) private val client: com.twitter.finagle.Service[(String, Message), (String, Message)] = cb .codec(new ProtoBufCodec(s)) .unsafeBuild() def callMethod(m: MethodDescriptor, controller: RpcController, request: Message, responsePrototype: Message, done: RpcCallback[Message]): Unit = { // retries is a workaround for ChannelClosedException raised when servers shut down. val retries = 3 callMethod(m, controller, request, responsePrototype, done, retries) } def callMethod(m: MethodDescriptor, controller: RpcController, request: Message, responsePrototype: Message, done: RpcCallback[Message], retries: Int): Unit = { Util.log("Request", m.getName(), request) val req = (m.getName(), request) client(req) onSuccess { result => Util.log("Response", m.getName(), result._2) futurePool({ handle(done, controller, result._2) }) } onFailure { e => log.warning("#callMethod# Failed. "+ e.getMessage) e match { case cc: ChannelClosedException => if (retries > 1) { log.warning("#callMethod# Retrying.") callMethod(m, controller, request, responsePrototype, done, retries - 1); } else { controller.asInstanceOf[RpcControllerWithOnFailureCallback].setFailed(e) } case _ => controller.asInstanceOf[RpcControllerWithOnFailureCallback].setFailed(e) } } } def handle(done: RpcCallback[Message], controller: RpcController, m: Message) { if (handler.canHandle(m)) { controller.asInstanceOf[RpcControllerWithOnFailureCallback].setFailed(handler.handle(m)) } else { done.run(m) } } def release() { client.close() } }
Example 13
Source File: RpcFactoryImpl.scala From finagle-protobuf with Apache License 2.0 | 5 votes |
package com.twitter.finagle.protobuf.rpc.impl import com.twitter.finagle.protobuf.rpc.RpcFactory import com.twitter.finagle.protobuf.rpc.RpcControllerWithOnFailureCallback import com.twitter.finagle.protobuf.rpc.RpcServer import com.twitter.finagle.builder.ServerBuilder import com.twitter.finagle.builder.ClientBuilder import com.twitter.util.Duration import com.google.protobuf.RpcController import com.google.protobuf.RpcChannel import com.google.protobuf.Message import com.google.protobuf.Service import java.util.concurrent.ExecutorService import com.twitter.finagle.protobuf.rpc.ServiceExceptionHandler import com.twitter.finagle.protobuf.rpc.ExceptionResponseHandler class RpcFactoryImpl extends RpcFactory { def createServer(sb: ServerBuilder[(String, Message), (String, Message), Any, Any, Any], port: Int, service: Service, handler: ServiceExceptionHandler[Message], executorService: ExecutorService): RpcServer = new RpcServerImpl(sb, port, service, handler, executorService) def createStub[T <: Service](cb: ClientBuilder[(String, Message), (String, Message), Any, Any, Any], service: {def newStub(c: RpcChannel): T}, handler: ExceptionResponseHandler[Message], executorService: ExecutorService): T = { service.newStub(new RpcChannelImpl(cb, service.asInstanceOf[T], handler, executorService)) } def createController(): RpcController = { new RpcControllerWithOnFailureCallback() } def release(stub: {def getChannel(): RpcChannel}) { stub.getChannel().asInstanceOf[RpcChannelImpl].release() } }
Example 14
Source File: RpcServerImpl.scala From finagle-protobuf with Apache License 2.0 | 5 votes |
package com.twitter.finagle.protobuf.rpc.impl import com.twitter.finagle.protobuf.rpc.channel.ProtoBufCodec import com.twitter.finagle.protobuf.rpc.{RpcServer, Util} import com.twitter.util._ import com.twitter.util.Duration import com.twitter.util.FuturePool import com.twitter.finagle.builder.{Server, ServerBuilder, ServerConfig} import java.net.InetSocketAddress import java.util.logging.Logger import scala.None import java.util.concurrent.Executors import java.util.concurrent.ExecutorService import com.google.common.base.Preconditions import com.twitter.finagle.protobuf.rpc.ServiceExceptionHandler import com.google.protobuf.DynamicMessage import com.google.protobuf.DynamicMessage.Builder import com.google.protobuf._ import com.google.protobuf.Descriptors._ import com.twitter.util.Promise class RpcServerImpl(sb: ServerBuilder[(String, Message), (String, Message), Any, Any, Any], port: Int, service: Service, handler: ServiceExceptionHandler[Message], executorService: ExecutorService) extends RpcServer { private val log = Logger.getLogger(getClass.toString) Preconditions.checkNotNull(executorService) Preconditions.checkNotNull(handler) private val execFuturePool = new ExecutorServiceFuturePool(executorService) private val server: Server = ServerBuilder.safeBuild(ServiceDispatcher(service, handler, execFuturePool), sb .codec(new ProtoBufCodec(service)) .name(getClass().getName()) .bindTo(new InetSocketAddress(port))) def close(d: Duration) = { server.close(d) } } class ServiceDispatcher(service: com.google.protobuf.Service, handler: ServiceExceptionHandler[Message], futurePool: FuturePool) extends com.twitter.finagle.Service[(String, Message), (String, Message)] { private val log = Logger.getLogger(getClass.toString) def apply(request: (String, Message)) = { val methodName = request._1 val reqMessage = request._2 Util.log("Request", methodName, reqMessage) val m = service.getDescriptorForType().findMethodByName(methodName); if (m == null) { throw new java.lang.AssertionError("Should never happen, we already decoded " + methodName) } val promise = new Promise[(String, Message)]() // dispatch to the service method val task = () => { try { service.callMethod(m, null, reqMessage, new RpcCallback[Message]() { def run(msg: Message) = { Util.log("Response", methodName, msg) promise.setValue((methodName, msg)) } }) } catch { case e: RuntimeException => { log.warning("#apply# Exception: "+e.getMessage) if (handler.canHandle(e)) { promise.setValue((methodName, handler.handle(e, constructEmptyResponseMessage(m)))) } } } } futurePool(task()) promise } def constructEmptyResponseMessage(m: MethodDescriptor): Message = { val outputType = m.getOutputType(); DynamicMessage.newBuilder(outputType).build() } } object ServiceDispatcher { def apply(service: com.google.protobuf.Service, handler: ServiceExceptionHandler[Message], futurePool: FuturePool): ServiceDispatcher = { new ServiceDispatcher(service, handler, futurePool) } }
Example 15
Source File: HttpLatencyMonitoringFilterSpec.scala From finagle-prometheus with MIT License | 5 votes |
package com.samstarling.prometheusfinagle.filter import com.samstarling.prometheusfinagle.UnitTest import com.samstarling.prometheusfinagle.helper.{CollectorHelper, CollectorRegistryHelper} import com.samstarling.prometheusfinagle.metrics.Telemetry import com.twitter.finagle.Service import com.twitter.finagle.http.{Method, Request, Response, Status} import com.twitter.finagle.util.DefaultTimer import com.twitter.util.{Await, Duration, Future, Timer} import io.prometheus.client.CollectorRegistry import org.specs2.specification.Scope class HttpLatencyMonitoringFilterSpec extends UnitTest { class SlowService extends Service[Request, Response] { implicit val timer = DefaultTimer.twitter override def apply(request: Request): Future[Response] = { Future .value(Response(request.version, Status.Ok)) .delayed(Duration.fromMilliseconds(1500)) } } trait Context extends Scope { val registry = new CollectorRegistry(true) val registryHelper = CollectorRegistryHelper(registry) val telemetry = new Telemetry(registry, "test") val buckets = Seq(1.0, 2.0) val labeller = new TestLabeller val filter = new HttpLatencyMonitoringFilter(telemetry, buckets, labeller) val service = mock[Service[Request, Response]] val slowService = new SlowService val request = Request(Method.Get, "/foo/bar") val serviceResponse = Response(Status.Created) val histogram = telemetry.histogram(name = "incoming_http_request_latency_seconds") service.apply(request) returns Future.value(serviceResponse) } "HttpLatencyMonitoringFilter" >> { "passes requests on to the next service" in new Context { Await.result(filter.apply(request, service)) there was one(service).apply(request) } "returns the Response from the next service" in new Context { val actualResponse = Await.result(filter.apply(request, service)) actualResponse ==== serviceResponse } "counts the request" in new Context { Await.result(filter.apply(request, slowService)) registryHelper.samples .get("test_incoming_http_request_latency_seconds_count") .map(_.map(_.value).sum) must beSome(1.0).eventually } "increments the counter with the labels from the labeller" in new Context { Await.result(filter.apply(request, service)) registryHelper.samples .get("test_incoming_http_request_latency_seconds_count") .map(_.head.dimensions.get("foo").get) must beSome("bar").eventually } "categorises requests into the correct bucket" in new Context { Await.result(filter.apply(request, slowService)) // Our request takes ~1500ms, so it should NOT fall into the "less than or equal to 1 second" bucket (le=0.5) registryHelper.samples .get("test_incoming_http_request_latency_seconds_bucket") .flatMap(_.find(_.dimensions.get("le").contains("1.0"))) .map(_.value) must beSome(0.0).eventually // However, it should fall into the "less than or equal to 2 seconds" bucket (le=0.5) registryHelper.samples .get("test_incoming_http_request_latency_seconds_bucket") .flatMap(_.find(_.dimensions.get("le").contains("2.0"))) .map(_.value) must beSome(1.0).eventually // It should also fall into the "+Inf" bucket registryHelper.samples .get("test_incoming_http_request_latency_seconds_bucket") .flatMap(_.find(_.dimensions.get("le").contains("+Inf"))) .map(_.value) must beSome(1.0).eventually } } }
Example 16
Source File: PrometheusStatsReceiverTest.scala From finagle-prometheus with MIT License | 5 votes |
package com.samstarling.prometheusfinagle import com.twitter.app.LoadService import com.twitter.finagle.stats.{StatsReceiver, Verbosity} import com.twitter.finagle.util.DefaultTimer import com.twitter.util.Duration import io.prometheus.client.CollectorRegistry class PrometheusStatsReceiverTest extends UnitTest { "PrometheusStatsReceiverTest" should { "have a zero-argument constructor" in { new PrometheusStatsReceiver() must not(throwA[RuntimeException]) } // This depends on content in test/resources/META-INF/services "be loaded as a StatsReceiver by LoadService" in { val classes: Seq[Class[_]] = LoadService[StatsReceiver]().map(_.getClass) classes.contains(classOf[PrometheusStatsReceiver]) ==== true } "be able to be instantiated by newInstance" in { classOf[PrometheusStatsReceiver].newInstance() must not( throwA[NoSuchMethodException]) } "allow a registry to be passed" in { val registry = CollectorRegistry.defaultRegistry new PrometheusStatsReceiver(registry) must not(throwA[RuntimeException]) } "allow a registry, namespace, and a Timer to be passed" in { val registry = CollectorRegistry.defaultRegistry val namespace = "testnamespace" new PrometheusStatsReceiver(registry, namespace, DefaultTimer.twitter, Duration.fromSeconds(1)) must not( throwA[RuntimeException]) } "allow metrics and labels with unsafe characters" in { val registry = CollectorRegistry.defaultRegistry val namespace = "test_metric_names_and_labels" val statsReceiver = new PrometheusStatsReceiver(registry, namespace, DefaultTimer.twitter, Duration.fromSeconds(1)) val metrics = Seq( Seq("finagle", "build/revision"), Seq("foo/bar", "baz"), Seq("foo/bar", "build/revision"), Seq("foo-bar", "baz"), Seq("finagle", "build-revsion"), ) metrics foreach { name => statsReceiver.stat(Verbosity.Default, name: _*) } must not(throwA[IllegalArgumentException]) } } }
Example 17
Source File: Http_03_Client.scala From airframe with Apache License 2.0 | 5 votes |
package wvlet.airframe.examples.http import java.util.concurrent.TimeUnit import com.twitter.finagle.Http import com.twitter.finagle.http.Request import com.twitter.util.Duration import wvlet.airframe.http.finagle.{Finagle, FinagleSyncClient} import wvlet.airframe.http.{Endpoint, HttpMethod, Router} import wvlet.log.LogSupport object Http_03_Client extends App with LogSupport { case class User(id: String, name: String) trait MyApp extends LogSupport { @Endpoint(method = HttpMethod.GET, path = "/user/:id") def getUser(id: String): User = { User(id, "xxx") } } val router = Router.add[MyApp] val serverDesign = Finagle.server .withName("myapp") .withRouter(router) .design val clietnDesign = Finagle.client // Max retry attempts .withMaxRetry(3) // Use backoff (or jittering) .withBackOff(1) // Set request timeout .withTimeout(Duration(90, TimeUnit.SECONDS)) // Add Finagle specific configuration .withInitializer { client: Http.Client => client.withHttp2 } // optional // Create a new http client to access the server. .syncClientDesign val design = serverDesign + clietnDesign design.build[FinagleSyncClient] { client => // FinagleServer will be started here // Read the JSON response as an object val user = client.get[User]("/user/1") debug(user) // Read the response as is val request = client.send(Request("/user/2")) val content = request.contentString debug(content) } }