私のスタックは、Node、Express、および pg モジュールです。ドキュメントといくつかの古いチュートリアルで理解しようと努力しています。いつ、どのように接続を切断してクライアントを終了するのか分かりません。
いくつかのルートではプールを使うことにしました。これが私のコードです
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 のルートでは、プールとは異なる DB 権限を持つプールの代わりにクライアントを使用します。
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);
});
})
}
この場合、 を取得してusername already used
別のユーザー名で再投稿しようとすると、 のクエリがgetUser
開始されず、ページがハングします。 をclient.end();
両方の関数から削除すると、機能します。
混乱していますので、いつどのように切断し、プールまたはクライアントを完全に終了するかについてアドバイスをお願いします。ヒントや説明、チュートリアルなどがあれば、ぜひ教えてください。
ありがとう
ベストアンサー1
まず、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
})
})
このコード/構造は十分な/プールを稼働させるために作られた、あなたのものはここにありますアプリケーションをシャットダウンすると、プールが適切に作成されるため、接続は正常にハングします。ハングしない場合でも、手動でハングする方法については、最後のセクションを参照してください。記事また、前の赤いセクション「常にクライアントを返す必要があります...」も確認してください。
- 義務的な
client.release()
指導 - 引数にアクセスする前に。
- コールバック内でスコープ/クロージャ クライアントを定義します。
それから、 から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())
私にとって最も明確な構文のように思えます:
- 結果がどうであれ、クライアントを終了します。
- 結果にアクセスする前にエンディングクライアント。
- コールバック内でクライアントをスコープ/クローズしない
一見すると、この2つの構文の対立が混乱を招くかもしれませんが、そこには魔法はなく、実装構築構文です。あなたのコールバックやクエリは、それらの構造ではなく、あなたの目にとって最もエレガントなものを選んでくださいあなたのコード。
*コメントを追加しました// ここにあなたのxxx明確にするために