1

I have a GraphQL request that is very slow (10 seconds for 1700 records) but that I could cache easily with a 10 minutes TTL. Here it is:

query GetMapAssets($first: Int, $page: Int) {
        assets(first: $first, page: $page, where: {
            AND: [
                {
                    column: "mag_id"
                    operator: IS_NOT_NULL
                }
                {
                    column: "last_mag_data_id"
                    operator: IS_NOT_NULL
                }
            ]
        }) {
            paginatorInfo {
                count
                currentPage
                lastPage
                total
            }
            data {
                id
                reference
                lastPosition {
                    latitude
                    longitude
                }
                asset_type {
                    id
                    name
                }
                state {
                    id
                }
                branches {
                    data {
                        id
                    }
                }
                sites {
                    data {
                        site_type {
                            id
                            name
                        }
                    }
                }
                mag {
                    mag_id
                }
                asset_group {
                    id
                }
                date_enter_site
            }
        }
    }

According to the documentation, I added a @cache directive on my Query:

extend type Query @guard(with: ["passport", "web"]) {
    assets(
        orderBy: _ @orderBy(columns: [
            "id",
            "reference",
            "buy_value",
            "asset_type_name",
            "asset_mag_id",
            "asset_group_reference",
            "asset_state_name"
        ])
        where: _ @whereConditions
    ): [Asset]
        @paginate(defaultCount: 10, scopes: [
            "filterBranch",
            "assetTypeName",
            "assetMagId",
            "assetGroupReference",
            "assetStateName"
        ])
        @can(ability: "view", model: "App\\Models\\Asset")
        @cache (private: true, maxAge: 600)
    asset(reference: String @where(key: "reference"), id: ID @where(key: "id")): Asset
        @first
        @can(ability: "view", model: "App\\Models\\Asset")
}

type Asset {
    id: ID!
    mag: Mag @belongsTo
    company: Company @belongsTo
    branches(
        orderBy: _ @orderBy(columns: ["id", "name"])
        where: _ @whereConditions
    ): [Branch] @belongsToMany(type: PAGINATOR)
    asset_type: AssetType @belongsTo
    state: AssetState @belongsTo
    reference: String!
    buy_value: Float
    last_mag_data_id: Int
    asset_group: AssetGroup @belongsTo
    responsible(
        orderBy: _ @orderBy(columns: ["id", "name"])
        where: _ @whereConditions
    ): [User] @belongsToMany(relation: "users", type: PAGINATOR)
    shipping_orders: [ShippingOrder] @hasMany(scopes:["tracked"])
    responsibles(
        orderBy: _ @orderBy(columns: ["id", "name"])
        where: _ @whereConditions
    ): [User] @hasMany(relation: "users", type: PAGINATOR)
    mag_datas(
        orderBy: _ @orderBy(columns: ["id", "device_timestamp"])
        where: _ @whereConditions
    ): [MagData] @hasMany(type: PAGINATOR)
    latestMagData: MagData @hasOne
    custom_parameters(
        orderBy: _ @orderBy(columns: ["id", "name"])
        where: _ @whereConditions
    ): [CustomParameter] @morphMany(relation: "custom_parameters", type: PAGINATOR)
    lastTemperature: MagData
    lastPosition: MagData @hasOne
    current_shipping_order: [ShippingOrder] @hasMany(relation: "shipping_orders", scopes: ["tracked"])
    sites(
        orderBy: _ @orderBy(columns: ["id", "name"])
        where: _ @whereConditions
    ): [Site] @belongsToMany(type: PAGINATOR) @can(ability: "view", model: "App\\Models\\Site")
    previous_sites(
        orderBy: _ @orderBy(columns: ["id", "name"])
        where: _ @whereConditions
    ): [Site] @belongsToMany(type: PAGINATOR) @can(ability: "view", model: "App\\Models\\Site")
    date_enter_site: DateTime
}

My cache driver is Redis (on all environnements), my lighthouse cache config looks like this:

    'cache' => [
        'enable' => env('LIGHTHOUSE_CACHE_ENABLE', 'local' !== env('APP_ENV')),
        'key' => env('LIGHTHOUSE_CACHE_KEY', 'lighthouse-schema'),
        'store' => env('LIGHTHOUSE_CACHE_STORE', null),
        'ttl' => env('LIGHTHOUSE_CACHE_TTL', null),
    ],

No matter what I tried, I still have a response time around 10 secondes, leading me to think that I just don't hit the cache.

My Redis is properly configured, since my sessions work on it, and also enabled on my local environnment.

EDIT: Here is the content of my redis after running the Query:

The key for my query looks different from the other, but contains the result when I do a get <key>

1) "company_cache:lighthouse:query:5463d14c79c39a60ba59927e444e37095660a3cc28cf14bf4cc97c2ecb263c34"
2) "company_cache:lighthouse-schema"
3) "company_cache:lighthouse:auth:1:Query::assets:first:2000:page:0:where:{\"operator\":\"=\",\"AND\":[{\"column\":\"mag_id\",\"operator\":\"NotNull\"},{\"column\":\"last_mag_data_id\",\"operator\":\"NotNull\"}]}"
Radyum
  • 99
  • 2
  • 11

1 Answers1

1

You need to debug why the cache isn't working at the level of the cache key and directive:

Is the cache key taking into account all the query arguments, including pagination arguments like $first and $page?

Use the redis-cli and run keys if this is a dev system or use scan on prod. Visually seeing what's being stored will shed some light on this.

Is @cache applied right to assets? What's the TTL?

Turn on Lighthouse debug mode and log the cache usage. In the lighthouse.php configuration file, set 'debug' => true

Does the version of Lighthouse you are using support the @cache directive?

Andrew Arrow
  • 4,248
  • 9
  • 53
  • 80
  • I'm using Lighthouse version 5.71, so @ cache should work. I checked `keys lighthouse-schema` in redis-cli but I have `(empty array)`. Then I tried to enable debug-mode but I don't know where I should look for debug data. – Radyum Jul 19 '23 at 14:36
  • The logs will be written to Laravel's default log file, which is usually storage/logs/laravel.log. You can open this file to see the debug output. – Andrew Arrow Jul 19 '23 at 14:39
  • After more digging: I have actually keys in my redis. I updated the main post because of character limit – Radyum Jul 19 '23 at 15:09