Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 节点中的RXJS PostgreSQL背压_Javascript_Node.js_Postgresql_Typescript_Rxjs - Fatal编程技术网

Javascript 节点中的RXJS PostgreSQL背压

Javascript 节点中的RXJS PostgreSQL背压,javascript,node.js,postgresql,typescript,rxjs,Javascript,Node.js,Postgresql,Typescript,Rxjs,原始标题:如何降低javascript中PgSQL结果行流的速度 我在使用RXJS(5.4.0)和PostgreSQL(驱动程序“pg”:“6.1.4”)的nodejs v4.5.0中遇到内存不足问题 我手动创建一个可观察的PgSQL行,如下所示: return Rx.Observable.create((subscriber) => { pool.connect().then((client: pg.Client) => { const stream:any

原始标题:如何降低javascript中PgSQL结果行流的速度

我在使用RXJS(5.4.0)和PostgreSQL(驱动程序“pg”:“6.1.4”)的nodejs v4.5.0中遇到内存不足问题

我手动创建一个可观察的PgSQL行,如下所示:

return Rx.Observable.create((subscriber) => {
    pool.connect().then((client: pg.Client) => {
        const stream:any = client.query(query.toParam());
        stream.on('row', (row) => {
            subscriber.next(row);
        });

        stream.on('end', () => {
            subscriber.complete();
            client.release();
        });
    });
});
然后我将一些操作符附加到rx可观测对象上,并进行一些处理。 请注意,从数据库返回的行有点重

调查使我得出一个结论: 数据库中的行返回的速度比处理它们的速度快得多。必须为这些繁重的数据保留内存才能等待处理,这会导致内存不足问题:

致命错误:调用和重试上次分配失败-进程内存不足

中止陷阱:6

我在PostgreSQL驱动程序上看不到任何暂停流的选项。有什么想法可以解决这个问题吗?

如果您使用的是同一位作者的,那么应该是比较直截了当的:

return Rx.Observable.defer(() => pg.connect())
  .flatMap(client => {
    const cursor = client.query(new Cursor('SELECT * FROM some_table WHERE prop > $1', [100]))

    const observableCursor = Rx.Observable.bindNodeCallback(cursor.read.bind(cursor));

    // Get the first 100 items
    observableCursor(100)
      .map(processRows)
      // This will only emit after the first one completes
      // and will recursively call this for each result
      .expand(_ => 
        observableCursor(100)
          .map(processRows)
      )
      // Unsubscribes once we don't get any more results
      .takeWhile(rows => rows.length > 0)
  });

我试图写@paulpdaniels solution建议的尽可能多的可读性,但我不确定这是否真的是反应式风格

我还有一个不同的处理函数,它取决于上下文变量。我喜欢有一个架构,可以方便地使用不同的rxjs操作符链,这取决于上下文条件并隐藏游标。读取逻辑,但我担心这是不可能的

当我显式地告诉数据库携带下一批数据(cursor.read)时,必须有一个位置,而且必须是在我从大量数据中释放内存后的位置

以下解决方案为typescript:

const db = require('./libs/db.js');
import * as Cursor from 'pg-cursor';
import * as pg from 'pg';
import * as Rx from 'rxjs';

let cursor, readHandler;

const source = Rx.Observable.create((subscriber) => {
    db.getClient().then((client: pg.Client) => {

        cursor = client.query(new Cursor('SELECT * FROM some_table WHERE prop > $1', [100]));
        readHandler = function (err, rowsBulk) {
            if (err) {
                subscriber.error(err);
                return client.release();
            }
            if (!rowsBulk.length) {
                subscriber.complete();
                return client.release();
            }
            subscriber.next(rowsBulk);
        };
    }).then(() => {
        // fetch first 100 records
        cursor.read(100, readHandler);
    });
});

source.flatMap((item) => {
    return new Promise((resolve) => {
        console.log('processing batch of items');
        setTimeout(() => { // timeout simulates processing
            item = null;
            console.log('release memory');
            resolve({});
        }, 5000);
    });
}).map(() => {
    // fetch every next 100 records
    console.log('allocate new memory');
    cursor.read(100, readHandler);
    return '.';
}).subscribe(console.log, (err) => {
    console.log('Error occurred');
    console.error(err);
});

原始查询得到的列是否超出需要?有时,在大型结果集上使用“select*”是个坏主意。不幸的是,在SQL查询级别没有太多的优化空间。其中一列包含重要数据,这是最重要的一列。您必须对数据进行分页读取,仅此而已。使用
LIMIT
OFFSET
进行此操作。在获取下一部分之前,使用光标并仅获取少量结果。CUROSR是PL/pgSQL功能,但在我的情况下,我需要将数据检索到javascript上下文中。在您的问题中,可能会扩展到“取决于上下文变量的不同处理函数”。我可以更新我的答案,但前提是你给出更具体的答案。我已经更新了标题并标记了你的信息。我同意将上下文对象作为参数传递到处理函数中。