Skip to content

Commit

Permalink
[Statsig] Remove client downsampling (bluesky-social#6153)
Browse files Browse the repository at this point in the history
  • Loading branch information
haileyok authored Nov 15, 2024
1 parent 400c432 commit 3bd1437
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 99 deletions.
2 changes: 1 addition & 1 deletion src/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
onStateChange={() => {
const routeName = getCurrentRouteName()
if (routeName === 'Notifications') {
logEvent('router:navigate:notifications:sampled', {})
logEvent('router:navigate:notifications', {})
}
}}
onReady={() => {
Expand Down
4 changes: 2 additions & 2 deletions src/components/ProfileCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ export function DescriptionPlaceholder({
export type FollowButtonProps = {
profile: AppBskyActorDefs.ProfileViewBasic
moderationOpts: ModerationOpts
logContext: LogEvents['profile:follow:sampled']['logContext'] &
LogEvents['profile:unfollow:sampled']['logContext']
logContext: LogEvents['profile:follow']['logContext'] &
LogEvents['profile:unfollow']['logContext']
} & Partial<ButtonProps>

export function FollowButton(props: FollowButtonProps) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/hooks/useFollowMethods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export function useFollowMethods({
logContext,
}: {
profile: Shadow<AppBskyActorDefs.ProfileViewBasic>
logContext: LogEvents['profile:follow:sampled']['logContext'] &
LogEvents['profile:unfollow:sampled']['logContext']
logContext: LogEvents['profile:follow']['logContext'] &
LogEvents['profile:unfollow']['logContext']
}) {
const {_} = useLingui()
const requireAuth = useRequireAuth()
Expand Down
30 changes: 15 additions & 15 deletions src/lib/statsig/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ export type LogEvents = {
context: 'StartOnboarding' | 'AfterOnboarding' | 'Login' | 'Home'
status: 'granted' | 'denied' | 'undetermined'
}
'state:background:sampled': {
'state:background': {
secondsActive: number
}
'state:foreground:sampled': {}
'router:navigate:notifications:sampled': {}
'state:foreground': {}
'router:navigate:notifications': {}
'deepLink:referrerReceived': {
to: string
referrer: string
Expand Down Expand Up @@ -76,7 +76,7 @@ export type LogEvents = {
'onboarding:finished:avatarResult': {
avatarResult: 'default' | 'created' | 'uploaded'
}
'home:feedDisplayed:sampled': {
'home:feedDisplayed': {
feedUrl: string
feedType: string
index: number
Expand All @@ -87,12 +87,12 @@ export type LogEvents = {
| 'desktop-sidebar-click'
| 'starter-pack-initial-feed'
}
'feed:endReached:sampled': {
'feed:endReached': {
feedUrl: string
feedType: string
itemCount: number
}
'feed:refresh:sampled': {
'feed:refresh': {
feedUrl: string
feedType: string
reason: 'pull-to-refresh' | 'soft-reset' | 'load-latest'
Expand All @@ -103,13 +103,13 @@ export type LogEvents = {
'discover:showLess': {
feedContext: string
}
'discover:clickthrough:sampled': {
'discover:clickthrough': {
count: number
}
'discover:engaged:sampled': {
'discover:engaged': {
count: number
}
'discover:seen:sampled': {
'discover:seen': {
count: number
}

Expand All @@ -132,27 +132,27 @@ export type LogEvents = {
postCount: number
isReply: boolean
}
'post:like:sampled': {
'post:like': {
doesLikerFollowPoster: boolean | undefined
doesPosterFollowLiker: boolean | undefined
likerClout: number | undefined
postClout: number | undefined
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
}
'post:repost:sampled': {
'post:repost': {
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
}
'post:unlike:sampled': {
'post:unlike': {
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
}
'post:unrepost:sampled': {
'post:unrepost': {
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
}
'post:mute': {}
'post:unmute': {}
'post:pin': {}
'post:unpin': {}
'profile:follow:sampled': {
'profile:follow': {
didBecomeMutual: boolean | undefined
followeeClout: number | undefined
followerClout: number | undefined
Expand All @@ -169,7 +169,7 @@ export type LogEvents = {
| 'FeedInterstitial'
| 'ProfileHeaderSuggestedFollows'
}
'profile:unfollow:sampled': {
'profile:unfollow': {
logContext:
| 'RecommendedFollowsItem'
| 'PostThreadItem'
Expand Down
42 changes: 3 additions & 39 deletions src/lib/statsig/statsig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function createStatsigOptions(prefetchUsers: StatsigUser[]) {
initTimeoutMs: 1,
// Get fresh flags for other accounts as well, if any.
prefetchUsers,
api: 'https://events.bsky.app/v2',
}
}

Expand Down Expand Up @@ -89,51 +90,14 @@ export function toClout(n: number | null | undefined): number | undefined {
}
}

const DOWNSAMPLE_RATE = 0.99 // 99% likely
const DOWNSAMPLED_EVENTS: Set<keyof LogEvents> = new Set([
'router:navigate:notifications:sampled',
'state:background:sampled',
'state:foreground:sampled',
'home:feedDisplayed:sampled',
'feed:endReached:sampled',
'feed:refresh:sampled',
'discover:clickthrough:sampled',
'discover:engaged:sampled',
'discover:seen:sampled',
'post:like:sampled',
'post:unlike:sampled',
'post:repost:sampled',
'post:unrepost:sampled',
'profile:follow:sampled',
'profile:unfollow:sampled',
])
const isDownsampledSession = Math.random() < DOWNSAMPLE_RATE

export function logEvent<E extends keyof LogEvents>(
eventName: E & string,
rawMetadata: LogEvents[E] & FlatJSONRecord,
) {
try {
if (
process.env.NODE_ENV === 'development' &&
eventName.endsWith(':sampled') &&
!DOWNSAMPLED_EVENTS.has(eventName)
) {
logger.error(
'Did you forget to add ' + eventName + ' to DOWNSAMPLED_EVENTS?',
)
}

const isDownsampledEvent = DOWNSAMPLED_EVENTS.has(eventName)
if (isDownsampledSession && isDownsampledEvent) {
return
}
const fullMetadata = {
...rawMetadata,
} as Record<string, string> // Statsig typings are unnecessarily strict here.
if (isDownsampledEvent) {
fullMetadata.downsampleRate = DOWNSAMPLE_RATE.toString()
}
fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)'
if (Statsig.initializeCalled()) {
Statsig.logEvent(eventName, null, fullMetadata)
Expand Down Expand Up @@ -232,13 +196,13 @@ AppState.addEventListener('change', (state: AppStateStatus) => {
lastState = state
if (state === 'active') {
lastActive = performance.now()
logEvent('state:foreground:sampled', {})
logEvent('state:foreground', {})
} else {
let secondsActive = 0
if (lastActive != null) {
secondsActive = Math.round((performance.now() - lastActive) / 1e3)
lastActive = null
logEvent('state:background:sampled', {
logEvent('state:background', {
secondsActive,
})
}
Expand Down
6 changes: 3 additions & 3 deletions src/state/feed-feedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,21 +234,21 @@ function flushToStatsig(stats: AggregatedStats | null) {
}

if (stats.clickthroughCount > 0) {
logEvent('discover:clickthrough:sampled', {
logEvent('discover:clickthrough', {
count: stats.clickthroughCount,
})
stats.clickthroughCount = 0
}

if (stats.engagedCount > 0) {
logEvent('discover:engaged:sampled', {
logEvent('discover:engaged', {
count: stats.engagedCount,
})
stats.engagedCount = 0
}

if (stats.seenCount > 0) {
logEvent('discover:seen:sampled', {
logEvent('discover:seen', {
count: stats.seenCount,
})
stats.seenCount = 0
Expand Down
24 changes: 12 additions & 12 deletions src/state/queries/post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ export function useGetPosts() {

export function usePostLikeMutationQueue(
post: Shadow<AppBskyFeedDefs.PostView>,
logContext: LogEvents['post:like:sampled']['logContext'] &
LogEvents['post:unlike:sampled']['logContext'],
logContext: LogEvents['post:like']['logContext'] &
LogEvents['post:unlike']['logContext'],
) {
const queryClient = useQueryClient()
const postUri = post.uri
Expand Down Expand Up @@ -157,7 +157,7 @@ export function usePostLikeMutationQueue(
}

function usePostLikeMutation(
logContext: LogEvents['post:like:sampled']['logContext'],
logContext: LogEvents['post:like']['logContext'],
post: Shadow<AppBskyFeedDefs.PostView>,
) {
const {currentAccount} = useSession()
Expand All @@ -174,7 +174,7 @@ function usePostLikeMutation(
if (currentAccount) {
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
}
logEvent('post:like:sampled', {
logEvent('post:like', {
logContext,
doesPosterFollowLiker: postAuthor.viewer
? Boolean(postAuthor.viewer.followedBy)
Expand All @@ -196,21 +196,21 @@ function usePostLikeMutation(
}

function usePostUnlikeMutation(
logContext: LogEvents['post:unlike:sampled']['logContext'],
logContext: LogEvents['post:unlike']['logContext'],
) {
const agent = useAgent()
return useMutation<void, Error, {postUri: string; likeUri: string}>({
mutationFn: ({likeUri}) => {
logEvent('post:unlike:sampled', {logContext})
logEvent('post:unlike', {logContext})
return agent.deleteLike(likeUri)
},
})
}

export function usePostRepostMutationQueue(
post: Shadow<AppBskyFeedDefs.PostView>,
logContext: LogEvents['post:repost:sampled']['logContext'] &
LogEvents['post:unrepost:sampled']['logContext'],
logContext: LogEvents['post:repost']['logContext'] &
LogEvents['post:unrepost']['logContext'],
) {
const queryClient = useQueryClient()
const postUri = post.uri
Expand Down Expand Up @@ -266,7 +266,7 @@ export function usePostRepostMutationQueue(
}

function usePostRepostMutation(
logContext: LogEvents['post:repost:sampled']['logContext'],
logContext: LogEvents['post:repost']['logContext'],
) {
const agent = useAgent()
return useMutation<
Expand All @@ -275,19 +275,19 @@ function usePostRepostMutation(
{uri: string; cid: string} // the post's uri and cid
>({
mutationFn: post => {
logEvent('post:repost:sampled', {logContext})
logEvent('post:repost', {logContext})
return agent.repost(post.uri, post.cid)
},
})
}

function usePostUnrepostMutation(
logContext: LogEvents['post:unrepost:sampled']['logContext'],
logContext: LogEvents['post:unrepost']['logContext'],
) {
const agent = useAgent()
return useMutation<void, Error, {postUri: string; repostUri: string}>({
mutationFn: ({repostUri}) => {
logEvent('post:unrepost:sampled', {logContext})
logEvent('post:unrepost', {logContext})
return agent.deleteRepost(repostUri)
},
})
Expand Down
12 changes: 6 additions & 6 deletions src/state/queries/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ export function useProfileUpdateMutation() {

export function useProfileFollowMutationQueue(
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
logContext: LogEvents['profile:follow:sampled']['logContext'] &
LogEvents['profile:follow:sampled']['logContext'],
logContext: LogEvents['profile:follow']['logContext'] &
LogEvents['profile:follow']['logContext'],
) {
const agent = useAgent()
const queryClient = useQueryClient()
Expand Down Expand Up @@ -293,7 +293,7 @@ export function useProfileFollowMutationQueue(
}

function useProfileFollowMutation(
logContext: LogEvents['profile:follow:sampled']['logContext'],
logContext: LogEvents['profile:follow']['logContext'],
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
) {
const {currentAccount} = useSession()
Expand All @@ -308,7 +308,7 @@ function useProfileFollowMutation(
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
}
captureAction(ProgressGuideAction.Follow)
logEvent('profile:follow:sampled', {
logEvent('profile:follow', {
logContext,
didBecomeMutual: profile.viewer
? Boolean(profile.viewer.followedBy)
Expand All @@ -322,12 +322,12 @@ function useProfileFollowMutation(
}

function useProfileUnfollowMutation(
logContext: LogEvents['profile:unfollow:sampled']['logContext'],
logContext: LogEvents['profile:unfollow']['logContext'],
) {
const agent = useAgent()
return useMutation<void, Error, {did: string; followUri: string}>({
mutationFn: async ({followUri}) => {
logEvent('profile:unfollow:sampled', {logContext})
logEvent('profile:unfollow', {logContext})
return await agent.deleteFollow(followUri)
},
})
Expand Down
4 changes: 2 additions & 2 deletions src/view/com/feeds/FeedPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export function FeedPage({
scrollToTop()
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
setHasNew(false)
logEvent('feed:refresh:sampled', {
logEvent('feed:refresh', {
feedType: feed.split('|')[0],
feedUrl: feed,
reason: 'soft-reset',
Expand All @@ -98,7 +98,7 @@ export function FeedPage({
scrollToTop()
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
setHasNew(false)
logEvent('feed:refresh:sampled', {
logEvent('feed:refresh', {
feedType: feed.split('|')[0],
feedUrl: feed,
reason: 'load-latest',
Expand Down
Loading

0 comments on commit 3bd1437

Please sign in to comment.