Listen&notifyとbwpの間違った使い方

1,513 views

Published on

PGCon 2013 LTで喋ったスライド。

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,513
On SlideShare
0
From Embeds
0
Number of Embeds
20
Actions
Shares
0
Downloads
5
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Listen&notifyとbwpの間違った使い方

  1. 1. PGCon 2013 Lighting Talk LISTEN/NOTIFYの 間違った使い方 ぬこ@横浜(@nuko_yokohama)
  2. 2. 自己紹介 「ぬこ@横浜」で検索 ラーメンの食べ歩きと 無駄なPostgreSQL拡張を考えるのが趣味 漢数字型とか、 neo4j_fdwとか ゆるい全文検索拡張とか
  3. 3. さて
  4. 4. 唐突ですが皆さん、 「ソリティア社員」 ってご存知ですか?
  5. 5. ソリティア社員とは? 社員に支給されるPCにインストール されているソリティアを一日中やっ ているような高齢社員を象徴とし て、「ソリティア社員」と呼ぶ。 http://s.ameblo.jp/motoko11/entry-10755776519.html
  6. 6. カリスマ給料泥棒を 目指す俺にとっては 夢みたいな立場だ!
  7. 7. しかし俺のPCには ソリティアが 入っていない (´・ω・`)ショボーン
  8. 8. だが、PCには PostgreSQLが 入っている! (`・ω・´)シャキーン!
  9. 9. くやしいので、 PostgreSQL上で 動作するゲームを 作ってみた
  10. 10. 本題
  11. 11. PostgreSQLには 非同期通知機能として LISTEN/NOTIFY というコマンドがある。
  12. 12. コマンド LISTEN チャネル NOTIFY チャネル[,ペイロード文字列]
  13. 13. なお、非同期通知の受け取り方は クライアント次第 psqlでは任意の コマンド実行契機で受信 pl/pgsqlでは受信の ハンドリングはできない。
  14. 14. 本当はpsqlやpl/pgsqlだけで 組みたかったが、 そういうわけなので 仕方なくlibpqで組むことに。
  15. 15. libpqの場合、LISTENを発行後 にPQnotifies()を発行して 通知があったか待ち続ける。
  16. 16. 通知があった場合、チャネルや (指定されていれば) ペイロード(メッセージ)を 受け取ることが出来る。 notify = Pqnotifies(conn); char* hoge = notify->extra;
  17. 17. LISTENと非同期通知の 受信については src/test/examples/testlibpq2.c が良い参考になる。 (というかパクった)
  18. 18. ちなみに今回作成する ゲームは数当て (Hit&Blow)4桁版 場所と数値が合ってたらHit 数値のみ会っていたらBlow
  19. 19. しかし・・・ それだけでは 芸がないかな
  20. 20. せっかく9.3上で 動かしているので
  21. 21. 無駄に Background Worker Processes 化してみた
  22. 22. Background Worker Process PostgreSQLは別々のプロセスでユーザ提供のコードが実行さ れるように、拡張することができます。 これらのプロセスは postgresによって起動、終了、監視され、サーバの状況に密接 に関係している生存期間を持たせます。 http://www.postgresql.jp/document/9.3/html/bgworker.html 個人的にはWritable FDWと並んで 9.3の目玉機能の一つと思っている
  23. 23. こんな感じ 【postgresql.conf】 起動 shared_preload_libraries = 'hb_worker' hb_worker.conninfo = 'dbname=xxx user=yyy' Postgres server(9.3) 起動 ロード・起動 LISTEN HB_SV hb_worker.so Background Worker Process (libpqを使用) LISTEN HB_CL チャネル HB_SV チャネル HB_CL psql 数当て判定処理 NOTIFY HB_CL,'結果' NOTIFY HB_SV,'数字列'
  24. 24. Background Worker Processは9.3の contrib/worker_spi が良い参考になる。 (というかパクった(2回目))
  25. 25. PostgreSQL版 Hit&Blowデモ
  26. 26. 一応ゲームっぽくは なっているはず。 ゲーム自体は他愛ないものだが。
  27. 27. 【ポイント】 ば・れ・に・く・い 傍目にはpsqlを使って 仕事をしているかのように見える。
  28. 28. ということで無駄に LISTEN/NOTIFYと BWPを使ってみました
  29. 29. ソースはここ https://github.com/nuko-yokohama/hb_worker
  30. 30. ご清聴 ありがとう ございました
  31. 31. 付録 hb_worker実行例
  32. 32. postgresql.conf設定例(抜粋) shared_preload_libraries = 'hb_worker' hb_worker.conninfo = 'dbname=postgres' サーバ起動例 [nuko]$ pg_ctl start -D ~/pgdata/9.3 server starting LOG: registering background worker "hb_worker" LOG: loaded library "hb_worker" LOG: database system was shut down at 2013-11-05 22:42:28 PST LOG: starting background worker process "hb_worker" LOG: database system is ready to accept connections LOG: autovacuum launcher started LOG: hb_worker conninfo = dbname=postgres LOG: hb_worker: set secret number=4539
  33. 33. psqlからの実行例 postgres=# LISTEN HB_CL; LISTEN postgres=# NOTIFY HB_SV,'xxxx';; NOTIFY Asynchronous notification "hb_cl" received from server process with postgres=# NOTIFY HB_SV,'0123';; NOTIFY Asynchronous notification "hb_cl" received from server process with postgres=# NOTIFY HB_SV,'0813';; NOTIFY Asynchronous notification "hb_cl" received from server process with postgres=# with payload "Invalid data.(xxxx)" PID 29520. with payload "2 Hit / 1 Blow." PID 29520. with payload "4 Hit! Conguratulatoins!, next new game." PID 29520. (注:見やすさのために適宜改行している) hb_workerの応答 LOG: LOG: NOTIFY HB_CL,'2 Hit / 1 Blow.' hb_worker: NOTIFY HB_CL,'4 Hit! Conguratulatoins!, next new game.' LOG: hb_worker: set secret number=0391

×