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,
> > &notify_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
>

Reply via email to