[docx] split commit for file 2600
Signed-off-by: Ari Archer <ari.web.xyz@gmail.com>
This commit is contained in:
parent
53c2f869f3
commit
8efd1b183b
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.common.alert.predicate
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used for building [[Predicate]]s
|
|
||||||
*
|
|
||||||
* @see [[https://docbird.twitter.biz/mon/reference.html#predicate OPERATOR]]
|
|
||||||
*/
|
|
||||||
private[alert] sealed trait Operator
|
|
||||||
private[alert] case object `>` extends Operator
|
|
||||||
private[alert] case object `>=` extends Operator
|
|
||||||
private[alert] case object `<` extends Operator
|
|
||||||
private[alert] case object `<=` extends Operator
|
|
||||||
private[alert] case object `!=` extends Operator
|
|
||||||
private[alert] case object `=` extends Operator
|
|
Binary file not shown.
|
@ -1,52 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.common.alert.predicate
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [[Predicate]]s will trigger if the metric's value is past the
|
|
||||||
* `threshold` for `datapointsPastThreshold` or more datapoints
|
|
||||||
* in a given `duration`
|
|
||||||
*
|
|
||||||
* @see [[https://docbird.twitter.biz/mon/reference.html#predicate Predicate]]
|
|
||||||
*/
|
|
||||||
trait Predicate {
|
|
||||||
|
|
||||||
/** @see [[https://docbird.twitter.biz/mon/reference.html#predicate OPERATOR]] */
|
|
||||||
val operator: Operator
|
|
||||||
|
|
||||||
/** @see [[https://docbird.twitter.biz/mon/reference.html#predicate THRESHOLD]] */
|
|
||||||
val threshold: Double
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of datapoints in a given duration beyond the threshold that will trigger an alert
|
|
||||||
* @see [[https://docbird.twitter.biz/mon/reference.html#predicate DATAPOINTS]]
|
|
||||||
*/
|
|
||||||
val datapointsPastThreshold: Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @note if using a [[metricGranularity]] of [[Minutes]] then this must be >= 3
|
|
||||||
* @see [[https://docbird.twitter.biz/mon/reference.html#predicate DURATION]]
|
|
||||||
*/
|
|
||||||
val duration: Int
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specifies the metric granularity
|
|
||||||
* @see [[https://docbird.twitter.biz/mon/reference.html#predicate DURATION]]
|
|
||||||
*/
|
|
||||||
val metricGranularity: MetricGranularity
|
|
||||||
|
|
||||||
require(
|
|
||||||
datapointsPastThreshold > 0,
|
|
||||||
s"`datapointsPastThreshold` must be > 0 but got `datapointsPastThreshold` = $datapointsPastThreshold"
|
|
||||||
)
|
|
||||||
|
|
||||||
require(
|
|
||||||
datapointsPastThreshold <= duration,
|
|
||||||
s"`datapointsPastThreshold` must be <= than `duration.inMinutes` but got `datapointsPastThreshold` = $datapointsPastThreshold `duration` = $duration"
|
|
||||||
)
|
|
||||||
require(
|
|
||||||
metricGranularity != Minutes || duration >= 3,
|
|
||||||
s"Predicate durations must be at least 3 minutes but got $duration"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** [[ThroughputPredicate]]s are predicates that can trigger when the throughput is too low or high */
|
|
||||||
trait ThroughputPredicate extends Predicate
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.common.alert.predicate
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A [[Predicate]] that triggers if the metric this is used with rises above
|
|
||||||
* the [[threshold]] for [[datapointsPastThreshold]] per [[duration]]
|
|
||||||
*/
|
|
||||||
case class TriggerIfAbove(
|
|
||||||
override val threshold: Double,
|
|
||||||
override val datapointsPastThreshold: Int = 10,
|
|
||||||
override val duration: Int = 15,
|
|
||||||
override val metricGranularity: MetricGranularity = Minutes)
|
|
||||||
extends Predicate
|
|
||||||
with ThroughputPredicate {
|
|
||||||
override val operator: Operator = `>`
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.common.alert.predicate
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A [[Predicate]] that triggers if the metric this is used with lowers below
|
|
||||||
* the [[threshold]] for [[datapointsPastThreshold]] per [[duration]]
|
|
||||||
*/
|
|
||||||
case class TriggerIfBelow(
|
|
||||||
override val threshold: Double,
|
|
||||||
override val datapointsPastThreshold: Int = 10,
|
|
||||||
override val duration: Int = 15,
|
|
||||||
override val metricGranularity: MetricGranularity = Minutes)
|
|
||||||
extends Predicate
|
|
||||||
with ThroughputPredicate {
|
|
||||||
override val operator: Operator = `<`
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,22 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.common.alert.predicate
|
|
||||||
|
|
||||||
import com.twitter.util.Duration
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A [[Predicate]] that triggers if the metric this is used with rises above the
|
|
||||||
* [[latencyThreshold]] for [[datapointsPastThreshold]] per [[duration]]
|
|
||||||
*
|
|
||||||
* @note [[latencyThreshold]] must be > 0
|
|
||||||
*/
|
|
||||||
case class TriggerIfLatencyAbove(
|
|
||||||
latencyThreshold: Duration,
|
|
||||||
override val datapointsPastThreshold: Int = 10,
|
|
||||||
override val duration: Int = 15,
|
|
||||||
override val metricGranularity: MetricGranularity = Minutes)
|
|
||||||
extends Predicate {
|
|
||||||
override val threshold: Double = latencyThreshold.inMillis
|
|
||||||
override val operator: Operator = `>`
|
|
||||||
require(
|
|
||||||
latencyThreshold > Duration.Zero,
|
|
||||||
s"TriggerIfLatencyAbove thresholds must be greater than 0 but got $latencyThreshold")
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
scala_library(
|
|
||||||
sources = ["*.scala"],
|
|
||||||
compiler_option_sets = ["fatal_warnings"],
|
|
||||||
platform = "java8",
|
|
||||||
strict_deps = True,
|
|
||||||
tags = ["bazel-compatible"],
|
|
||||||
dependencies = [
|
|
||||||
"3rdparty/jvm/javax/inject:javax.inject",
|
|
||||||
"configapi/configapi-core",
|
|
||||||
"configapi/configapi-featureswitches:v2",
|
|
||||||
"featureswitches/featureswitches-core",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/functional_component/configapi/registry",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/request",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/product/registry",
|
|
||||||
],
|
|
||||||
exports = [
|
|
||||||
"3rdparty/jvm/javax/inject:javax.inject",
|
|
||||||
"configapi/configapi-core",
|
|
||||||
"configapi/configapi-featureswitches:v2",
|
|
||||||
"featureswitches/featureswitches-core",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/functional_component/configapi/registry",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/request",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/product/registry",
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,17 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.functional_component.configapi.registry.GlobalParamRegistry
|
|
||||||
import com.twitter.product_mixer.core.product.registry.ProductParamRegistry
|
|
||||||
import com.twitter.timelines.configapi.CompositeConfig
|
|
||||||
import com.twitter.timelines.configapi.Config
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class ConfigBuilder @Inject() (
|
|
||||||
productParamRegistry: ProductParamRegistry,
|
|
||||||
globalParamRegistry: GlobalParamRegistry) {
|
|
||||||
|
|
||||||
def build(): Config =
|
|
||||||
new CompositeConfig(productParamRegistry.build() ++ Seq(globalParamRegistry.build()))
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,34 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi
|
|
||||||
|
|
||||||
import com.twitter.finagle.stats.StatsReceiver
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.request.ClientContext
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.request.Product
|
|
||||||
import com.twitter.servo.util.MemoizingStatsReceiver
|
|
||||||
import com.twitter.timelines.configapi.Config
|
|
||||||
import com.twitter.timelines.configapi.FeatureValue
|
|
||||||
import com.twitter.timelines.configapi.Params
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
/** Singleton object for building [[Params]] to override */
|
|
||||||
@Singleton
|
|
||||||
class ParamsBuilder @Inject() (
|
|
||||||
config: Config,
|
|
||||||
requestContextBuilder: RequestContextBuilder,
|
|
||||||
statsReceiver: StatsReceiver) {
|
|
||||||
|
|
||||||
private[this] val scopedStatsReceiver =
|
|
||||||
new MemoizingStatsReceiver(statsReceiver.scope("configapi"))
|
|
||||||
|
|
||||||
def build(
|
|
||||||
clientContext: ClientContext,
|
|
||||||
product: Product,
|
|
||||||
featureOverrides: Map[String, FeatureValue],
|
|
||||||
fsCustomMapInput: Map[String, Any] = Map.empty
|
|
||||||
): Params = {
|
|
||||||
val requestContext =
|
|
||||||
requestContextBuilder.build(clientContext, product, featureOverrides, fsCustomMapInput)
|
|
||||||
|
|
||||||
config(requestContext, scopedStatsReceiver)
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,19 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi
|
|
||||||
|
|
||||||
import com.twitter.timelines.configapi.BaseRequestContext
|
|
||||||
import com.twitter.timelines.configapi.FeatureContext
|
|
||||||
import com.twitter.timelines.configapi.GuestId
|
|
||||||
import com.twitter.timelines.configapi.UserId
|
|
||||||
import com.twitter.timelines.configapi.WithFeatureContext
|
|
||||||
import com.twitter.timelines.configapi.WithGuestId
|
|
||||||
import com.twitter.timelines.configapi.WithUserId
|
|
||||||
|
|
||||||
/** Represents [[com.twitter.timelines.configapi]]'s context information */
|
|
||||||
case class RequestContext(
|
|
||||||
userId: Option[UserId],
|
|
||||||
guestId: Option[GuestId],
|
|
||||||
featureContext: FeatureContext)
|
|
||||||
extends BaseRequestContext
|
|
||||||
with WithUserId
|
|
||||||
with WithGuestId
|
|
||||||
with WithFeatureContext
|
|
Binary file not shown.
|
@ -1,72 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi
|
|
||||||
|
|
||||||
import com.twitter.featureswitches.v2.FeatureSwitches
|
|
||||||
import com.twitter.featureswitches.UserAgent
|
|
||||||
import com.twitter.featureswitches.{Recipient => FeatureSwitchRecipient}
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.request.ClientContext
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.request.Product
|
|
||||||
import com.twitter.timelines.configapi.featureswitches.v2.FeatureSwitchResultsFeatureContext
|
|
||||||
import com.twitter.timelines.configapi.FeatureContext
|
|
||||||
import com.twitter.timelines.configapi.FeatureValue
|
|
||||||
import com.twitter.timelines.configapi.ForcedFeatureContext
|
|
||||||
import com.twitter.timelines.configapi.OrElseFeatureContext
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request Context Factory is used to build RequestContext objects which are used
|
|
||||||
* by the config api to determine the param overrides to apply to the request.
|
|
||||||
* The param overrides are determined per request by configs which specify which
|
|
||||||
* FS/Deciders/AB translate to what param overrides.
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
class RequestContextBuilder @Inject() (featureSwitches: FeatureSwitches) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param `fsCustomMapInput` allows you to set custom fields on your feature switches.
|
|
||||||
* This feature isn't directly supported by product mixer yet, so using this argument
|
|
||||||
* will likely result in future cleanup work.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
def build(
|
|
||||||
clientContext: ClientContext,
|
|
||||||
product: Product,
|
|
||||||
featureOverrides: Map[String, FeatureValue],
|
|
||||||
fsCustomMapInput: Map[String, Any]
|
|
||||||
): RequestContext = {
|
|
||||||
val featureContext =
|
|
||||||
getFeatureContext(clientContext, product, featureOverrides, fsCustomMapInput)
|
|
||||||
|
|
||||||
RequestContext(clientContext.userId, clientContext.guestId, featureContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
private[configapi] def getFeatureContext(
|
|
||||||
clientContext: ClientContext,
|
|
||||||
product: Product,
|
|
||||||
featureOverrides: Map[String, FeatureValue],
|
|
||||||
fsCustomMapInput: Map[String, Any]
|
|
||||||
): FeatureContext = {
|
|
||||||
val recipient = getFeatureSwitchRecipient(clientContext)
|
|
||||||
.withCustomFields("product" -> product.identifier.toString, fsCustomMapInput.toSeq: _*)
|
|
||||||
|
|
||||||
val results = featureSwitches.matchRecipient(recipient)
|
|
||||||
OrElseFeatureContext(
|
|
||||||
ForcedFeatureContext(featureOverrides),
|
|
||||||
new FeatureSwitchResultsFeatureContext(results))
|
|
||||||
}
|
|
||||||
|
|
||||||
private[configapi] def getFeatureSwitchRecipient(
|
|
||||||
clientContext: ClientContext
|
|
||||||
): FeatureSwitchRecipient = FeatureSwitchRecipient(
|
|
||||||
userId = clientContext.userId,
|
|
||||||
userRoles = clientContext.userRoles,
|
|
||||||
deviceId = clientContext.deviceId,
|
|
||||||
guestId = clientContext.guestId,
|
|
||||||
languageCode = clientContext.languageCode,
|
|
||||||
countryCode = clientContext.countryCode,
|
|
||||||
userAgent = clientContext.userAgent.flatMap(UserAgent.apply),
|
|
||||||
isVerified = None,
|
|
||||||
clientApplicationId = clientContext.appId,
|
|
||||||
isTwoffice = clientContext.isTwoffice
|
|
||||||
)
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi
|
|
||||||
|
|
||||||
import com.twitter.timelines.configapi.Param
|
|
||||||
|
|
||||||
/** A [[Param]] used for constant values where we do not require backing by feature switches or deciders */
|
|
||||||
case class StaticParam[ValueType](value: ValueType) extends Param[ValueType](value)
|
|
|
@ -1,23 +0,0 @@
|
||||||
scala_library(
|
|
||||||
sources = ["*.scala"],
|
|
||||||
compiler_option_sets = ["fatal_warnings"],
|
|
||||||
platform = "java8",
|
|
||||||
strict_deps = True,
|
|
||||||
tags = ["bazel-compatible"],
|
|
||||||
dependencies = [
|
|
||||||
"3rdparty/jvm/javax/inject:javax.inject",
|
|
||||||
"configapi/configapi-core",
|
|
||||||
"configapi/configapi-decider",
|
|
||||||
"servo/decider",
|
|
||||||
"util/util-core:util-core-util",
|
|
||||||
"util/util-logging",
|
|
||||||
],
|
|
||||||
exports = [
|
|
||||||
"3rdparty/jvm/javax/inject:javax.inject",
|
|
||||||
"configapi/configapi-core",
|
|
||||||
"configapi/configapi-decider",
|
|
||||||
"servo/decider",
|
|
||||||
"util/util-core:util-core-util",
|
|
||||||
"util/util-logging",
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,7 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi.registry
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register Params that do not relate to a specific product.
|
|
||||||
* See [[ParamConfig]] for hooks to register Params based on type.
|
|
||||||
*/
|
|
||||||
trait GlobalParamConfig extends ParamConfig with ParamConfigBuilder
|
|
Binary file not shown.
|
@ -1,21 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi.registry
|
|
||||||
|
|
||||||
import com.twitter.finagle.stats.StatsReceiver
|
|
||||||
import com.twitter.servo.decider.DeciderGateBuilder
|
|
||||||
import com.twitter.timelines.configapi.BaseConfigBuilder
|
|
||||||
import com.twitter.timelines.configapi.Config
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class GlobalParamRegistry @Inject() (
|
|
||||||
globalParamConfig: GlobalParamConfig,
|
|
||||||
deciderGateBuilder: DeciderGateBuilder,
|
|
||||||
statsReceiver: StatsReceiver) {
|
|
||||||
|
|
||||||
def build(): Config = {
|
|
||||||
val globalConfigs = globalParamConfig.build(deciderGateBuilder, statsReceiver)
|
|
||||||
|
|
||||||
BaseConfigBuilder(globalConfigs).build("GlobalParamRegistry")
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,74 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi.registry
|
|
||||||
|
|
||||||
import com.twitter.timelines.configapi.FeatureSwitchOverrideUtil.DefinedFeatureName
|
|
||||||
import com.twitter.timelines.configapi.FeatureSwitchOverrideUtil.EnumParamWithFeatureName
|
|
||||||
import com.twitter.timelines.configapi.FeatureSwitchOverrideUtil.EnumSeqParamWithFeatureName
|
|
||||||
import com.twitter.timelines.configapi.FeatureSwitchOverrideUtil.ValueFeatureName
|
|
||||||
import com.twitter.timelines.configapi.decider.HasDecider
|
|
||||||
import com.twitter.timelines.configapi.Bounded
|
|
||||||
import com.twitter.timelines.configapi.FSName
|
|
||||||
import com.twitter.timelines.configapi.HasDurationConversion
|
|
||||||
import com.twitter.timelines.configapi.OptionalOverride
|
|
||||||
import com.twitter.timelines.configapi.Param
|
|
||||||
import com.twitter.util.Duration
|
|
||||||
|
|
||||||
/** ParamConfig is used to configure overrides for [[Param]]s of various types */
|
|
||||||
trait ParamConfig {
|
|
||||||
|
|
||||||
def booleanDeciderOverrides: Seq[Param[Boolean] with HasDecider] = Seq.empty
|
|
||||||
|
|
||||||
def booleanFSOverrides: Seq[Param[Boolean] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def optionalBooleanOverrides: Seq[
|
|
||||||
(Param[Option[Boolean]], DefinedFeatureName, ValueFeatureName)
|
|
||||||
] = Seq.empty
|
|
||||||
|
|
||||||
def enumFSOverrides: Seq[EnumParamWithFeatureName[_ <: Enumeration]] = Seq.empty
|
|
||||||
|
|
||||||
def enumSeqFSOverrides: Seq[EnumSeqParamWithFeatureName[_ <: Enumeration]] = Seq.empty
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for non-Duration supplied FS overrides (e.g. `timeFromStringFSOverrides`,
|
|
||||||
* `timeFromNumberFSOverrides`, `getBoundedOptionalDurationFromMillisOverrides`) is not provided
|
|
||||||
* as Duration is preferred
|
|
||||||
*/
|
|
||||||
def boundedDurationFSOverrides: Seq[
|
|
||||||
Param[Duration] with Bounded[Duration] with FSName with HasDurationConversion
|
|
||||||
] = Seq.empty
|
|
||||||
|
|
||||||
/** Support for unbounded numeric FS overrides is not provided as bounded is preferred */
|
|
||||||
def boundedIntFSOverrides: Seq[Param[Int] with Bounded[Int] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def boundedOptionalIntOverrides: Seq[
|
|
||||||
(Param[Option[Int]] with Bounded[Option[Int]], DefinedFeatureName, ValueFeatureName)
|
|
||||||
] = Seq.empty
|
|
||||||
|
|
||||||
def intSeqFSOverrides: Seq[Param[Seq[Int]] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def boundedLongFSOverrides: Seq[Param[Long] with Bounded[Long] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def boundedOptionalLongOverrides: Seq[
|
|
||||||
(Param[Option[Long]] with Bounded[Option[Long]], DefinedFeatureName, ValueFeatureName)
|
|
||||||
] = Seq.empty
|
|
||||||
|
|
||||||
def longSeqFSOverrides: Seq[Param[Seq[Long]] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def longSetFSOverrides: Seq[Param[Set[Long]] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def boundedDoubleFSOverrides: Seq[Param[Double] with Bounded[Double] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def boundedOptionalDoubleOverrides: Seq[
|
|
||||||
(Param[Option[Double]] with Bounded[Option[Double]], DefinedFeatureName, ValueFeatureName)
|
|
||||||
] = Seq.empty
|
|
||||||
|
|
||||||
def doubleSeqFSOverrides: Seq[Param[Seq[Double]] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def stringFSOverrides: Seq[Param[String] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def stringSeqFSOverrides: Seq[Param[Seq[String]] with FSName] = Seq.empty
|
|
||||||
|
|
||||||
def optionalStringOverrides: Seq[(Param[Option[String]], DefinedFeatureName, ValueFeatureName)] =
|
|
||||||
Seq.empty
|
|
||||||
|
|
||||||
def gatedOverrides: Map[String, Seq[OptionalOverride[_]]] = Map.empty
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,49 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.configapi.registry
|
|
||||||
|
|
||||||
import com.twitter.finagle.stats.StatsReceiver
|
|
||||||
import com.twitter.logging.Logger
|
|
||||||
import com.twitter.servo.decider.DeciderGateBuilder
|
|
||||||
import com.twitter.timelines.configapi.FeatureSwitchOverrideUtil
|
|
||||||
import com.twitter.timelines.configapi.OptionalOverride
|
|
||||||
import com.twitter.timelines.configapi.decider.DeciderUtils
|
|
||||||
|
|
||||||
trait ParamConfigBuilder { paramConfig: ParamConfig =>
|
|
||||||
|
|
||||||
/** Builds a Seq of [[OptionalOverride]]s based on the [[paramConfig]] */
|
|
||||||
def build(
|
|
||||||
deciderGateBuilder: DeciderGateBuilder,
|
|
||||||
statsReceiver: StatsReceiver
|
|
||||||
): Seq[OptionalOverride[_]] = {
|
|
||||||
val logger = Logger(classOf[ParamConfig])
|
|
||||||
|
|
||||||
DeciderUtils.getBooleanDeciderOverrides(deciderGateBuilder, booleanDeciderOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBooleanFSOverrides(booleanFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getOptionalBooleanOverrides(optionalBooleanOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getEnumFSOverrides(
|
|
||||||
statsReceiver.scope("enumConversion"),
|
|
||||||
logger,
|
|
||||||
enumFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getEnumSeqFSOverrides(
|
|
||||||
statsReceiver.scope("enumSeqConversion"),
|
|
||||||
logger,
|
|
||||||
enumSeqFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedDurationFSOverrides(boundedDurationFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedIntFSOverrides(boundedIntFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedOptionalIntOverrides(boundedOptionalIntOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getIntSeqFSOverrides(intSeqFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedLongFSOverrides(boundedLongFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedOptionalLongOverrides(boundedOptionalLongOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getLongSeqFSOverrides(longSeqFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getLongSetFSOverrides(longSetFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedDoubleFSOverrides(boundedDoubleFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getBoundedOptionalDoubleOverrides(
|
|
||||||
boundedOptionalDoubleOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getDoubleSeqFSOverrides(doubleSeqFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getStringFSOverrides(stringFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getStringSeqFSOverrides(stringSeqFSOverrides: _*) ++
|
|
||||||
FeatureSwitchOverrideUtil.getOptionalStringOverrides(optionalStringOverrides: _*) ++
|
|
||||||
gatedOverrides.flatMap {
|
|
||||||
case (fsName, overrides) => FeatureSwitchOverrideUtil.gatedOverrides(fsName, overrides: _*)
|
|
||||||
}.toSeq
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
scala_library(
|
|
||||||
name = "decoration",
|
|
||||||
sources = ["Decoration.scala"],
|
|
||||||
compiler_option_sets = ["fatal_warnings"],
|
|
||||||
platform = "java8",
|
|
||||||
strict_deps = True,
|
|
||||||
tags = ["bazel-compatible"],
|
|
||||||
dependencies = [
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
],
|
|
||||||
exports = [
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
scala_library(
|
|
||||||
sources = [
|
|
||||||
"!Decoration.scala",
|
|
||||||
"*.scala",
|
|
||||||
],
|
|
||||||
compiler_option_sets = ["fatal_warnings"],
|
|
||||||
platform = "java8",
|
|
||||||
strict_deps = True,
|
|
||||||
tags = ["bazel-compatible"],
|
|
||||||
dependencies = [
|
|
||||||
":decoration",
|
|
||||||
"3rdparty/jvm/javax/inject:javax.inject",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/pipeline",
|
|
||||||
],
|
|
||||||
exports = [
|
|
||||||
":decoration",
|
|
||||||
"3rdparty/jvm/javax/inject:javax.inject",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/pipeline",
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,61 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.Component
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.common.identifier.ComponentIdentifier
|
|
||||||
import com.twitter.product_mixer.core.model.common.identifier.DecoratorIdentifier
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
import com.twitter.stitch.Stitch
|
|
||||||
|
|
||||||
/**
|
|
||||||
* [[CandidateDecorator]] generates a [[com.twitter.product_mixer.core.model.common.presentation.UniversalPresentation]]
|
|
||||||
* for Candidates, which encapsulate information about how to present the candidate
|
|
||||||
*
|
|
||||||
* @see [[https://docbird.twitter.biz/product-mixer/functional-components.html#candidate-decorator]]
|
|
||||||
* @see [[com.twitter.product_mixer.core.model.common.presentation.UniversalPresentation]]
|
|
||||||
*/
|
|
||||||
trait CandidateDecorator[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]]
|
|
||||||
extends Component {
|
|
||||||
|
|
||||||
override val identifier: DecoratorIdentifier = CandidateDecorator.DefaultCandidateDecoratorId
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Given a Seq of `Candidate`, returns a [[Decoration]] for candidates which should be decorated
|
|
||||||
*
|
|
||||||
* `Candidate`s which aren't decorated can be omitted from the results
|
|
||||||
*/
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidates: Seq[CandidateWithFeatures[Candidate]]
|
|
||||||
): Stitch[Seq[Decoration]]
|
|
||||||
}
|
|
||||||
|
|
||||||
object CandidateDecorator {
|
|
||||||
private[core] val DefaultCandidateDecoratorId: DecoratorIdentifier =
|
|
||||||
DecoratorIdentifier(ComponentIdentifier.BasedOnParentComponent)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For use when building a [[CandidateDecorator]] in a [[com.twitter.product_mixer.core.pipeline.PipelineBuilder]]
|
|
||||||
* to ensure that the identifier is updated with the parent [[com.twitter.product_mixer.core.pipeline.Pipeline.identifier]]
|
|
||||||
*/
|
|
||||||
private[core] def copyWithUpdatedIdentifier[
|
|
||||||
Query <: PipelineQuery,
|
|
||||||
Candidate <: UniversalNoun[Any]
|
|
||||||
](
|
|
||||||
decorator: CandidateDecorator[Query, Candidate],
|
|
||||||
parentIdentifier: ComponentIdentifier
|
|
||||||
): CandidateDecorator[Query, Candidate] = {
|
|
||||||
if (decorator.identifier == DefaultCandidateDecoratorId) {
|
|
||||||
new CandidateDecorator[Query, Candidate] {
|
|
||||||
override val identifier: DecoratorIdentifier = DecoratorIdentifier(parentIdentifier.name)
|
|
||||||
override def apply(
|
|
||||||
query: Query,
|
|
||||||
candidates: Seq[CandidateWithFeatures[Candidate]]
|
|
||||||
): Stitch[Seq[Decoration]] = decorator.apply(query, candidates)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
decorator
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,11 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.common.presentation.UniversalPresentation
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decoration associates specific [[UniversalPresentation]] with a candidate
|
|
||||||
*/
|
|
||||||
case class Decoration(
|
|
||||||
candidate: UniversalNoun[Any],
|
|
||||||
presentation: UniversalPresentation)
|
|
|
@ -1,21 +0,0 @@
|
||||||
scala_library(
|
|
||||||
sources = ["*.scala"],
|
|
||||||
compiler_option_sets = ["fatal_warnings"],
|
|
||||||
platform = "java8",
|
|
||||||
strict_deps = True,
|
|
||||||
tags = ["bazel-compatible"],
|
|
||||||
dependencies = [
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/functional_component/decorator",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/slice",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/pipeline",
|
|
||||||
],
|
|
||||||
exports = [
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/functional_component/decorator",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/slice",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/pipeline",
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.slice.builder
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.slice.SliceItem
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait CandidateSliceItemBuilder[
|
|
||||||
-Query <: PipelineQuery,
|
|
||||||
-BuilderInput <: UniversalNoun[Any],
|
|
||||||
BuilderOutput <: SliceItem] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: BuilderInput, featureMap: FeatureMap): BuilderOutput
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
scala_library(
|
|
||||||
sources = ["**/*.scala"],
|
|
||||||
compiler_option_sets = ["fatal_warnings"],
|
|
||||||
platform = "java8",
|
|
||||||
strict_deps = True,
|
|
||||||
tags = ["bazel-compatible"],
|
|
||||||
dependencies = [
|
|
||||||
"product-mixer/component-library/src/main/scala/com/twitter/product_mixer/component_library/model/candidate",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/functional_component/decorator",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/urt",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/urt/item",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/urt/metadata",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/pipeline",
|
|
||||||
],
|
|
||||||
exports = [
|
|
||||||
"product-mixer/component-library/src/main/scala/com/twitter/product_mixer/component_library/model/candidate",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/functional_component/decorator",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/common/presentation",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/urt",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/urt/item",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/model/marshalling/response/urt/metadata",
|
|
||||||
"product-mixer/core/src/main/scala/com/twitter/product_mixer/core/pipeline",
|
|
||||||
],
|
|
||||||
)
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.TimelineEntry
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait CandidateUrtEntryBuilder[
|
|
||||||
-Query <: PipelineQuery,
|
|
||||||
-BuilderInput <: UniversalNoun[Any],
|
|
||||||
BuilderOutput <: TimelineEntry] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: BuilderInput, candidateFeatures: FeatureMap): BuilderOutput
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.icon
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.icon.HorizonIcon
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseHorizonIconBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidates: Seq[CandidateWithFeatures[Candidate]]
|
|
||||||
): Option[HorizonIcon]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,11 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.alert
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.ShowAlertCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
import com.twitter.util.Duration
|
|
||||||
|
|
||||||
trait BaseDurationBuilder[-Query <: PipelineQuery] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: ShowAlertCandidate, features: FeatureMap): Option[Duration]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.alert
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.ShowAlertCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.alert.ShowAlertColorConfiguration
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseShowAlertColorConfigurationBuilder[-Query <: PipelineQuery] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: ShowAlertCandidate,
|
|
||||||
features: FeatureMap
|
|
||||||
): ShowAlertColorConfiguration
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.alert
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.ShowAlertCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.alert.ShowAlertDisplayLocation
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseShowAlertDisplayLocationBuilder[-Query <: PipelineQuery] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: ShowAlertCandidate,
|
|
||||||
features: FeatureMap
|
|
||||||
): ShowAlertDisplayLocation
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.alert
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.ShowAlertCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.alert.ShowAlertIconDisplayInfo
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseShowAlertIconDisplayInfoBuilder[-Query <: PipelineQuery] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: ShowAlertCandidate,
|
|
||||||
features: FeatureMap
|
|
||||||
): Option[ShowAlertIconDisplayInfo]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.alert
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.ShowAlertCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.alert.ShowAlertNavigationMetadata
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseShowAlertNavigationMetadataBuilder[-Query <: PipelineQuery] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: ShowAlertCandidate,
|
|
||||||
features: FeatureMap
|
|
||||||
): Option[ShowAlertNavigationMetadata]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,10 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.alert
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.ShowAlertCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseShowAlertUserIdsBuilder[-Query <: PipelineQuery] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: ShowAlertCandidate, features: FeatureMap): Option[Seq[Long]]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.topic
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.item.topic.TopicDisplayType
|
|
||||||
|
|
||||||
trait BaseTopicDisplayTypeBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: PipelineQuery,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[TopicDisplayType]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.topic
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.item.topic.TopicFunctionalityType
|
|
||||||
|
|
||||||
trait BaseTopicFunctionalityTypeBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: PipelineQuery,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[TopicFunctionalityType]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.tweet
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.BaseTweetCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseEntryIdToReplaceBuilder[-Query <: PipelineQuery, -Candidate <: BaseTweetCandidate] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[String]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.tweet
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.BaseTweetCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.item.tweet.TimelinesScoreInfo
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseTimelinesScoreInfoBuilder[-Query <: PipelineQuery, -Candidate <: BaseTweetCandidate] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[TimelinesScoreInfo]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.tweet
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.BaseTweetCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.item.tweet.TweetHighlights
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseTweetHighlightsBuilder[-Query <: PipelineQuery, -Candidate <: BaseTweetCandidate] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[TweetHighlights]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.item.user
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.component_library.model.candidate.BaseUserCandidate
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.item.user.UserReactiveTriggers
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseUserReactiveTriggersBuilder[-Query <: PipelineQuery, -Candidate <: BaseUserCandidate] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[UserReactiveTriggers]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,19 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.metadata
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.metadata.ClientEventDetails
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseClientEventDetailsBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a [[ClientEventDetails]] for the provided [[Candidate]]
|
|
||||||
* @see [[ClientEventDetails]]
|
|
||||||
*/
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[ClientEventDetails]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,20 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.metadata
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.metadata.ClientEventInfo
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseClientEventInfoBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return a [[ClientEventInfo]] for the provided [[Candidate]]
|
|
||||||
* @see [[ClientEventInfo]]
|
|
||||||
*/
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap,
|
|
||||||
element: Option[String]
|
|
||||||
): Option[ClientEventInfo]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.metadata
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.metadata.FeedbackActionInfo
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseFeedbackActionInfoBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[FeedbackActionInfo]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,10 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.metadata
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseModuleStr[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidates: Seq[CandidateWithFeatures[Candidate]]): String
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,10 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.metadata
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseStr[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: Candidate, candidateFeatures: FeatureMap): String
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,11 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.metadata
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.metadata.Url
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
|
|
||||||
trait BaseUrlBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: Candidate, candidateFeatures: FeatureMap): Url
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.promoted
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.promoted.PromotedMetadata
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BasePromotedMetadataBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[PromotedMetadata]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,11 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.richtext
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.richtext.RichText
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseRichTextBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: Candidate, candidateFeatures: FeatureMap): RichText
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.social_context
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.metadata.SocialContext
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseModuleSocialContextBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidates: Seq[CandidateWithFeatures[Candidate]]
|
|
||||||
): Option[SocialContext]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.social_context
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.metadata.SocialContext
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseSocialContextBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidate: Candidate,
|
|
||||||
candidateFeatures: FeatureMap
|
|
||||||
): Option[SocialContext]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,12 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.stringcenter
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseModuleStringCenterPlaceholderBuilder[
|
|
||||||
-Query <: PipelineQuery,
|
|
||||||
-Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidates: Seq[CandidateWithFeatures[Candidate]]): Map[String, Any]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,12 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.stringcenter
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseStringCenterPlaceholderBuilder[
|
|
||||||
-Query <: PipelineQuery,
|
|
||||||
-Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(query: Query, candidate: Candidate, candidateFeatures: FeatureMap): Map[String, Any]
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.timeline_module
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.timeline_module.ModuleDisplayType
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseModuleDisplayTypeBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidates: Seq[CandidateWithFeatures[Candidate]]
|
|
||||||
): ModuleDisplayType
|
|
||||||
}
|
|
Binary file not shown.
|
@ -1,14 +0,0 @@
|
||||||
package com.twitter.product_mixer.core.functional_component.decorator.urt.builder.timeline_module
|
|
||||||
|
|
||||||
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
||||||
import com.twitter.product_mixer.core.model.common.UniversalNoun
|
|
||||||
import com.twitter.product_mixer.core.model.marshalling.response.urt.timeline_module.ModuleFooter
|
|
||||||
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
||||||
|
|
||||||
trait BaseModuleFooterBuilder[-Query <: PipelineQuery, -Candidate <: UniversalNoun[Any]] {
|
|
||||||
|
|
||||||
def apply(
|
|
||||||
query: Query,
|
|
||||||
candidates: Seq[CandidateWithFeatures[Candidate]]
|
|
||||||
): Option[ModuleFooter]
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue