2017-10-23 8 views
0

메모리 DB를 사용하여 응답을 스트리밍 할 수 있습니까?NodeJS - 메모리 DB를 사용하여 응답을 스트리밍 할 수 있습니까?

메모리 데이터베이스에 Loki JS를 사용하고 있습니다. 테이블의 전체 내용을 반환해야하는 특정 리소스가 있습니다 (페이지 매김 될 수 없음). 테이블은 약 300MB 인 500,000 개 항목까지 커질 수 있습니다. 다른 경우

, 나는 파일을 얻을하여 사용자에게 스트리밍 fs.createReadStream을 사용한이 큰 파일을 위해 좋은 일했다

fs.createReadStream('zips.json') 
    .on('data', function() { 
    res.write(...) 
    }) 
    .on('end', function() { 
    res.end(); 
    }) 

,하지만 어떻게 내가는 사용하여 상응하는 뭔가를 할 수 메모리 DB에?

const items = lokiDb.addCollection('items'); 
items.insert('a bunch of items ...'); 

// I would now like to stream items via res.write 
res.write(items) 

현재 res.write(items)은 노드가 전체 응답을 한 번에 보내려고하므로 메모리 문제가 발생합니다.

답변

0

내가 알 수있는 한, Loki에는 네이티브 스트림 공급자가 없습니다. 그러나 놓친 것일 수도 있습니다. 내가 올바른 해요 경우

const items = lokiDb.addCollection('items'); 
items.on('insert', (results) => { 
    res.write(results); 
}); 

items.insert('a bunch of items ...'); 
0

는, 기본적으로 문제가 readStreams는 파일에서 읽어이며, : 당신이 대신 수행 할 수 있습니다 것은 컬렉션에서 '삽입'이벤트를 수신과 같은, 그 쓰기입니다 메모리 내 데이터 구조에서 읽으려고합니다. 해결책은 약간 프로토 타입 stream.Readable._read 방법 수정, 자신의 readStream 클래스를 정의 할 수 있습니다 :

var util = require('util'); 
var stream = require('stream'); 

"use strict"; 
var begin=0, end=0; 
var options = { 
    highWaterMark: 16384, 
    encoding:  null, 
    objectMode:  false 
}; 

util.inherits(InMemoryStream, stream.Readable); 

function InMemoryStream(userDefinedOptions, resource){ 

    if (userDefinedOptions){ 
     for (var key in userDefinedOptions){ 
      options.key = userDefinedOptions[key]; 
     } 
    } 

    this.resource = resource; 
    stream.Readable.call(this, options); 
} 


InMemoryStream.prototype._read = function(size){ 

    end += size; 
    this.push(this.resource.slice(begin, end)); 
    begin += size; 

    } 

exports.InMemoryStream = InMemoryStream;  
exports.readStream = function(UserDefinedOptions, resource){ 
    return new InMemoryStream(UserDefinedOptions, resource); 
} 

당신은 (다음 예 배열에서) 메모리의 자료 구조를 변환 readStream에, 그리고 파이프 writeStream을 통해 다음과 같이 처리합니다.

"use strict"; 

var fs = require('fs'); 
var InMemoryStream = require('/home/regular/javascript/poc/inmemorystream.js'); 

var stored=[], writestream, config={}; 

config = { 
    encoding: null, 
    fileToRead: 'raphael.js', 
    fileToWrite: 'secondraphael.js' 
} 

fs.readFile(config.fileToRead, function(err, data){ 
    if (err) return console.log('Error when opening file', err); 
    stored = data; 

    var inMemoryStream = InMemoryStream.readStream({encoding: config.encoding}, stored); 
    writestream = fs.createWriteStream(config.fileToWrite); 
    inMemoryStream.pipe(writestream); 

    inMemoryStream.on('error', function(err){ 
     console.log('in memory stream error', err); 
    }); 


}); 
+0

죄송합니다, 바보 같은 예; 똑바로 생각하지 않았습니다 : 저장된 저장은 단순히 버퍼가됩니다. 다음과 같이 prototype에서 push()를 변경하면 적어도 문자열 기반 데이터의 경우 괜찮을 것입니다. this.push (this.resource.join ('') .slice (begin, end)); – mycena