예제 #1
0
        /// <summary>
        /// Listen database on selected channels
        /// </summary>
        /// <param name="stoppingToken">Cancellation</param>
        /// <returns></returns>
        public async Task ListenDb(CancellationToken stoppingToken)
        {
            await ParallelHelper.Run(() =>
            {
                Log.Info($"Listening started for DB: {_dbName}");

                while (!stoppingToken.IsCancellationRequested)
                {
                    try
                    {
                        using (PgSqlDbConnect connect = new PgSqlDbConnect(_connectionString))
                        {
                            connect.Open();

                            connect.UnderlyingConnection.Notification += OnNotification;

                            connect.Execute($"LISTEN {PgSqlDbConnect.CHANNEL_GENESIS_REQUEST};");
                            connect.Execute($"LISTEN {PgSqlDbConnect.CHANNEL_GENESIS_DELETE};");
                            connect.Execute($"LISTEN {PgSqlDbConnect.CHANNEL_BACKUP_REQUEST};");

                            while (!stoppingToken.IsCancellationRequested && connect.UnderlyingConnection.State == ConnectionState.Open)
                            {
                                connect.UnderlyingConnection.Wait(100);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                        Thread.Sleep(1000);
                    }
                }
            });
        }
예제 #2
0
        /// <summary>
        /// Event on DB notification on listened channels occurs
        /// </summary>
        /// <param name="sender">Sender of event</param>
        /// <param name="args">Event arguments</param>
        private void OnNotification(object sender, NpgsqlNotificationEventArgs args)
        {
            try
            {
                switch (args.Channel)
                {
                case PgSqlDbConnect.CHANNEL_GENESIS_REQUEST:
                {
                    if (string.IsNullOrEmpty(args.Payload))
                    {
                        throw new ArgumentException("Payload is empty");
                    }

                    string filePath = Path.Combine(_config["GenesisOutputDir"], args.Payload + ".sql");
                    FileHelper.DirectoryEnsure(filePath);

                    string exePath  = _config["PgDumpPath"];
                    string argsText = $"{_config["GenesisArgs"]} --file=\"{filePath}\" {_dbName}";

                    Log.Info($"RUN {exePath} {argsText}");
                    Process pgsql = Process.Start(exePath, argsText);
                    pgsql?.WaitForExit();

                    using (PgSqlDbConnect connect2 = new PgSqlDbConnect(_connectionString))
                    {
                        connect2.Open();
                        connect2.Execute($"SELECT pg_notify('{PgSqlDbConnect.CHANNEL_GENESIS_RESPOND}', '{filePath}'::TEXT);");
                    }

                    break;
                }

                case PgSqlDbConnect.CHANNEL_GENESIS_DELETE:
                {
                    File.Delete(args.Payload);
                    break;
                }

                case PgSqlDbConnect.CHANNEL_BACKUP_REQUEST:
                {
                    string exePath  = _config["PgDumpAllPath"];
                    string filePath = Path.Combine(_config["BackupOutputDir"],
                                                   _config["BackupFilePrefix"] + DateTimeHelper.Now.ToString(DateTimeHelper.FORMAT_FULL).Replace(".", "_").Replace(":", "_").Replace(" ", "_") + ".pgbak");
                    string argsText = $"{_config["BackupArgs"]} --file=\"{filePath}\"";

                    Log.Info($"RUN {exePath} {argsText}");
                    Process pgsql = Process.Start(exePath, argsText);
                    pgsql?.WaitForExit();
                    break;
                }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex, $"{args.Channel} [{args.Payload}]");
            }
        }