何时断开连接以及何时结束pg客户端或池 [英] when to disconnect and when to end a pg client or pool

查看:123
本文介绍了何时断开连接以及何时结束pg客户端或池的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的堆栈是node,express和pg模块。我真的试图通过文档和一些过时的教程来理解。 我不知道何时,如何断开连接并终止客户端。

My stack is node, express and the pg module. I really try to understand by the documentation and some outdated tutorials. I dont know when and how to disconnect and to end a client.

对于某些路线,我决定使用游泳池。这是我的代码

For some routes I decided to use a pool. This is my code

const pool = new pg.Pool({
  user: 'pooluser',host: 'localhost',database: 'mydb',password: 'pooluser',port: 5432});

pool.on('error', (err, client) => {
  console.log('error ', err);  process.exit(-1);
});

app.get('/', (req, res)=>{
  pool.connect()
    .then(client => {
      return client.query('select ....')
            .then(resolved => {
              client.release();
              console.log(resolved.rows);
            })
            .catch(e => { 
              client.release();
              console.log('error', e);
            })
      pool.end();
    })
});

在CMS的路由中,我使用客户端而不是具有与池不同的数据库特权的池

In the routes of the CMS, I use client instead of pool that has different db privileges than the pool.

const client = new pg.Client({
  user: 'clientuser',host: 'localhost',database: 'mydb',password: 'clientuser',port: 5432});    
client.connect();

const signup = (user) => {
  return new Promise((resolved, rejeted)=>{
    getUser(user.email)
    .then(getUserRes => {
      if (!getUserRes) {
        return resolved(false);
      }            
            client.query('insert into user(username, password) values ($1,$2)',[user.username,user.password])
              .then(queryRes => {
                client.end();
                resolved(true);
              })
              .catch(queryError => {
                client.end();
                rejeted('username already used');
              });
    })
    .catch(getUserError => {
      return rejeted('error');
    });
  }) 
};

const getUser = (username) => {
  return new Promise((resolved, rejeted)=>{
    client.query('select username from user WHERE username= $1',[username])
      .then(res => {
        client.end();
        if (res.rows.length == 0) {
          return resolved(true);
        }
        resolved(false);
      })
      .catch(e => {
        client.end();
        console.error('error ', e);
      });
  })
}

在这种情况下,如果我得到一个用户名已使用并尝试使用其他用户名重新发布, getUser 的查询永远不会启动并且页面会挂起。如果我从两个函数中删除 client.end(); ,它将起作用。

In this case if I get a username already used and try to re-post with another username, the query of the getUser never starts and the page hangs. If I remove the client.end(); from both functions, it will work.

我很困惑,因此请提供有关断开连接以及如何完全终止池或客户端的建议。任何提示或解释或教程,将不胜感激。

I am confused, so please advice on how and when to disconnect and to completely end a pool or a client. Any hint or explanation or tutorial will be appreciated.

谢谢

推荐答案

首先,从 pg文档 *:

const { Pool } = require('pg')

const pool = new Pool()

// the pool with emit an error on behalf of any idle clients
// it contains if a backend error or network partition happens
pool.on('error', (err, client) => {
  console.error('Unexpected error on idle client', err) // your callback here
  process.exit(-1)
})

// promise - checkout a client
pool.connect()
  .then(client => {
    return client.query('SELECT * FROM users WHERE id = $1', [1]) // your query string here
      .then(res => {
        client.release()
        console.log(res.rows[0]) // your callback here
      })
      .catch(e => {
        client.release()
        console.log(err.stack) // your callback here
      })
  })

此代码/构造为足够 /旨在使您的游泳池正常工作,并提供您这里的东西。如果关闭应用程序,则连接将正常挂起,因为创建的池很好,即使挂接确实提供了手动挂接的方式,也无法挂接,
参见文章
还请参见前面的红色部分,其中显示您必须始终退还客户...以接受

This code/construct is suficient/made to get your pool working, providing the your thing here things. If you shut down your application, the connection will hang normaly, since the pool is created well, exactly not to hang, even if it does provides a manual way of hanging, see last section of the article. Also look at the previous red section which says "You must always return the client..." to accept


  • 强制性 client.release()指令

  • 在接受参数之前。

  • 确定范围/关闭客户端

  • the mandatory client.release() instruction
  • before accesing argument.
  • you scope/closure client within your callbacks.

然后,来自 pg.client文档 *:

带有承诺的纯文本查询

const { Client } = require('pg').Client
const client = new Client()
client.connect()
client.query('SELECT NOW()') // your query string here
  .then(result => console.log(result)) // your callback here
  .catch(e => console.error(e.stack)) // your callback here
  .then(() => client.end())

对我来说似乎是最清晰的语法:

seems to me the clearest syntax:


  • 无论结果如何,您都将结束客户。
  • 您可以在终止客户端之前访问结果。

  • 您无需在回调中限制/封闭客户端
  • you end the client whatever the results.
  • you access the result before ending the client.
  • you don´t scope/closure the client within your callbacks

乍一看,这两种语法之间的这种对立可能会造成混淆,但是其中没有魔术,它是实现构造语法。
专注于您的回调和查询,而不是那些构造,只需选择最美观的并用 代码填充

It is this sort of oposition between the two syntaxes that may be confusing at first sight, but there is no magic in there, it is implementation construction syntax. Focus on your callbacks and queries, not on those constructs, just pick up the most elegant for your eyes and feed it with your code.

*为了清楚起见,我在此处添加了注释 //您的xxx

*I added the comments // your xxx here for clarity

这篇关于何时断开连接以及何时结束pg客户端或池的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆