2011-10-08 17 views
5

Vì vậy, nút hoạt động tốt với tôi. Tôi có một ứng dụng máy chủ rất cụ thể về cơ bản chấp nhận các yêu cầu để thực hiện một thủ tục cụ thể CPU-ràng buộc, và nó thực hiện một chương trình C để làm như vậy. Thing là, nếu tôi có nhiều khách hàng, rất có thể tôi sẽ nhận được nhiều phiên bản của cùng một yêu cầu. Nó sẽ là một tối ưu hóa tốt đẹp bằng cách nào đó xử lý một cách rõ ràng, bằng cách thực hiện một bộ nhớ cache với một cái gì đó của một khóa trên một khóa cụ thể, để các khách hàng khác sẽ đơn giản chờ đợi yêu cầu đó quay lại và sao chép phản hồi của nó.Cách tạo bộ nhớ cache trong node.js xử lý rõ ràng cho các yêu cầu trùng lặp đồng thời cho hoạt động liên kết CPU

Nhưng tôi mới làm quen với nút, vì vậy tôi không biết cách xử lý cơ chế này thành cơ chế xử lý yêu cầu bộ định tuyến nút cơ bản của tôi. Rõ ràng tôi có thể làm điều đó trong ngôn ngữ x sử dụng nguyên thủy cơ bản concurrency, nhưng tôi biết rằng nút là sự kiện theo định hướng và tôi nghĩ rằng điều này có thể được thực hiện khá thanh lịch trong một cách evented. Ý tưởng?

Trả lời

0

Trong thế giới phía máy khách của JavaScript, bạn thường lưu trữ các mục trong một mảng. Tôi cũng là một nút mới, vì vậy xin tha thứ nếu đây không phải là câu trả lời bạn đang tìm kiếm, nhưng nó đáng để thử.

Bạn có thể thiết lập một mảng trống khi máy chủ bắt đầu và lưu trữ kết quả bằng một băm đặc biệt của một số loại dựa trên yêu cầu nhận được. Điều này có vẻ như một giải pháp khả thi.

Ví dụ:

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"); 
+0

Tôi nghĩ rằng bạn đang đi đúng hướng, mối quan tâm chính của tôi là liệu tôi có cần xử lý đồng thời hay không khi kiểm tra mảng khóa và cách xử lý chờ phản hồi quay lại nếu khóa được đăng ký nhưng giá trị chưa có sẵn. những gì tôi thực sự cần là một cơ chế đồng thời của một số loại kết hợp với một cách để đăng ký một sự kiện cho khách hàng để thức dậy khi giá trị trở nên có sẵn. đó là một phần tôi thực sự bị mắc kẹt trên – William

+0

đoán tôi có thể có bộ nhớ cache duy trì một bộ phát sự kiện cho mỗi phím để cho phép bạn đăng ký? sau đó tôi chỉ phải đối phó với concurrency – William

0

Dễ dàng peasy .. Node.js là đơn luồng, do đó yêu cầu ràng buộc CPU đầu tiên đang chặn máy chủ anyway .. vì vậy hãy ghi nhớ kết quả. Về cơ bản, bạn thiết lập một băm với khóa được yêu cầu và trước khi gọi chương trình C, hãy kiểm tra hàm băm. Nếu nó ở đó, trả lại, bạn đang làm xong. Nếu không, hãy chạy chương trình C, dán kết quả vào băm tại khóa được yêu cầu trước khi trở về, rồi trả về.

+0

yeah man i grok cache là gì nhưng vấn đề là nhất quán. Tôi đã được dạy để suy nghĩ về bất kỳ có thể "đặt hàng" nhưng tôi không hiểu lập kế hoạch của nút cũng đủ. bạn đang nói rằng tất cả các hoạt động là nguyên tử? tức là tôi không cần phải lo lắng về thread Một yêu cầu, thread A bắt đầu công việc, thread B yêu cầu, thread B bắt đầu công việc, thread A trả về, cập nhật bộ nhớ cache, thread B trả về, cập nhật bộ nhớ cache. Hiểu ý tôi chứ? – William

+0

Không có chủ đề nào. Vâng, được rồi, * 1 * thread. Do đó, tất cả các sự kiện đều được lên kế hoạch hợp tác. Đó là lý do tại sao bạn phải cẩn thận về xử lý sự kiện mà làm rất nhiều; nó có 'sàn' cho đến khi nào nó muốn, cho đến khi nó trở lại. Vì vậy, Yêu cầu A đến, Yêu cầu A bắt đầu xử lý, Yêu cầu B đi vào, nhưng vòng lặp sự kiện không quay lại, vì vậy yêu cầu B nằm trong hàng đợi của socket cho đến khi Trình xử lý yêu cầu trả về. –

3

Một số câu trả lời ở trên, nhưng không có câu nào thực sự xử lý yêu cầu paralel cho cùng một tài nguyên một cách chính xác.

Bạn không cần phải lo lắng về sự tương tranh khi kiểm tra khóa bộ nhớ cache, vì nút là môi trường một luồng. Tất cả các hành động của bạn thực sự là nguyên tử. Tuy nhiên, tất cả các hoạt động không đồng bộ trong nút sẽ khiến nó chấp nhận các yêu cầu tiếp theo. Vì vậy, bạn cần phải xử lý các yêu cầu trùng lặp đồng thời, tại đây được giải quyết với việc đăng ký người quan sát đến 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"); 
Các vấn đề liên quan