2016-04-26 11:17 GMT+02:00 Jinhua Luo <luajit...@gmail.com>: > Why not use libpq in worker? i.e. your worker works just like a pure PG > client. >
there must be some overhead from using client API on server side. Regards Pavel > > In my project, I uses worker in this way and it works well. I do not > use any backend API to access the database. > > 2016-04-21 15:51 GMT+08:00 Ihnat Peter | TSS Group a.s. <ih...@tssgroup.sk > >: > > I am trying to create background worker which listens to notifications > and > > do some work after receiving one. > > > > I got 2 problems: > > > > - Worker is receiving notifications from every channel not only > the > > registered channel (in my case “foo”) > > > > - Notifications are not logged in the server log – I cannot > store > > the payloads for further work > > > > Any help is welcomed. > > > > > > > > Here is the code: > > > > PG_MODULE_MAGIC; > > > > > > > > void _PG_init(void); > > > > void _PG_fini(void); > > > > > > > > static volatile sig_atomic_t got_sigterm = false; > > > > static volatile sig_atomic_t got_sigusr1 = false; > > > > static char *notify_database = NULL; > > > > static emit_log_hook_type prev_log_hook = NULL; > > > > > > > > static void > > > > bgw_sigterm(SIGNAL_ARGS) > > > > { > > > > int save_errno = errno; > > > > got_sigterm = true; > > > > if (MyProc) > > > > SetLatch(&MyProc->procLatch); > > > > errno = save_errno; > > > > } > > > > > > > > static void > > > > bgw_sigusr1(SIGNAL_ARGS) > > > > { > > > > int save_errno = errno; > > > > got_sigusr1 = true; > > > > if (MyProc) > > > > SetLatch(&MyProc->procLatch); > > > > errno = save_errno; > > > > } > > > > > > > > static void > > > > notify_main(Datum main_arg) > > > > { > > > > pqsignal(SIGTERM, bgw_sigterm); > > > > pqsignal(SIGUSR1, bgw_sigusr1); > > > > > > > > BackgroundWorkerUnblockSignals(); > > > > BackgroundWorkerInitializeConnection(notify_database, > NULL); > > > > EnableNotifyInterrupt(); > > > > > > > > pgstat_report_activity(STATE_RUNNING, > "background_worker"); > > > > StartTransactionCommand(); > > > > Async_Listen("foo"); > > > > CommitTransactionCommand(); > > > > pgstat_report_activity(STATE_IDLE, NULL); > > > > > > > > while (!got_sigterm) > > > > { > > > > int rc; > > > > > > > > rc = WaitLatch(&MyProc->procLatch, > > WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, 10000L); > > > > ResetLatch(&MyProc->procLatch); > > > > > > > > if (rc & WL_POSTMASTER_DEATH) > > > > proc_exit(1); > > > > > > > > if (got_sigusr1) > > > > { > > > > got_sigusr1 = false; > > > > elog(INFO, " > > background_worker: notification received"); > > > > // DO SOME WORK WITH > STORED > > NOTIFICATIONS > > > > } > > > > > > > > } > > > > > > > > elog(LOG, "background_worker: finished"); > > > > proc_exit(0); > > > > } > > > > > > > > static void > > > > store_notification(ErrorData *edata) > > > > { > > > > // HERE STORE THE NOTIFICATION FROM SERVER LOG > > > > > > > > if (prev_log_hook) > > > > (*prev_log_hook) (edata); > > > > } > > > > > > > > void > > > > _PG_init(void) > > > > { > > > > BackgroundWorker worker; > > > > DefineCustomStringVariable("postgres", NULL, NULL, > > ¬ify_database, > > > > "postgres", > > > > PGC_POSTMASTER, 0, NULL, NULL, > > NULL); > > > > > > > > MemSet(&worker, 0, sizeof(BackgroundWorker)); > > > > snprintf(worker.bgw_name, BGW_MAXLEN, > "background_worker"); > > > > worker.bgw_flags = BGWORKER_SHMEM_ACCESS | > > BGWORKER_BACKEND_DATABASE_CONNECTION; > > > > worker.bgw_start_time = BgWorkerStart_RecoveryFinished; > > > > worker.bgw_main = notify_main; > > > > worker.bgw_restart_time = 10; > > > > worker.bgw_main_arg = (Datum) 0; > > > > worker.bgw_notify_pid = 0; > > > > RegisterBackgroundWorker(&worker); > > > > > > > > prev_log_hook = emit_log_hook; > > > > emit_log_hook = store_notification; > > > > } > > > > > > > > void > > > > _PG_fini(void) > > > > { > > > > emit_log_hook = prev_log_hook; > > > > } > > > -- > Sent via pgsql-general mailing list (pgsql-general@postgresql.org) > To make changes to your subscription: > http://www.postgresql.org/mailpref/pgsql-general >