如何在node.js中创建一个缓存,该缓存显式处理CPU绑定操作的同时重复请求

Wil*_*iam 5 node.js

所以节点对我来说很有用.我有一个非常特定的服务器应用程序,它基本上接受执行特定CPU绑定过程的请求,并执行一个C程序来执行此操作.事实是,如果我有多个客户端,我很可能会得到同一请求的多个版本.通过在特定键上实现具有锁定功能的缓存,以某种方式显式处理它将是一个很好的优化,以便其他客户端只需等待该请求返回,并复制其响应.

但我是节点的新手,所以我不知道如何将其安装到我的基本节点路由器请求处理程序机制中.显然我可以使用基本并发原语在语言x中完成它,但我知道该节点是面向事件的,我认为这可以通过一种非常优雅的方式完成.想法?

zze*_*zen 5

上面有几个答案,但没有一个真正正确地处理对同一资源的并行请求。

检查缓存键时无需担心并发问题,因为节点是单线程环境。你所有的行为确实都是原子的。然而,节点中的所有异步操作都会导致它接受进一步的请求。因此,您需要处理并发重叠请求,这里通过将观察者注册到 EventEmmiter 来解决:

var http = require('http'), EventEmitter = require('events').EventEmitter;
var cache = {};

http.createServer(function (req, res) {
   var key = someMagic(req), cached = cache[key]; // get some unique request identifier

   if (!cached) { // if we've never seen this request before
     cached = new EventEmitter(); // make this cache entry an event emitter
     cached.status = 'running';
     handleAsyncRequest(function(result) { // your request handling is probably asynchronous, call this callback when you're done
       cached.response = result; // memoize data
       cached.status = 'finished';
       cached.emit('finished'); // notify all observers waiting for this request
     });

   } else {
     switch(cached.status) { // if existing request, check if it's still running or finished
       case 'finished':
         res.end(cached.response); // send cached response immediately if request has finished
         break;
       case 'running':
         // subscribe as observer; send response when request is finished
         cached.once('finished', function() { res.end(cached.response); });
         break;
     }
   }
}).listen(1337, "127.0.0.1");
Run Code Online (Sandbox Code Playgroud)


Tre*_*vor 0

在 JavaScript 的客户端世界中,您通常将项目缓存在数组中。我也是节点新手,所以如果这不是您正在寻找的答案,请原谅,但值得一试。

您可以在服务器启动时设置一个空数组,并根据收到的请求使用某种特殊的哈希值存储结果。这似乎是一个可行的解决方案。

例如

var http = require('http');
var cache = [];
http.createServer(function (req, res) {
   var obj; 
   if(!cache[key]) {
      obj = .... // logic that gets results
      cache[obj.key] = obj;
    } else {
      obj = cache[key];
    }
}).listen(1337, "127.0.0.1");
Run Code Online (Sandbox Code Playgroud)