Skip to content

Commit

Permalink
Merge pull request kodadot#10764 from Jarsen136/issue-10749
Browse files Browse the repository at this point in the history
refactor: Optimize subscription with polling
  • Loading branch information
Jarsen136 authored Aug 22, 2024
2 parents cdc2308 + 8c66730 commit 6c84032
Show file tree
Hide file tree
Showing 5 changed files with 295 additions and 152 deletions.
20 changes: 16 additions & 4 deletions components/shared/modals/keyboardShortcutsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,30 @@
>
<template #default>
<div class="flex justify-between">
<NeoTable v-for="ktype in types" :key="ktype" :data="updateData[ktype]">
<NeoTableColumn v-slot="props" field="text" :label="labels[ktype]">
<NeoTable
v-for="ktype in types"
:key="ktype"
:data="updateData[ktype]"
>
<NeoTableColumn
v-slot="props"
field="text"
:label="labels[ktype]"
>
<div class="text-left">
{{ props.row.text }}
</div>
</NeoTableColumn>
<NeoTableColumn v-slot="props" field="shortcut">
<NeoTableColumn
v-slot="props"
field="shortcut"
>
<div class="flex flex-grow">
<span
v-for="(shortcut, index) in props.row.shortcut.split('+', 2)"
:key="shortcut"
class="inline-flex">
class="inline-flex"
>
<kbd class="keyboard-shortcut-kbd">
{{ shortcut || '+' }}
</kbd>
Expand Down
95 changes: 59 additions & 36 deletions composables/useSubscriptionGraphql.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,82 @@
import { createClient } from 'graphql-ws'
import { getWSUrlByClient } from '@/utils/websocket'
import isEqual from 'lodash/isEqual'
import { apolloClientConfig } from '@/utils/constants'

export default function ({
clientName = '',
query,
onChange,
onError,
pollingInterval = 6000,
}: {
clientName?: string
query: string
onChange: (data) => void
onError?: (error) => void
pollingInterval?: number
}) {
const { client: prefixClient } = usePrefix()
const { $consola } = useNuxtApp()
const client = clientName || prefixClient.value
const wsUrl = getWSUrlByClient(client)
const httpUrl = apolloClientConfig[client]?.httpEndpoint

if (!wsUrl) {
// this client do not subscription
if (!httpUrl) {
return () => {}
}

const wsClient = createClient({
url: wsUrl,
})
let lastQueryResult = null
let intervalId: number | null = null

const isPolling = ref(false)

wsClient.subscribe(
{
query: `
subscription {
async function pollData() {
try {
const response = await $fetch(httpUrl, {
method: 'POST',
body: {
query: `
query {
${query}
}
`,
/**
* For each entity types, the following queries are supported for subscriptions:
* ${EntityName}ById -- query a single entity
* ${EntityName}s -- query multiple entities with a where filter
* ref: https://docs.subsquid.io/develop-a-squid/graphql-api/subscriptions/
*/
},
{
next: (data) => {
$consola.log(`ws subscription: New changes: ${JSON.stringify(data)}`)
onChange(data)
},
error: (error) => {
$consola.error('ws subscription: error', error)
onError && onError(error)
},
complete: () => {
$consola.log('ws subscription: done!')
},
},
)

return () => wsClient.dispose()
`,
},
})

const newResult = response.data as any

if (!isEqual(newResult, lastQueryResult)) {
$consola.log(`[Graphql Subscription] New changes: ${JSON.stringify(newResult)}`)
onChange({ data: newResult })
lastQueryResult = newResult
}
}
catch (error) {
$consola.error('[Graphql Subscription] Polling error:', error)
onError && onError(error)
}
}

function startPolling() {
if (!isPolling.value) {
isPolling.value = true
intervalId = setInterval(pollData, pollingInterval) as unknown as number
$consola.log('[Graphql Subscription] Started polling')
}
}

function stopPolling() {
if (isPolling.value && intervalId !== null) {
clearInterval(intervalId)
isPolling.value = false
$consola.log('[Graphql Subscription] Stopped polling')
}
}

startPolling()

// Clean up on component unmount
onUnmounted(() => {
stopPolling()
})

return stopPolling
}
1 change: 0 additions & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export default defineNuxtConfig({
'chartjs-plugin-zoom',
'date-fns/format',
'date-fns/formatDistanceToNow',
'graphql-ws',
'keen-slider/vue',
'lodash/camelCase',
'lodash/filter',
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@
"date-fns": "^2.30.0",
"gql.tada": "^1.8.2",
"graphql": "^16.9.0",
"graphql-ws": "^5.16.0",
"jdenticon": "3.2.0",
"keen-slider": "^6.8.6",
"lodash": "^4.17.21",
Expand Down
Loading

0 comments on commit 6c84032

Please sign in to comment.