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

Parallel .multi requests with custom scripts result in NOSCRIPT error #1303

Closed
marcbachmann opened this issue Mar 19, 2021 · 1 comment · Fixed by #1304
Closed

Parallel .multi requests with custom scripts result in NOSCRIPT error #1303

marcbachmann opened this issue Mar 19, 2021 · 1 comment · Fixed by #1304
Labels

Comments

@marcbachmann
Copy link
Collaborator

marcbachmann commented Mar 19, 2021

In a project I'm working on we're using ioredis with redis streams and some custom lua scripts.
Locally and also on our CI, we've observed that there are NOSCRIPT errors and most times they occur in the same tests.

I've digged down into the issue and found out that ioredis doesn't queue the second command as it thinks the script is already initialized. The problematic line is here: https://github.com/luin/ioredis/blob/master/lib/pipeline.ts#L321

Most likely we only want to set the variable once we get a successful exists check back from redis.
So we could move the assignment after the load promise: https://github.com/luin/ioredis/blob/master/lib/pipeline.ts#L341

Reproduction:

// DEBUG=ioredis.* node index.js
async function start () {
  const Redis = require('ioredis')
  const random = Math.random()
  const redis = new Redis()
  redis.defineCommand('something', {numberOfKeys: 0, lua: `return "${random}"`})
  const [[first], [second]] = await Promise.all([
    redis.multi([['something']]).exec(),
    redis.multi([['something']]).exec()
  ])

  console.log({first: first[0], second: second[0]})

  redis.disconnect()
}

start()

Output:

  ioredis:redis status[localhost:6379]: [empty] -> connecting +0ms
  ioredis:redis queue command[localhost:6379]: 0 -> script([ 'exists', '6ddff55aad13ecdf2763faa3a884ec066ebf0724' ]) +2ms
  ioredis:redis queue command[localhost:6379]: 0 -> multi([]) +2ms
  ioredis:redis queue command[localhost:6379]: 0 -> evalsha([ '6ddff55aad13ecdf2763faa3a884ec066ebf0724', '0' ]) +0ms
  ioredis:redis queue command[localhost:6379]: 0 -> exec([]) +0ms
  ioredis:redis status[127.0.0.1:6379]: connecting -> connect +5ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> info([]) +0ms
  ioredis:redis status[127.0.0.1:6379]: connect -> ready +3ms
  ioredis:connection send 4 commands in offline queue +0ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> script([ 'exists', '6ddff55aad13ecdf2763faa3a884ec066ebf0724' ]) +0ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> multi([]) +0ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> evalsha([ '6ddff55aad13ecdf2763faa3a884ec066ebf0724', '0' ]) +0ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> exec([]) +1ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> script([ 'load', 'return "0.42066807125457295"' ]) +0ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> multi([]) +2ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> evalsha([ '6ddff55aad13ecdf2763faa3a884ec066ebf0724', '0' ]) +0ms
  ioredis:redis write command[127.0.0.1:6379]: 0 -> exec([]) +0ms
{
  first: null,
  second: ReplyError: NOSCRIPT No matching script. Please use EVAL.
      at parseError (/node_modules/redis-parser/lib/parser.js:179:12)
      at parseType (/node_modules/redis-parser/lib/parser.js:302:14)
}
  ioredis:redis status[127.0.0.1:6379]: ready -> close +5ms
  ioredis:connection skip reconnecting since the connection is manually closed. +8ms
  ioredis:redis status[127.0.0.1:6379]: close -> end +0ms
@ioredis-robot
Copy link
Collaborator

🎉 This issue has been resolved in version 4.24.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

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

Successfully merging a pull request may close this issue.

2 participants