Skip to content

Commit

Permalink
Merge pull request #136 from cyprus-developer-community/feat-add-cach…
Browse files Browse the repository at this point in the history
…e-to-github-events

feat: add in-memory cache to github events
  • Loading branch information
PatrickHeneise authored Sep 6, 2023
2 parents f7eb888 + a31f74f commit 6e6f58a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 20 deletions.
19 changes: 11 additions & 8 deletions app/features/providers/github/commands/getPastEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,25 @@ import {
} from '~/features/providers/misc/http'
import { mapIssuesToEvents } from './misc/mapIssueToEvent'
import type { Event } from './types'
import { fetchCached } from './misc/cache'

export const getPastEvents = async (
nextToken?: String
): Promise<ApiResponse<Event[]>> => {
try {
const client = newGraphQLClientFactory()

const res = await client<GetPastEventsQuery>(getPastEventsQuery, {
owner: 'cyprus-developer-community',
repo: 'events',
size: 20,
after: nextToken
})

const events = await mapIssuesToEvents(res.repository.issues.nodes)
const cacheKey = 'pastEvents'
const events = await fetchCached(cacheKey, async () => {
const res = await client<GetPastEventsQuery>(getPastEventsQuery, {
owner: 'cyprus-developer-community',
repo: 'events',
size: 20,
after: nextToken
})

return mapIssuesToEvents(res.repository.issues.nodes)
})
return newSuccessfulResponse(events)
} catch (e) {
return newErrorResponse(e)
Expand Down
18 changes: 11 additions & 7 deletions app/features/providers/github/commands/getUpcomingEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,25 @@ import {
} from '~/features/providers/misc/http'
import type { Event } from './types'
import { mapIssuesToEvents } from './misc/mapIssueToEvent'
import { fetchCached } from './misc/cache'

export const getUpcomingEvents = async (
nextToken?: String
): Promise<ApiResponse<Event[]>> => {
try {
const client = newGraphQLClientFactory()

const res = await client<GetUpcomingEventsQuery>(getUpcomingEventsQuery, {
owner: 'cyprus-developer-community',
repo: 'events',
size: 20,
after: nextToken
})
const cacheKey = 'upcomingEvents'
const events = await fetchCached(cacheKey, async () => {
const res = await client<GetUpcomingEventsQuery>(getUpcomingEventsQuery, {
owner: 'cyprus-developer-community',
repo: 'events',
size: 20,
after: nextToken
})

const events = await mapIssuesToEvents(res.repository.issues.nodes)
return mapIssuesToEvents(res.repository.issues.nodes)
})
return newSuccessfulResponse(events)
} catch (e) {
return newErrorResponse(e)
Expand Down
49 changes: 49 additions & 0 deletions app/features/providers/github/commands/misc/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import NodeCache from 'node-cache'

let cache: NodeCache
let expired = {}

declare global {
var __cache: NodeCache | undefined
var __expired: { [key: string]: boolean }
}

if (process.env.NODE_ENV === 'production') {
cache = new NodeCache({ deleteOnExpire: false })
} else {
if (!global.__cache) {
global.__cache = new NodeCache({ deleteOnExpire: false })
}
cache = global.__cache
if (!global.__expired) {
global.__expired = {}
}
expired = global.__expired
}

cache.on('expired', (key) => {
expired[key] = true
})

const fetchCached = async <T>(
cacheKey: string,
fetcher: () => Promise<T>,
ttl = 60 * 20
) => {
let response: T
if (cache.has(cacheKey)) {
response = cache.get(cacheKey)
if (expired[cacheKey]) {
;(async () => {
expired[cacheKey] = false
cache.set(cacheKey, await fetcher(), ttl)
})()
}
return response
}
response = await fetcher()
cache.set(cacheKey, response, ttl)
return response
}

export { cache, fetchCached }
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"date-fns-tz": "^2.0.0",
"graphql": "^16.6.0",
"marked": "^4.2.12",
"node-cache": "^5.1.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11",
Expand Down
34 changes: 29 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6e6f58a

Please sign in to comment.