簡體   English   中英

如何限制flatMap的並發性?

[英]How to limit the concurrency of flatMap?

我正在嘗試使用RxJS編寫一個腳本來處理數百個日志文件,每個文件大約1GB。 腳本的骨架看起來像

Rx.Observable.from(arrayOfLogFilePath)
.flatMap(function(logFilePath){
   return Rx.Node.fromReadStream(logFilePath)
   .filter(filterLogLine)
})
.groupBy(someGroupingFunc)
.map(someFurtherProcessing)
.subscribe(...)

代碼有效,但請注意所有日志文件的過濾步驟將同時啟動。 但是,從文件系統IO性能的角度來看,最好一個接一個地處理一個文件(或者至少將並發限制為幾個文件而不是同時打開所有數百個文件)。 在這方面,我如何以“功能反應方式”實施?

我曾想過調度程序,但無法弄清楚它在這里有什么用處。

您可以使用.merge(maxConcurrent)來限制並發性。 因為.merge(maxConcurrent)一個metaobservable(可觀察的observables)展平為一個observable,你需要用.map替換.flatMap以便輸出是一個metaobservable(“unflat”),然后你調用.merge(maxConcurrent)

Rx.Observable.from(arrayOfLogFilePath)
.map(function(logFilePath){
   return Rx.Node.fromReadStream(logFilePath)
   .filter(filterLogLine)
})
.merge(2) // 2 concurrent 
.groupBy(someGroupingFunc)
.map(someFurtherProcessing)
.subscribe(...)

此代碼尚未經過測試(因為我無法訪問您擁有的開發環境),但這是如何繼續進行的。 RxJS沒有很多具有並發參數的運算符,但你幾乎總能用.merge(maxConcurrent)做你需要的。

我剛剛用RxJs 5解決了類似的問題,所以我希望解決方案可以幫助其他人解決類似的問題。

 // Simulate always processing 2 requests in parallel (when one is finished it starts processing one more), // retry two times, push error on stream if retry fails. //const Rx = require('rxjs-es6/Rx'); // -- Global variabel just to show that it works. -- let parallelRequests = 0; // -------------------------------------------------- function simulateRequest(req) { console.log("Request " + req); // --- To log retries --- var retry = 0; // ---------------------- // Can't retry a promise, need to restart before the promise is made. return Rx.Observable.of(req).flatMap(req => new Promise((resolve, reject) => { var random = Math.floor(Math.random() * 2000); // -- To show that it works -- if (retry) { console.log("Retrying request " + req + " ,retry " + retry); } else { parallelRequests++; } // --------------------------- setTimeout(() => { if (random < 900) { retry++; return reject(req + " !!!FAILED!!!"); } return resolve(req); }, random); })).retry(2).catch(e => Rx.Observable.of(e)); } Rx.Observable.range(1, 10) .flatMap(e => simulateRequest(e), null, 2) // -- To show that it works -- .do(() => { console.log("ParallelRequests " + parallelRequests); parallelRequests--; }) // --------------------------- .subscribe(e => console.log("Response from request " + e), e => console.log("Should not happen, error: " + e), e => console.log("Finished")); 
 <script src="https://npmcdn.com/@reactivex/rxjs@5.0.0-beta.6/dist/global/Rx.umd.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM