in tweetypie/server/src/main/scala/com/twitter/tweetypie/config/TweetServiceBuilder.scala [141:478]
def apply(
settings: TweetServiceSettings,
statsReceiver: StatsReceiver,
tweetServiceScope: StatsReceiver,
syncTweetService: ThriftTweetService,
timer: Timer,
deciderGates: TweetypieDeciderGates,
featureSwitchesWithExperiments: FeatureSwitches,
featureSwitchesWithoutExperiments: FeatureSwitches,
backendClients: BackendClients,
clientIdHelper: ClientIdHelper,
): ThriftTweetService = {
val (syncInvocationBuilder, asyncInvocationBuilder) = {
val b =
new ServiceInvocationBuilder(syncTweetService, settings.simulateDeferredrpcCallbacks)
(b.withClientId(settings.thriftClientId), b.withClientId(settings.deferredrpcClientId))
}
val tweetKeyFactory = TweetKeyFactory(settings.tweetKeyCacheVersion)
val caches =
if (!settings.withCache)
Caches.NoCache
else
Caches(
settings = settings,
stats = statsReceiver,
timer = timer,
clients = backendClients,
tweetKeyFactory = tweetKeyFactory,
deciderGates = deciderGates,
clientIdHelper = clientIdHelper,
)
val logicalRepos =
LogicalRepositories(
settings = settings,
stats = statsReceiver,
timer = timer,
deciderGates = deciderGates,
external = new ExternalServiceRepositories(
clients = backendClients,
statsReceiver = statsReceiver,
settings = settings,
clientIdHelper = clientIdHelper,
),
caches = caches,
stratoClient = backendClients.stratoserverClient,
hasMedia = hasMedia,
clientIdHelper = clientIdHelper,
featureSwitchesWithoutExperiments = featureSwitchesWithoutExperiments,
)
val tweetCreationLock =
new CacheBasedTweetCreationLock(
cache = caches.tweetCreateLockerCache,
maxTries = 3,
stats = statsReceiver.scope("tweet_save").scope("locker"),
logUniquenessId =
if (settings.scribeUniquenessIds) CacheBasedTweetCreationLock.ScribeUniquenessId
else CacheBasedTweetCreationLock.LogUniquenessId
)
val tweetStores =
TweetStores(
settings = settings,
statsReceiver = statsReceiver,
timer = timer,
deciderGates = deciderGates,
tweetKeyFactory = tweetKeyFactory,
clients = backendClients,
caches = caches,
asyncBuilder = asyncInvocationBuilder,
hasMedia = hasMedia,
clientIdHelper = clientIdHelper,
)
val tweetDeletePathHandler =
new DefaultTweetDeletePathHandler(
tweetServiceScope,
logicalRepos.tweetResultRepo,
logicalRepos.optionalUserRepo,
logicalRepos.stratoSafetyLabelsRepo,
logicalRepos.lastQuoteOfQuoterRepo,
tweetStores,
getPerspectives = backendClients.timelineService.getPerspectives,
)
val tweetBuilders =
TweetBuilders(
settings = settings,
statsReceiver = statsReceiver,
deciderGates = deciderGates,
featureSwitchesWithExperiments = featureSwitchesWithExperiments,
clients = backendClients,
caches = caches,
repos = logicalRepos,
tweetStore = tweetStores,
hasMedia = hasMedia,
unretweetEdits = tweetDeletePathHandler.unretweetEdits,
)
val hydrateTweetForInsert =
WritePathHydration.hydrateTweet(
logicalRepos.tweetHydrators.hydrator,
statsReceiver.scope("insert_tweet")
)
val defaultTweetQueryOptions = TweetQuery.Options(include = GetTweetsHandler.BaseInclude)
val parentUserIdRepo: ParentUserIdRepository.Type =
ParentUserIdRepository(
tweetRepo = logicalRepos.tweetRepo
)
val undeleteTweetHandler =
UndeleteTweetHandlerBuilder(
backendClients.tweetStorageClient,
logicalRepos,
tweetStores,
parentUserIdRepo,
statsReceiver
)
val eraseUserTweetsHandler =
EraseUserTweetsHandlerBuilder(
backendClients,
asyncInvocationBuilder,
deciderGates,
settings,
timer,
tweetDeletePathHandler,
tweetServiceScope
)
val setRetweetVisibilityHandler =
SetRetweetVisibilityHandler(
tweetGetter =
TweetRepository.tweetGetter(logicalRepos.optionalTweetRepo, defaultTweetQueryOptions),
tweetStores.setRetweetVisibility
)
val takedownHandler =
TakedownHandlerBuilder(
logicalRepos = logicalRepos,
tweetStores = tweetStores
)
val updatePossiblySensitiveTweetHandler =
UpdatePossiblySensitiveTweetHandler(
HandlerError.getRequired(
TweetRepository.tweetGetter(logicalRepos.optionalTweetRepo, defaultTweetQueryOptions),
HandlerError.tweetNotFoundException
),
HandlerError.getRequired(
FutureArrow(
UserRepository
.userGetter(
logicalRepos.optionalUserRepo,
UserQueryOptions(Set(UserField.Safety), UserVisibility.All)
)
.compose(UserKey.byId)
),
HandlerError.userNotFoundException
),
tweetStores.updatePossiblySensitiveTweet
)
val userTakedownHandler =
UserTakedownHandlerBuilder(
logicalRepos = logicalRepos,
tweetStores = tweetStores,
stats = tweetServiceScope
)
val getDeletedTweetsHandler =
GetDeletedTweetsHandler(
getDeletedTweets = backendClients.tweetStorageClient.getDeletedTweets,
tweetsExist =
GetDeletedTweetsHandler.tweetsExist(backendClients.tweetStorageClient.getTweet),
stats = tweetServiceScope.scope("get_deleted_tweets_handler")
)
val hydrateQuotedTweet =
WritePathHydration.hydrateQuotedTweet(
logicalRepos.optionalTweetRepo,
logicalRepos.optionalUserRepo,
logicalRepos.quoterHasAlreadyQuotedRepo
)
val deleteLocationDataHandler =
DeleteLocationDataHandler(
backendClients.geoScrubEventStore.getGeoScrubTimestamp,
Scribe(DeleteLocationData, "tweetypie_delete_location_data"),
backendClients.deleteLocationDataPublisher
)
val getStoredTweetsHandler = GetStoredTweetsHandler(logicalRepos.tweetResultRepo)
val getStoredTweetsByUserHandler = GetStoredTweetsByUserHandler(
getStoredTweetsHandler = getStoredTweetsHandler,
getStoredTweet = backendClients.tweetStorageClient.getStoredTweet,
selectPage = FutureArrow { select =>
backendClients.tflockReadClient
.selectPage(select, Some(settings.getStoredTweetsByUserPageSize))
},
maxPages = settings.getStoredTweetsByUserMaxPages
)
val getTweetsHandler =
GetTweetsHandler(
logicalRepos.tweetResultRepo,
logicalRepos.containerAsGetTweetResultRepo,
logicalRepos.deletedTweetVisibilityRepo,
statsReceiver.scope("read_path"),
deciderGates.shouldMaterializeContainers
)
val getTweetFieldsHandler =
GetTweetFieldsHandler(
logicalRepos.tweetResultRepo,
logicalRepos.deletedTweetVisibilityRepo,
logicalRepos.containerAsGetTweetFieldsResultRepo,
statsReceiver.scope("read_path"),
deciderGates.shouldMaterializeContainers
)
val unretweetHandler =
UnretweetHandler(
tweetDeletePathHandler.deleteTweets,
backendClients.timelineService.getPerspectives,
tweetDeletePathHandler.unretweetEdits,
logicalRepos.tweetRepo,
)
val hydrateInsertEvent =
WritePathHydration.hydrateInsertTweetEvent(
hydrateTweet = hydrateTweetForInsert,
hydrateQuotedTweet = hydrateQuotedTweet
)
val scrubGeoUpdateUserTimestampBuilder =
ScrubGeoEventBuilder.UpdateUserTimestamp(
stats = tweetServiceScope.scope("scrub_geo_update_user_timestamp"),
userRepo = logicalRepos.optionalUserRepo
)
val scrubGeoScrubTweetsBuilder =
ScrubGeoEventBuilder.ScrubTweets(
stats = tweetServiceScope.scope("scrub_geo"),
userRepo = logicalRepos.optionalUserRepo
)
val handlerFilter =
PostTweet
.DuplicateHandler(
tweetCreationLock = tweetCreationLock,
getTweets = getTweetsHandler,
stats = statsReceiver.scope("duplicate")
)
.andThen(PostTweet.RescueTweetCreateFailure)
.andThen(PostTweet.LogFailures)
val postTweetHandler =
handlerFilter[PostTweetRequest](
PostTweet.Handler(
tweetBuilder = tweetBuilders.tweetBuilder,
hydrateInsertEvent = hydrateInsertEvent,
tweetStore = tweetStores,
)
)
val postRetweetHandler =
handlerFilter[RetweetRequest](
PostTweet.Handler(
tweetBuilder = tweetBuilders.retweetBuilder,
hydrateInsertEvent = hydrateInsertEvent,
tweetStore = tweetStores,
)
)
val quotedTweetDeleteBuilder: QuotedTweetDeleteEventBuilder.Type =
QuotedTweetDeleteEventBuilder(logicalRepos.optionalTweetRepo)
val quotedTweetTakedownBuilder: QuotedTweetTakedownEventBuilder.Type =
QuotedTweetTakedownEventBuilder(logicalRepos.optionalTweetRepo)
val setAdditionalFieldsBuilder: SetAdditionalFieldsBuilder.Type =
SetAdditionalFieldsBuilder(
tweetRepo = logicalRepos.tweetRepo
)
val asyncSetAdditionalFieldsBuilder: AsyncSetAdditionalFieldsBuilder.Type =
AsyncSetAdditionalFieldsBuilder(
userRepo = logicalRepos.userRepo
)
val deleteAdditionalFieldsBuilder: DeleteAdditionalFieldsBuilder.Type =
DeleteAdditionalFieldsBuilder(
tweetRepo = logicalRepos.tweetRepo
)
val asyncDeleteAdditionalFieldsBuilder: AsyncDeleteAdditionalFieldsBuilder.Type =
AsyncDeleteAdditionalFieldsBuilder(
userRepo = logicalRepos.userRepo
)
new DispatchingTweetService(
asyncDeleteAdditionalFieldsBuilder = asyncDeleteAdditionalFieldsBuilder,
asyncSetAdditionalFieldsBuilder = asyncSetAdditionalFieldsBuilder,
deleteAdditionalFieldsBuilder = deleteAdditionalFieldsBuilder,
deleteLocationDataHandler = deleteLocationDataHandler,
deletePathHandler = tweetDeletePathHandler,
eraseUserTweetsHandler = eraseUserTweetsHandler,
getDeletedTweetsHandler = getDeletedTweetsHandler,
getStoredTweetsHandler = getStoredTweetsHandler,
getStoredTweetsByUserHandler = getStoredTweetsByUserHandler,
getTweetsHandler = getTweetsHandler,
getTweetFieldsHandler = getTweetFieldsHandler,
getTweetCountsHandler = GetTweetCountsHandler(logicalRepos.tweetCountsRepo),
postTweetHandler = postTweetHandler,
postRetweetHandler = postRetweetHandler,
quotedTweetDeleteBuilder = quotedTweetDeleteBuilder,
quotedTweetTakedownBuilder = quotedTweetTakedownBuilder,
scrubGeoUpdateUserTimestampBuilder = scrubGeoUpdateUserTimestampBuilder,
scrubGeoScrubTweetsBuilder = scrubGeoScrubTweetsBuilder,
setAdditionalFieldsBuilder = setAdditionalFieldsBuilder,
setRetweetVisibilityHandler = setRetweetVisibilityHandler,
statsReceiver = statsReceiver,
takedownHandler = takedownHandler,
tweetStore = tweetStores,
undeleteTweetHandler = undeleteTweetHandler,
unretweetHandler = unretweetHandler,
updatePossiblySensitiveTweetHandler = updatePossiblySensitiveTweetHandler,
userTakedownHandler = userTakedownHandler,
clientIdHelper = clientIdHelper,
)
}