grafana / scenes

Build Grafana dashboards directly in your Grafana app plugins.
https://grafana.com/developers/scenes
Apache License 2.0
133 stars 20 forks source link

ScenesReact: Cache SceneQueryRunners and other scene object by a key / hashing string #788

Open torkelo opened 3 months ago

torkelo commented 3 months ago

With @grafana/scenes-react creating scene object on the fly as react components are rendered (or hooks called) we need a different way to cache query results, query variables and viz panel state.

This PR explores scene object cache and key hashing mechanism.

Example, simple string key:

  const dataProvider = useQueryRunner({
    queries: [{ uid: 'gdev-testdata', refId: 'A', scenarioId: 'random_walk', alias: queryAlias ?? 'env = $env' }],
    maxDataPoints: maxDataPoints,
    cacheKey: "My unique cache key string",
  });

Example: Object as key

  const queries = [{ uid: 'gdev-testdata', refId: 'A', scenarioId: 'random_walk', alias: queryAlias ?? 'env = $env' }];

  const dataProvider = useQueryRunner({
    queries,
    maxDataPoints: maxDataPoints,
    cacheKey: queries,
  });

By default the system will get the hash key by doing JSON.stringify on objects (but with sorted properties so property order does not matter), same as react-query.

cacheKey can also be an array so you can combine multiple strings (or numbers) or object values

  const queries = [{ uid: 'gdev-testdata', refId: 'A', scenarioId: 'random_walk', alias: queryAlias ?? 'env = $env' }];

  const dataProvider = useQueryRunner({
    queries,
    maxDataPoints: maxDataPoints,
    cacheKey: [queries, maxDataPoints],
  });

If you have really large query objects and want faster hashing by reference there is a util function cacheByRef which returns a unique number for a given object reference.

The cache key hashing will also always append the scene object constructor name to the key to avoid conflicts when same cache key is used for different SceneObject types.

torkelo commented 3 months ago

@leeoniya yes, the hashing by reference is for those cases. But this method described here is not to be used for core dashboards (at least not initially, as there we cache the full scene), only for custom scene apps.