Skip to content
This repository has been archived by the owner on Nov 20, 2024. It is now read-only.

Commit

Permalink
feat: add hooks for measure typesense response time
Browse files Browse the repository at this point in the history
  • Loading branch information
SidStraw authored and DanSnow committed Dec 12, 2023
1 parent e8e2e22 commit 843a819
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 3 deletions.
11 changes: 10 additions & 1 deletion packages/karbon/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,28 @@ import { getResources, payloadScopes } from './runtime/api/sitemap'
import telemetry from './modules/telemetry'
import feed from './modules/feed'
import instantsearch from './modules/instantsearch'
import type { RequestContext, ResponseContext } from './runtime/composables/storipress-base-client'
import type {
RequestContext,
ResponseContext,
SearchRequestContext,
SearchResponseContext,
} from './runtime/composables/storipress-base-client'

declare module '#app' {
interface RuntimeNuxtHooks {
'karbon:request': (ctx: RequestContext) => HookResult
'karbon:response': (ctx: ResponseContext) => HookResult
'karbon:searchRequest': (ctx: SearchRequestContext) => HookResult
'karbon:searchResponse': (ctx: SearchResponseContext) => HookResult
}
}

declare module 'nitropack' {
interface NitroRuntimeHooks {
'karbon:request': (ctx: RequestContext) => void
'karbon:response': (ctx: ResponseContext) => void
'karbon:searchRequest': (ctx: SearchRequestContext) => HookResult
'karbon:searchResponse': (ctx: SearchResponseContext) => HookResult
}
}

Expand Down
32 changes: 30 additions & 2 deletions packages/karbon/src/runtime/api/article.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { PER_PAGE, getSearchQuery, useTypesenseClient } from '../composables/typ
import { splitPaidContent } from '../lib/split-paid-content'
import type { NormalSegment } from '../lib/split-article'
import { splitArticle } from '../lib/split-article'
import { getStoripressConfig } from '../composables/storipress-base-client'
import { _karbonClientHooks, getStoripressConfig } from '../composables/storipress-base-client'
import { verboseInvariant } from '../utils/verbose-invariant'
import type { PaidContent, RawArticleLike, _NormalizeArticle } from './normalize-article'
import { normalizeArticle } from './normalize-article'
Expand Down Expand Up @@ -257,15 +257,36 @@ const GetArticle = gql`
`

export async function listArticles(filter?: TypesenseFilter) {
const storipress = getStoripressConfig()
const typesenseClient = useTypesenseClient()
const documents = typesenseClient.collections('articles').documents()

const groupId = crypto.randomUUID()
const site = storipress.clientId
const name = 'listArticles'
const articles = []
const groupStartTime = Date.now()
let hasMore = true
let page = 1
while (hasMore) {
const id = crypto.randomUUID()
const query = getSearchQuery(page, filter)
const isFirstRequest = page === 1
const ctx = { name, id, groupId, query, site, isFirstRequest, groupStartTime, requestTime: Date.now() }
_karbonClientHooks.callHookParallel('karbon:searchRequest', ctx)

// `destr` is workaround for fetch adapter not automatically parse response
const searchResult = destr<SearchResponse<RawArticleLike>>(await documents.search(getSearchQuery(page, filter), {}))
const rawSearchResult = await documents.search(query, {}).catch((error: Error) => {
_karbonClientHooks.callHookParallel('karbon:searchResponse', {
...ctx,
type: 'error',
responseTime: Date.now(),
hasMore,
error,
})
throw error
})
const searchResult = destr<SearchResponse<RawArticleLike>>(rawSearchResult)
const currentPageArticles =
searchResult?.hits?.map(({ document }) => {
const article = normalizeArticle(document as RawArticleLike)
Expand All @@ -275,6 +296,13 @@ export async function listArticles(filter?: TypesenseFilter) {

hasMore = searchResult.found > searchResult.page * PER_PAGE
page = searchResult.page + 1

_karbonClientHooks.callHookParallel('karbon:searchResponse', {
...ctx,
type: 'complete',
hasMore,
responseTime: Date.now(),
})
}
return articles
}
Expand Down
21 changes: 21 additions & 0 deletions packages/karbon/src/runtime/composables/storipress-base-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { fetch } from 'cross-fetch'
import { withHttps } from 'ufo'
import { Hookable } from 'hookable'
import type { Subscription } from 'zen-observable-ts'
import type { SearchParams, SearchParamsWithPreset } from 'typesense/lib/Typesense/Documents'
import type { ModuleRuntimeConfig } from '../types'

let c: any = null
Expand All @@ -23,11 +24,31 @@ export interface ResponseContext {
data: any
}

export interface SearchRequestContext {
id: string
groupId: string
name: string
query: SearchParams | SearchParamsWithPreset
site: string
isFirstRequest: boolean
requestTime: number
groupStartTime: number
}

export interface SearchResponseContext extends SearchRequestContext {
type: 'error' | 'complete'
hasMore: boolean
responseTime: number
error?: Error
}

type HookResult = Promise<void> | void

export const _karbonClientHooks = new Hookable<{
'karbon:request': (ctx: RequestContext) => HookResult
'karbon:response': (ctx: ResponseContext) => HookResult
'karbon:searchRequest': (ctx: SearchRequestContext) => HookResult
'karbon:searchResponse': (ctx: SearchResponseContext) => HookResult
}>()

export const storipressConfigCtx = {
Expand Down
7 changes: 7 additions & 0 deletions packages/karbon/src/runtime/plugins/client-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ export default defineNuxtPlugin((nuxt) => {
_karbonClientHooks.hook('karbon:response', async (ctx) => {
await nuxt.hooks.callHookParallel('karbon:response', ctx)
})
_karbonClientHooks.hook('karbon:searchRequest', async (ctx) => {
await nuxt.hooks.callHookParallel('karbon:searchRequest', ctx)
})

_karbonClientHooks.hook('karbon:searchResponse', async (ctx) => {
await nuxt.hooks.callHookParallel('karbon:searchResponse', ctx)
})
})
6 changes: 6 additions & 0 deletions packages/karbon/src/runtime/server/plugins/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ export default defineNitroPlugin((nitro) => {
hooks.hook('karbon:response', (ctx) => {
return nitro.hooks.callHookParallel('karbon:response', ctx)
})
hooks.hook('karbon:searchRequest', (ctx) => {
return nitro.hooks.callHookParallel('karbon:searchRequest', ctx)
})
hooks.hook('karbon:searchResponse', (ctx) => {
return nitro.hooks.callHookParallel('karbon:searchResponse', ctx)
})
})
6 changes: 6 additions & 0 deletions packages/playground/plugins/listener.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@ export default defineNuxtPlugin(() => {
nuxt.hooks.hook('karbon:response', (ctx) => {
console.log('nuxt response', ctx)
})
nuxt.hooks.hook('karbon:searchRequest', (ctx) => {
console.log('nuxt searchRequest', ctx)
})
nuxt.hooks.hook('karbon:searchResponse', (ctx) => {
console.log('nuxt searchResponse', ctx)
})
})
6 changes: 6 additions & 0 deletions packages/playground/server/plugins/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@ export default defineNitroPlugin((nitro) => {
nitro.hooks.hook('karbon:response', (ctx) => {
console.log('nitro response', ctx)
})
nitro.hooks.hook('karbon:searchRequest', (ctx) => {
console.log('nitro searchRequest', ctx)
})
nitro.hooks.hook('karbon:searchResponse', (ctx) => {
console.log('nitro searchResponse', ctx)
})
})

0 comments on commit 843a819

Please sign in to comment.