stress test

This commit is contained in:
Dan Abramov
2024-07-09 19:43:32 +01:00
parent d5503d17de
commit 551e68439c
5 changed files with 107 additions and 18 deletions
+4 -1
View File
@@ -51,7 +51,10 @@ async function fetchHandler(
const res = await fetch(reqUri, {
method: reqMethod,
headers: reqHeaders,
headers: {
...reqHeaders,
'x-bsky-entryway': 'short-session'
},
body: reqBody,
signal: controller.signal,
})
+67 -1
View File
@@ -1,3 +1,69 @@
import {BskyAgent, jsonToLex, stringifyLex} from '@atproto/api'
const GET_TIMEOUT = 15e3 // 15s
const POST_TIMEOUT = 60e3 // 60s
export function doPolyfill() {
// no polyfill is needed on web
BskyAgent.configure({fetch: fetchHandler})
}
interface FetchHandlerResponse {
status: number
headers: Record<string, string>
body: any
}
async function fetchHandler(
reqUri: string,
reqMethod: string,
reqHeaders: Record<string, string>,
reqBody: any,
): Promise<FetchHandlerResponse> {
const reqMimeType = reqHeaders['Content-Type'] || reqHeaders['content-type']
if (reqMimeType && reqMimeType.startsWith('application/json')) {
reqBody = stringifyLex(reqBody)
}
const controller = new AbortController()
const to = setTimeout(
() => controller.abort(),
reqMethod === 'post' ? POST_TIMEOUT : GET_TIMEOUT,
)
const res = await fetch(reqUri, {
method: reqMethod,
headers: {
...reqHeaders,
'x-bsky-entryway': 'short-session'
},
body: reqBody,
signal: controller.signal,
})
const resStatus = res.status
const resHeaders: Record<string, string> = {}
res.headers.forEach((value: string, key: string) => {
resHeaders[key] = value
})
const resMimeType = resHeaders['Content-Type'] || resHeaders['content-type']
let resBody
if (resMimeType) {
if (resMimeType.startsWith('application/json')) {
resBody = jsonToLex(await res.json())
} else if (resMimeType.startsWith('text/')) {
resBody = await res.text()
} else if (resMimeType === 'application/vnd.ipld.car') {
resBody = await res.arrayBuffer()
} else {
throw new Error('Non-supported mime type')
}
}
clearTimeout(to)
return {
status: resStatus,
headers: resHeaders,
body: resBody,
}
}
+34 -15
View File
@@ -35,7 +35,7 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) {
const aggregatedStats = React.useRef<AggregatedStats | null>(null)
const throttledFlushAggregatedStats = React.useMemo(
() =>
throttle(() => flushToStatsig(aggregatedStats.current), 45e3, {
throttle(() => flushToStatsig(aggregatedStats.current), 5e3, {
leading: true, // The outer call is already throttled somewhat.
trailing: true,
}),
@@ -43,22 +43,41 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) {
)
const sendToFeedNoDelay = React.useCallback(() => {
const proxyAgent = agent.withProxy(
// @ts-ignore TODO need to update withProxy() to support this key -prf
'bsky_fg',
// TODO when we start sending to other feeds, we need to grab their DID -prf
'did:web:discover.bsky.app',
) as BskyAgent
const interactions = Array.from(queue.current).map(toInteraction)
queue.current.clear()
// Send to the feed
proxyAgent.app.bsky.feed
.sendInteractions({interactions})
.catch((e: any) => {
logger.warn('Failed to send feed interactions', {error: e})
})
if (true) {
// Send to the feed
agent.app.bsky.feed
.sendInteractions({ interactions }, {
encoding: 'application/json',
headers: {
'atproto-proxy': 'did:web:discover.bsky.app#bsky_fg'
}
})
.catch((e: any) => {
logger.warn('Failed to send feed interactions', { error: e })
})
} else {
const proxyAgent = agent.withProxy(
// @ts-ignore TODO need to update withProxy() to support this key -prf
'bsky_fg',
// TODO when we start sending to other feeds, we need to grab their DID -prf
'did:web:discover.bsky.app',
) as BskyAgent
// Send to the feed
proxyAgent.app.bsky.feed
.sendInteractions({ interactions }, {
encoding: 'application/json',
headers: {
'atproto-proxy': 'did:web:discover.bsky.app#bsky_fg'
}
})
.catch((e: any) => {
logger.warn('Failed to send feed interactions', { error: e })
})
}
// Send to Statsig
if (aggregatedStats.current === null) {
@@ -70,7 +89,7 @@ export function useFeedFeedback(feed: FeedDescriptor, hasSession: boolean) {
const sendToFeed = React.useMemo(
() =>
throttle(sendToFeedNoDelay, 15e3, {
throttle(sendToFeedNoDelay, 1e3, {
leading: false,
trailing: true,
}),
+1
View File
@@ -71,6 +71,7 @@ let nextMessageIndex = 0
const MAX_SLICE_LENGTH = 1000
export function addSessionDebugLog(log: Log) {
console.log(new Date(), log)
try {
if (!Statsig.initializeCalled() || !Statsig.getStableID()) {
// Drop these logs for now.
+1 -1
View File
@@ -29,7 +29,7 @@ export type ListProps<ItemT> = Omit<
}
export type ListRef = React.MutableRefObject<any | null> // TODO: Better types.
const ON_ITEM_SEEN_WAIT_DURATION = 1.5e3 // when we consider post to be "seen"
const ON_ITEM_SEEN_WAIT_DURATION = 100 // when we consider post to be "seen"
const ON_ITEM_SEEN_INTERSECTION_OPTS = {
rootMargin: '-200px 0px -200px 0px',
} // post must be 200px visible to be "seen"