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

bug? keyPrefix not added to the KEYS command #239

Closed
Volox opened this issue Jan 28, 2016 · 6 comments
Closed

bug? keyPrefix not added to the KEYS command #239

Volox opened this issue Jan 28, 2016 · 6 comments

Comments

@Volox
Copy link

Volox commented Jan 28, 2016

Hi,
i have a problem with the KEYS command and the use of keyPrefix. It seems that using a prefixed connection the prefix is not passed to the KEYS command.

I created a simple snippet of code to reproduce the problem.

'use strict';
let Promise = require( 'bluebird' );
let Redis = require( 'ioredis' );

const prefix = 'NS:'
// Create an unprefixed connection
let redisNP = new Redis();
// Create an prefixed connection
let redisP = new Redis( {
  keyPrefix: prefix,
} );


let key = 'test:namespace:test';
let matchKey = 'test:*:test';
const data = {
  mytest: 'true',
  'my test2': 5,
};

// Add a namespaced(prefixed) key
redisP.hmset( key, data )
.then( () => {
  // Issue the keys command to the connections
  return Promise
  .props( {
    // Try the prefixed connection
    prefix: redisP.keys( matchKey ),
    // Try the unprefixed connection
    noPrefix: redisNP.keys( matchKey ),
    // Try to manual add the prefix to the  unprefixed connection
    manualPrefix: redisNP.keys( prefix+matchKey ),
  } );
} )
.then( results => {
  // I have 0 prefixed keys, should be 1
  console.log( 'Should be 1', results.prefix.length );
  // I have 0 unprefixed keys, OK
  console.log( 'Should be 0', results.noPrefix.length );
  // I have 1 manually prefixed keys, OK
  console.log( 'Should be 1', results.manualPrefix.length );
  console.log( 'Results: %j', results );
} )
.catch( err => console.error( err, err.stack ) )
.then( () => {
  return [
    redisP.quit(),
    redisNP.quit(),
  ];
} );
@luin
Copy link
Collaborator

luin commented Jan 28, 2016

Actually it's not a bug. ioredis relies on the COMMAND command of Redis to get the position of the keys in a command's parameters. For keys (as well as scan) command, Redis tells ioredis that it doesn't contain a key, so that ioredis won't prefix it.

@Volox
Copy link
Author

Volox commented Jan 28, 2016

Ah ok, i got the point.
But since i am requiring keys it would be nice/useful to use this command transparently no?

@BridgeAR
Copy link
Collaborator

How are you able to determine what keys you actually have in redis, if the keys parameter would be prefixed? This is not possible in that case, so if you want to have the keys command prefixed you might consider adding a arguments transformer to it to always prefix the argument. I do not recommend it though.

@Volox
Copy link
Author

Volox commented Feb 2, 2016

Ok,
but once i got the keys from the keys command i cannot use them coherently with the other commands.
Here is an example:

// Just pretend that it works without promises/callbacks :)

// prefx: "NS:"
let keys = redisP.keys( '*' ); // keys = [ "key1", "NS:key2" ]

// This will NEVER get "key1" because the get is namespaced
let val = redisP.get( keys[0] );
// also i cannot get "NS:key2" because i will get "NS:NS:key2" instead

@luin
Copy link
Collaborator

luin commented Feb 2, 2016

@Volox I agree with you that it is of course a little inconvenience for people who want to use the keyPrefix option as namespaces in order to have multiple applications share a single redis instance.

However, keyPrefix literally means prefix keys with a string, but the parameter of KEY command is a pattern instead of a key name, so that it won't be prefixed.

It's not hard to make the pattern also be prefixed, but I don't want to let ioredis do too much magic. There are other commands that should be prefixed if we handle the KEYS command, for instance, SCAN.

I don't want to mislead people into thinking they can reply on the keyPrefix as namespaces. For example, FLUSHDB actually deletes all the keys in the redis instead of the keys whose name started with keyPrefix.

The workaround is to create another instance for KEYS and SCAN command or just create a wrapper yourself.

@Volox
Copy link
Author

Volox commented Feb 2, 2016

Thanks to all for the support, I see there is no easy solution for this.

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