Skip to content

Commit

Permalink
✨ image store caching polish
Browse files Browse the repository at this point in the history
  • Loading branch information
ikesau committed Apr 15, 2024
1 parent 958d3a3 commit dc4c6f0
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 30 deletions.
9 changes: 1 addition & 8 deletions baker/algolia/algoliaUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,10 @@ function generateGdocRecords(
importance: 3,
})
)
.with(OwidGdocType.Fragment, () => ({
.with(P.union(OwidGdocType.Fragment, undefined), () => ({
type: "other" as const,
importance: 0,
}))
.with(undefined, () => {
console.error(
`Failed indexing gdoc post ${gdoc.id} (No type)`,
gdoc
)
return { type: "other" as const, importance: 0 }
})
.exhaustive()
}

Expand Down
2 changes: 1 addition & 1 deletion db/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ export const getHomepageId = (
).then((result) => result?.id)
}

export const getImagesMetadataByFilenames = async (
export const getImageMetadataByFilenames = async (
knex: KnexReadonlyTransaction,
filenames: string[]
): Promise<Record<string, ImageMetadata>> => {
Expand Down
2 changes: 1 addition & 1 deletion db/model/Gdoc/GdocBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ export class GdocBase implements OwidGdocBaseInterface {

if (!imagesFilenames.length) return

const imageMetadata = await db.getImagesMetadataByFilenames(
const imageMetadata = await db.getImageMetadataByFilenames(
knex,
imagesFilenames
)
Expand Down
7 changes: 2 additions & 5 deletions db/model/Gdoc/GdocFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
KnexReadonlyTransaction,
knexRaw,
KnexReadWriteTransaction,
getImagesMetadataByFilenames,
getImageMetadataByFilenames,
getPublishedGdocPosts,
} from "../../db.js"
import { enrichedBlocksToMarkdown } from "./enrichedToMarkdown.js"
Expand Down Expand Up @@ -347,10 +347,7 @@ export async function loadGdocFromGdocBase(
await fetchImagesFromDriveAndSyncToS3(knex, gdoc.filenames)
}

const start = Date.now()
await gdoc.loadState(knex)
const end = Date.now()
console.log(`Loaded state for ${gdoc.id} in ${end - start}ms`)

return gdoc
}
Expand Down Expand Up @@ -604,7 +601,7 @@ export async function addImagesToContentGraph(
// Includes fragments so that images in data pages are
// synced to S3 and ultimately baked in bakeDriveImages().
if (filenames.length && gdoc.published) {
const images = await getImagesMetadataByFilenames(trx, filenames)
const images = await getImageMetadataByFilenames(trx, filenames)
const gdocXImagesToInsert: DbInsertPostGdocXImage[] = []
for (const filename in images) {
const image = images[filename] as DbEnrichedImage
Expand Down
35 changes: 21 additions & 14 deletions db/model/Image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
serializeImageRow,
ImagesTableName,
merge,
pick,
excludeUndefined,
} from "@ourworldindata/utils"
import { OwidGoogleAuth } from "../OwidGoogleAuth.js"
Expand All @@ -34,22 +33,17 @@ import {
} from "../../settings/serverSettings.js"
import { KnexReadWriteTransaction, KnexReadonlyTransaction } from "../db.js"
import { at } from "lodash"
import { ENV } from "../../settings/clientSettings.js"

class ImageStore {
images: Record<string, ImageMetadata> | undefined
hasInitialized: boolean = false
isFetchingFromGoogleDrive: boolean = false

constructor() {
setInterval(
async () => {
await this.fetchImageMetadata([])
},
60 * 60 * 1000
)
}
lastFetchTime: number | undefined

async init(): Promise<void> {
// don't prefetch every image in development mode, wait for a specific request first
if (ENV === "development") return
// only one init at a time
while (this.isFetchingFromGoogleDrive) {
await new Promise((resolve) => setTimeout(resolve, 100))
Expand All @@ -65,6 +59,16 @@ class ImageStore {
async fetchImageMetadata(
filenames: string[]
): Promise<Record<string, ImageMetadata | undefined>> {
if (
this.images &&
this.lastFetchTime &&
Date.now() - this.lastFetchTime < 60 * 1000
) {
console.log(
`Skipping image metadata refresh since last fetch was less than a minute ago`
)
return this.images
}
this.isFetchingFromGoogleDrive = true
try {
console.log(
Expand Down Expand Up @@ -157,6 +161,7 @@ class ImageStore {
throw error
} finally {
this.isFetchingFromGoogleDrive = false
this.lastFetchTime = Date.now()
}
}

Expand All @@ -173,11 +178,11 @@ class ImageStore {
}
}

export const imageStore = new ImageStore()
const _imageStore = new ImageStore()

export async function getImageStore(): Promise<ImageStore> {
await imageStore.init()
return imageStore
await _imageStore.init()
return _imageStore
}

export const s3Client = new S3Client({
Expand Down Expand Up @@ -236,12 +241,14 @@ export class Image implements ImageMetadata {
if (
stored.updatedAt !== fresh.updatedAt ||
stored.defaultAlt !== fresh.defaultAlt ||
stored.originalWidth !== fresh.originalWidth
stored.originalWidth !== fresh.originalWidth ||
stored.originalHeight !== fresh.originalHeight
) {
await fresh.fetchFromDriveAndUploadToS3()
stored.updatedAt = fresh.updatedAt
stored.defaultAlt = fresh.defaultAlt
stored.originalWidth = fresh.originalWidth
stored.originalHeight = fresh.originalHeight
await updateImage(knex, stored.id, {
updatedAt: fresh.updatedAt,
defaultAlt: fresh.defaultAlt,
Expand Down
3 changes: 2 additions & 1 deletion devTools/updateImageHeights/update-image-heights.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { imageStore } from "../../db/model/Image.js"
import { getImageStore } from "../../db/model/Image.js"
import * as db from "../../db/db.js"
import * as lodash from "lodash"
import { exit } from "../../db/cleanup.js"

async function updateImageHeights() {
const imageStore = await getImageStore()
const transaction = await db.knexInstance().transaction()
const filenames = await db
.knexRaw<{ filename: string }>(
Expand Down

0 comments on commit dc4c6f0

Please sign in to comment.