Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Upstash Redis REST SDK in useResponseCache with Redis cache as store #1218

Open
dthyresson opened this issue Jan 20, 2022 · 11 comments

Comments

@dthyresson
Copy link
Contributor

dthyresson commented Jan 20, 2022

Currently, useReponseCache offers a LRU and a Redis cache option.

The redis-cache relies on ioredis as seen here: https://github.com/dotansimha/envelop/blob/cdb32401bc385ca4d3503c4bc6b23ddb1a5909c6/packages/plugins/response-cache-redis/src/redis-cache.ts#L1

  /**
   * Redis instance
   * @see Redis.Redis https://github.com/luin/ioredis
   */
  redis: Redis.Redis;

And then any gets, sets, keys, or smember checks use the Redis client; for example:

    // find the responseIds for the entity
    const responseIds = await store.smembers(entity);

Describe the solution you'd like

Upstash is a serverless database service compatible with Redis® API.

They offer a REST API and a Javascript SDK: https://docs.upstash.com/redis/features/javascriptsdk

The advantage of this over a Redis client in the serverless world (where your GraphQL queries will be done in a Lambda like with RedwoodJS) is that it's less likely to run into connection limits. Other Redis offerings have 10, 20, 40 connections and base pricing on that where with Upstash the pricing is per usage.

Use upstash-redis in serverless functions if you expect high number of concurrent connections​

Serverless functions scale up fast. This can cause some issues if you need persistent connections. REST based upstash-redis fits better in such cases as it does not require a TCP connection with its stateless design.

Also, the Rest client works well on the Edge in a Netlify or Vercel edge handler/function.

However, because the current cache implementation needs a client to invoke get etc, one cannot easily use the Upstash SDK:

For example (their sample code):

import { auth, set } from '@upstash/redis';

(async () => {
    try {
        auth('UPSTASH_REDIS_REST_URL', 'UPSTASH_REDIS_REST_TOKEN');
        const { data, error } = await set('key', 'value');
        if (error) throw error;
        console.log(data);
        // -> "OK"
    } catch (error) {
        console.error(error);
    }
})();

Notice that here set is a method, but not like store.set() on the client.

Perhaps create another redis cache that uses Upstash specifically?

Would this be part of https://github.com/dotansimha/envelop/tree/main/packages/plugins/response-cache-redis/src or an entirely new plugin just for Upstash?

Other

Or, perhaps there is a way to modify the SDK such that there is a client that can be imported (here? https://github.com/upstash/upstash-redis/blob/master/src/index.ts) and then the plugin can have as is?

  • Question: The REST API supports pipeline but not 100% certain if the SDK does.

Additional context

@enesakar
Copy link

@dthyresson You can instantiate a new client as here

Pipeline will be supported by SDK soon (in ~2 weeks)

@dthyresson
Copy link
Contributor Author

@dthyresson You can instantiate a new client as here

Pipeline will be supported by SDK soon (in ~2 weeks)

Thanks! I completely missed those docs.

I’ll keep a watch for pipeline support since with that I think can just drop in the Upstash client and be good to go. Currently the pipeline command is used.

@dthyresson
Copy link
Contributor Author

I’ll keep this issue open as a reminder but I think it can become an issue to add documentation for using the Upstash Sdk instead.

@dthyresson
Copy link
Contributor Author

dthyresson commented May 19, 2022

Hi @enesakar I recently got back into trying out GraphQL response caching with the @upstash/redis client and am encountering the following error:

TypeError: Cannot use 'in' operator to search for 'ex' in PX

in @upstash/redis/script/pkg/commands/set.js:12:22

I Need to do some investigation, but currently looking at:

https://github.com/dotansimha/envelop/blob/4eaaf76d418cf56476d57c176ca876fff89a86b2/packages/plugins/response-cache-redis/src/redis-cache.ts#L71

Where set is used in a pipeline.

Also looking at: https://docs.upstash.com/redis/features/restapi#pipelining

@chronark
Copy link

Hey @dthyresson
The @upstash/redis api is not compatible with ioredis, because we wanted to provide a nicer typescript experience, however it would be pretty easy to write a small adapter.

Judging from the readme example, I should probably just create another package that exports createUpstashCache(..)

So you would use it like this:

import { envelop } from '@envelop/core';
import { useResponseCache } from '@envelop/response-cache';
import { createUpstashCache } from '@envelop/response-cache-upstash';
import { Redis } from "@upstash/redis"

const cache = createUpstashCache(Redis.fromEnv());

const getEnveloped = envelop({
  plugins: [
    // ... other plugins ...
    useResponseCache({ cache }),
  ],
});

Please let me know what you think and I'll implement it afterwards

@dthyresson
Copy link
Contributor Author

@chronark Now that you mention the iodredis client in the package I was trying to use, this all makes so much sense why it wasn't working -- no idea why that didn't occur to me. :) I had a 🤦‍♂️ moment for sure.

A dedicated Upstash Redis client would be great and I know I'd want to use it.

Happy to help with implementation and testing as well.

@chronark
Copy link

Hey @dthyresson I've created a draft PR #1404
Maybe you can try and figure out why the tests are not working yet. I'll retry as well sometime this week.

@dthyresson
Copy link
Contributor Author

Hey @dthyresson I've created a draft PR #1404
Maybe you can try and figure out why the tests are not working yet. I'll retry as well sometime this week.

Hi. I'll try too look too as well but Tim from the RedwoodJS community has offered to help as well; see: https://community.redwoodjs.com/t/guide-power-of-graphql-caching/2624/21?u=dthyresson

@akashkashyap
Copy link

Hi @chronark, is upstash still planning on adding support for this or is it on the back-burner for now? We'd definitely be interested in using upstash if this was production-ready.

@n1ru4l
Copy link
Owner

n1ru4l commented Feb 15, 2023

@akashkashyap a PR is here, currently it needs passing tests: #1404 (comment)

@chronark
Copy link

Hey @akashkashyap
yeah we definitely would like to make this happen

unfortunately I got completely stuck on making the tests work
I'd appreciate a second set of eyes looking at it. I probably just made a stupid mistake

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants