the-algorithm/pushservice/src/main/scala/com/twitter/frigate/pushservice/controller/PushServiceController.scala

115 lines
4.1 KiB
Scala

package com.twitter.frigate.pushservice.controller
import com.google.inject.Inject
import com.twitter.finagle.stats.StatsReceiver
import com.twitter.finagle.thrift.ClientId
import com.twitter.finatra.thrift.Controller
import com.twitter.frigate.pushservice.exception.DisplayLocationNotSupportedException
import com.twitter.frigate.pushservice.refresh_handler.RefreshForPushHandler
import com.twitter.frigate.pushservice.send_handler.SendHandler
import com.twitter.frigate.pushservice.refresh_handler.LoggedOutRefreshForPushHandler
import com.twitter.frigate.pushservice.thriftscala.PushService.Loggedout
import com.twitter.frigate.pushservice.thriftscala.PushService.Refresh
import com.twitter.frigate.pushservice.thriftscala.PushService.Send
import com.twitter.frigate.pushservice.{thriftscala => t}
import com.twitter.frigate.thriftscala.NotificationDisplayLocation
import com.twitter.util.logging.Logging
import com.twitter.util.Future
class PushServiceController @Inject() (
sendHandler: SendHandler,
refreshForPushHandler: RefreshForPushHandler,
loggedOutRefreshForPushHandler: LoggedOutRefreshForPushHandler,
statsReceiver: StatsReceiver)
extends Controller(t.PushService)
with Logging {
private val stats: StatsReceiver = statsReceiver.scope(s"${this.getClass.getSimpleName}")
private val failureCount = stats.counter("failures")
private val failureStatsScope = stats.scope("failures")
private val uncaughtErrorCount = failureStatsScope.counter("uncaught")
private val uncaughtErrorScope = failureStatsScope.scope("uncaught")
private val clientIdScope = stats.scope("client_id")
handle(t.PushService.Send) { request: Send.Args =>
send(request)
}
handle(t.PushService.Refresh) { args: Refresh.Args =>
refresh(args)
}
handle(t.PushService.Loggedout) { request: Loggedout.Args =>
loggedOutRefresh(request)
}
private def loggedOutRefresh(
request: t.PushService.Loggedout.Args
): Future[t.PushService.Loggedout.SuccessType] = {
val fut = request.request.notificationDisplayLocation match {
case NotificationDisplayLocation.PushToMobileDevice =>
loggedOutRefreshForPushHandler.refreshAndSend(request.request)
case _ =>
Future.exception(
new DisplayLocationNotSupportedException(
"Specified notification display location is not supported"))
}
fut.onFailure { ex =>
logger.error(
s"Failure in push service for logged out refresh request: $request - ${ex.getMessage} - ${ex.getStackTrace
.mkString(", \n\t")}",
ex)
failureCount.incr()
uncaughtErrorCount.incr()
uncaughtErrorScope.counter(ex.getClass.getCanonicalName).incr()
}
}
private def refresh(
request: t.PushService.Refresh.Args
): Future[t.PushService.Refresh.SuccessType] = {
val fut = request.request.notificationDisplayLocation match {
case NotificationDisplayLocation.PushToMobileDevice =>
val clientId: String =
ClientId.current
.flatMap { cid => Option(cid.name) }
.getOrElse("none")
clientIdScope.counter(clientId).incr()
refreshForPushHandler.refreshAndSend(request.request)
case _ =>
Future.exception(
new DisplayLocationNotSupportedException(
"Specified notification display location is not supported"))
}
fut.onFailure { ex =>
logger.error(
s"Failure in push service for refresh request: $request - ${ex.getMessage} - ${ex.getStackTrace
.mkString(", \n\t")}",
ex
)
failureCount.incr()
uncaughtErrorCount.incr()
uncaughtErrorScope.counter(ex.getClass.getCanonicalName).incr()
}
}
private def send(
request: t.PushService.Send.Args
): Future[t.PushService.Send.SuccessType] = {
sendHandler(request.request).onFailure { ex =>
logger.error(
s"Failure in push service for send request: $request - ${ex.getMessage} - ${ex.getStackTrace
.mkString(", \n\t")}",
ex
)
failureCount.incr()
uncaughtErrorCount.incr()
uncaughtErrorScope.counter(ex.getClass.getCanonicalName).incr()
}
}
}