So, I'm stilling learning the JS/Node way from a long time in other languages.
因此,我仍然在用其他语言长期学习JS/Node。
I have a tiny micro-service that reads from a redis channel, temp stores it in a working channel, does the work, removes it, and moves on. If there is more in the channel it re-runs immediately. If not, it sets a timeout and checks again in 1 second.
我有一个小的微服务,从redis通道读取数据,temp将其存储在一个工作通道中,完成工作,删除它,然后继续。如果有更多的频道,它会立即重新运行。如果不是,则设置一个超时,并在1秒内再次检查。
It works fine...but timeout polling doesn't seem to be the "correct" way to approach this. And I haven't found much about using BRPOPLPUSH to try to block (vs. RPOPLPUSH) and wait in Node....or other options like that. (Pub/Sub isn't an option here...this is the only listener, and it may not always be listening.)
它工作正常…但是超时轮询似乎并不是解决这个问题的“正确”方法。我还没有找到关于使用BRPOPLPUSH试图阻止(vs RPOPLPUSH)等节点....或者其他类似的选择。(这里没有酒吧/潜水艇……)这是唯一的倾听者,它可能并不总是在倾听。
Here's the short essence of what I'm doing:
以下是我所做的简短的要点:
var Redis = require('ioredis');
var redis = new Redis();
var redisLoop = function () {
redis.rpoplpush('channel', 'channel-working').then(function (result) {
if (result) {
processJob(result); //do stuff
//delete the item from the working channel, and check for another item
redis.lrem('channel-working', 1, result).then(function (result) { });
redisLoop();
} else {
//no items, wait 1 second and try again
setTimeout(redisLoop, 1000);
}
});
};
redisLoop();
I feel like I'm missing something really obvious. Thanks!
我觉得我错过了一些很明显的东西。谢谢!
1 个解决方案
#1
2
BRPOPLPUSH
doesn't block in Node, it blocks in the client. In this instance I think it's exactly what you need to get rid of the polling.
BRPOPLPUSH不会在节点中阻塞,它会在客户机中阻塞。在这种情况下,我认为这正是您需要摆脱轮询的地方。
var Redis = require('ioredis');
var redis = new Redis();
var redisLoop = function () {
redis.brpoplpush('channel', 'channel-working', 0).then(function (result) {
// because we are using BRPOPLPUSH, the client promise will not resolve
// until a 'result' becomes available
processJob(result);
// delete the item from the working channel, and check for another item
redis.lrem('channel-working', 1, result).then(redisLoop);
});
};
redisLoop();
Note that redis.lrem
is asynchronous, so you should use lrem(...).then(redisLoop)
to ensure that your next tick executes only after the item is successfully removed from channel-working
.
注意,复述。lrem是异步的,所以您应该使用lrem(…)然后(redisLoop)来确保您的下一个tick只在成功地从通道工作中删除后才执行。
#1
2
BRPOPLPUSH
doesn't block in Node, it blocks in the client. In this instance I think it's exactly what you need to get rid of the polling.
BRPOPLPUSH不会在节点中阻塞,它会在客户机中阻塞。在这种情况下,我认为这正是您需要摆脱轮询的地方。
var Redis = require('ioredis');
var redis = new Redis();
var redisLoop = function () {
redis.brpoplpush('channel', 'channel-working', 0).then(function (result) {
// because we are using BRPOPLPUSH, the client promise will not resolve
// until a 'result' becomes available
processJob(result);
// delete the item from the working channel, and check for another item
redis.lrem('channel-working', 1, result).then(redisLoop);
});
};
redisLoop();
Note that redis.lrem
is asynchronous, so you should use lrem(...).then(redisLoop)
to ensure that your next tick executes only after the item is successfully removed from channel-working
.
注意,复述。lrem是异步的,所以您应该使用lrem(…)然后(redisLoop)来确保您的下一个tick只在成功地从通道工作中删除后才执行。