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

Parse Server Redis Sentinel Support for Live Query #4452

Closed
alkebuware opened this issue Dec 24, 2017 · 3 comments
Closed

Parse Server Redis Sentinel Support for Live Query #4452

alkebuware opened this issue Dec 24, 2017 · 3 comments

Comments

@alkebuware
Copy link

Issue Description

It appears that Parse Server doesn't support redis-sentinel URLs for Live Query. When passing in a redis-sentinel url, the underlying redis module throws an exception

Steps to reproduce

  1. Put a redis-sentinel URI in ParseServer's liveQuery block's redisURL
  2. Put the same redis-sentinel URI in the options for createLiveQueryServer
var api = new ParseServer({
  ...
  liveQuery: {
    classNames: ['Foo','Bar'],
    redisURL: 'redis-sentinel://redis0.rs.local:6379,redis1.rs.local:6379,redis2.rs.local:6379'
  }
});

ParseServer.createLiveQueryServer(httpServer, {
  ...
  redisURL: 'redis-sentinel://redis0.rs.local:6379,redis1.rs.local:6379,redis2.rs.local:6379'
});

Expected Results

I was hoping that Parse Server would be able to support Redis Sentinel URIs as it allows for automatic failover in production environments. Similiar to how it can accept the MongoDB URI of a replica set

Actual Outcome

The below exception was thrown instead when passing in the redisURL: redis-sentinel://redis0.rs.local:6379,redis1.rs.local:6379,redis2.rs.local:6379

node_redis: WARNING: You passed "redis-sentinel" as protocol instead of the "redis" protocol!
node_redis: WARNING: You passed "redis-sentinel" as protocol instead of the "redis" protocol!

/opt/parseserver/node_modules/parse-server/lib/ParseServer.js:218
throw err;
^
ReplyError: ERR invalid DB index
at parseError (/opt/parseserver/node_modules/redis-parser/lib/parser.js:193:12)
at parseType (/opt/parseserver/node_modules/redis-parser/lib/parser.js:303:14)

Environment Setup

  • Server

    • parse-server version: 2.7.1
    • Operating System: Ubuntu 16.04
    • Hardware: n/a
    • Localhost or remote server?: GCP Compute Instance
  • Database

    • MongoDB version: n/a
    • Storage engine: n/a
    • Hardware: n/a
    • Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): n/a

Logs/Trace

node_redis: WARNING: You passed "redis-sentinel" as protocol instead of the "redis" protocol!
node_redis: WARNING: You passed "redis-sentinel" as protocol instead of the "redis" protocol!

/opt/parseserver/node_modules/parse-server/lib/ParseServer.js:218
throw err;
^
ReplyError: ERR invalid DB index
at parseError (/opt/parseserver/node_modules/redis-parser/lib/parser.js:193:12)
at parseType (/opt/parseserver/node_modules/redis-parser/lib/parser.js:303:14)

@flovilmart
Copy link
Contributor

HI @alkebuware you're right, we don't support redis-sentinel out of the box, but you can write your own adapter for it if that's something you're interested in.

A custom pubsub adapter should be pretty simple to write based on the redis adapter

There is this redis-sentinel package maintained by Docusign that would probably do the trick.

// setup redissentinel
var RedisSentinel = require('node-redis-sentinel-client');

function createPublisher(options) {
  return RedisSentinel.createClient(options);
}

function createSubscriber(options) {
  return RedisSentinel.createClient(options);
}

let RedisSentinelPubsub = {
  createPublisher,
  createSubscriber
}

new ParseServer({
  ... 
  /* for publishing */
  liveQuery: {
    classNames: ..., // your classNames here
    pubSubAdapter: RedisSentinelPubsub,
  },
  /* for the subscriptions */
  liveQueryServerOptions: {
    pubSubAdapter: RedisSentinelPubSub,
  },
});

You'll probably need to run npm install --save redis-sentinel-client

Note that I didn't test the code, just out of my mind this is probably working :)

@alkebuware
Copy link
Author

@flovilmart ok give that a try. Thanks for pointing me in the right direction.

@isokosan
Copy link

For anyone who might stumble here, make sure to have two separate redis clients for the publisher and the subscriber. Here is an example io-redis adapter that gets the job done:

const Redis = require('ioredis')

class IORedisPubSubAdapter {
  constructor (config) {
    this.pub = new Redis(config)
    this.sub = new Redis(config)
  }

  createPublisher () {
    return this.pub
  }

  createSubscriber () {
    return this.sub
  }
}

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

3 participants