Background worker with Listen

Поиск
Список
Период
Сортировка
От Ihnat Peter | TSS Group a.s.
Тема Background worker with Listen
Дата
Msg-id 653F38FD5CD7424981050380095AE47A10C81AA3@SRVEXCHANGE.TSSGROUP.local
обсуждение исходный текст
Ответы Re: Background worker with Listen  (Jinhua Luo <luajit.io@gmail.com>)
Список pgsql-general

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;

}

В списке pgsql-general по дате отправления:

Предыдущее
От: Shane Kilkelly
Дата:
Сообщение: Announcing BedquiltDB: A json doc-store built on PostgreSQL
Следующее
От: Guyren Howe
Дата:
Сообщение: Proper relational database?