More cache hint tags for Item etc

Trying to get that Item page fast!

I don't really want to ship this as-is, because I'd really like to get stale-while-revalidate working before shipping a 1-week cache timer… will be tricky though!
This commit is contained in:
Emi Matchu 2021-02-02 17:51:54 -08:00
parent f0b3047112
commit c00df62bdc
4 changed files with 33 additions and 23 deletions

View file

@ -6,7 +6,14 @@ const connectToDb = require("./db");
const buildLoaders = require("./loaders"); const buildLoaders = require("./loaders");
const rootTypeDefs = gql` const rootTypeDefs = gql`
directive @cacheControl(maxAge: Int!) on FIELD_DEFINITION | OBJECT enum CacheScope {
PUBLIC
PRIVATE
}
directive @cacheControl(
maxAge: Int
scope: CacheScope
) on FIELD_DEFINITION | OBJECT
type Mutation type Mutation
type Query type Query

View file

@ -1,8 +1,8 @@
const { gql } = require("apollo-server"); const { gql } = require("apollo-server");
const { getRestrictedZoneIds } = require("../util"); const { getRestrictedZoneIds, oneWeek, oneHour } = require("../util");
const typeDefs = gql` const typeDefs = gql`
type Item { type Item @cacheControl(maxAge: ${oneWeek}) {
id: ID! id: ID!
name: String! name: String!
description: String! description: String!
@ -19,26 +19,26 @@ const typeDefs = gql`
# item was added so long ago that we don't have this field! # item was added so long ago that we don't have this field!
createdAt: String createdAt: String
currentUserOwnsThis: Boolean! currentUserOwnsThis: Boolean! @cacheControl(scope: PRIVATE)
currentUserWantsThis: Boolean! currentUserWantsThis: Boolean! @cacheControl(scope: PRIVATE)
# How many users are offering/seeking this in their public trade lists. # How many users are offering/seeking this in their public trade lists.
numUsersOfferingThis: Int! numUsersOfferingThis: Int! @cacheControl(maxAge: ${oneHour})
numUsersSeekingThis: Int! numUsersSeekingThis: Int! @cacheControl(maxAge: ${oneHour})
# The trades available for this item, grouped by offering vs seeking. # The trades available for this item, grouped by offering vs seeking.
tradesOffering: [ItemTrade!]! tradesOffering: [ItemTrade!]! @cacheControl(maxAge: 0)
tradesSeeking: [ItemTrade!]! tradesSeeking: [ItemTrade!]! @cacheControl(maxAge: 0)
# How this item appears on the given species/color combo. If it does not # How this item appears on the given species/color combo. If it does not
# fit the pet, we'll return an empty ItemAppearance with no layers. # fit the pet, we'll return an empty ItemAppearance with no layers.
appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance! appearanceOn(speciesId: ID!, colorId: ID!): ItemAppearance! @cacheControl(maxAge: ${oneHour})
# This is set manually by Support users, when the pet is only for e.g. # This is set manually by Support users, when the pet is only for e.g.
# Maraquan pets, and our usual auto-detection isn't working. We provide # Maraquan pets, and our usual auto-detection isn't working. We provide
# this for the Support UI; it's not very helpful for most users, because it # this for the Support UI; it's not very helpful for most users, because it
# can be empty even if the item _has_ an auto-detected special color. # can be empty even if the item _has_ an auto-detected special color.
manualSpecialColor: Color manualSpecialColor: Color @cacheControl(maxAge: 0)
# This is set manually by Support users, when the item _seems_ to fit all # This is set manually by Support users, when the item _seems_ to fit all
# pets the same because of its zones, but it actually doesn't - e.g., # pets the same because of its zones, but it actually doesn't - e.g.,
@ -46,30 +46,30 @@ const typeDefs = gql`
# provide this for the Support UI; it's not very helpful for most users, # provide this for the Support UI; it's not very helpful for most users,
# because it's only used at modeling time. This value does not change how # because it's only used at modeling time. This value does not change how
# layer data from this API should be interpreted! # layer data from this API should be interpreted!
explicitlyBodySpecific: Boolean! explicitlyBodySpecific: Boolean! @cacheControl(maxAge: 0)
# Get the species that we need modeled for this item for the given color. # Get the species that we need modeled for this item for the given color.
# #
# NOTE: Most color IDs won't be accepted here. Either pass the ID of a # NOTE: Most color IDs won't be accepted here. Either pass the ID of a
# major special color like Baby (#6), or leave it blank for standard # major special color like Baby (#6), or leave it blank for standard
# bodies like Blue, Green, Red, etc. # bodies like Blue, Green, Red, etc.
speciesThatNeedModels(colorId: ID): [Species!]! speciesThatNeedModels(colorId: ID): [Species!]! @cacheControl(maxAge: ${oneHour})
# Return a single ItemAppearance for this item. It'll be for the species # Return a single ItemAppearance for this item. It'll be for the species
# with the smallest ID for which we have item appearance data. We use this # with the smallest ID for which we have item appearance data. We use this
# on the item page, to initialize the preview section. (You can find out # on the item page, to initialize the preview section. (You can find out
# which species this is for by going through the body field on # which species this is for by going through the body field on
# ItemAppearance!) # ItemAppearance!)
canonicalAppearance: ItemAppearance canonicalAppearance: ItemAppearance @cacheControl(maxAge: ${oneHour})
# All zones that this item occupies, for at least one body. That is, it's # All zones that this item occupies, for at least one body. That is, it's
# a union of zones for all of its appearances! We use this for overview # a union of zones for all of its appearances! We use this for overview
# info about the item. # info about the item.
allOccupiedZones: [Zone!]! allOccupiedZones: [Zone!]! @cacheControl(maxAge: ${oneHour})
# All bodies that this item is compatible with. Note that this might return # All bodies that this item is compatible with. Note that this might return
# the special representsAllPets body, e.g. if this is just a Background! # the special representsAllPets body, e.g. if this is just a Background!
compatibleBodies: [Body!]! compatibleBodies: [Body!]! @cacheControl(maxAge: ${oneHour})
} }
type ItemAppearance { type ItemAppearance {

View file

@ -3,18 +3,17 @@ const {
capitalize, capitalize,
getPoseFromPetState, getPoseFromPetState,
getRestrictedZoneIds, getRestrictedZoneIds,
oneWeek,
} = require("../util"); } = require("../util");
const typeDefs = gql` const typeDefs = gql`
# Cache for 1 week (unlikely to change) type Color @cacheControl(maxAge: ${oneWeek}) {
type Color @cacheControl(maxAge: 604800) {
id: ID! id: ID!
name: String! name: String!
isStandard: Boolean! isStandard: Boolean!
} }
# Cache for 1 week (unlikely to change) type Species @cacheControl(maxAge: ${oneWeek}) {
type Species @cacheControl(maxAge: 604800) {
id: ID! id: ID!
name: String! name: String!
@ -38,7 +37,7 @@ const typeDefs = gql`
UNKNOWN # for when we have the data, but we don't know what it is UNKNOWN # for when we have the data, but we don't know what it is
} }
type Body { type Body @cacheControl(maxAge: ${oneWeek}) {
id: ID! id: ID!
species: Species! species: Species!
@ -49,8 +48,7 @@ const typeDefs = gql`
representsAllBodies: Boolean! representsAllBodies: Boolean!
} }
# Cache for 1 week (unlikely to change) type PetAppearance @cacheControl(maxAge: ${oneWeek}) {
type PetAppearance @cacheControl(maxAge: 604800) {
id: ID! id: ID!
species: Species! species: Species!
color: Color! color: Color!

View file

@ -148,4 +148,9 @@ module.exports = {
loadBodyName, loadBodyName,
logToDiscord, logToDiscord,
normalizeRow, normalizeRow,
// For Apollo's @cacheControl maxAge: time in seconds.
oneWeek: 604800,
oneDay: 86400,
oneHour: 3600,
}; };