private async Task LogRequestResponseAndTriggerNext(HttpContext context)
        {
            var request = context.Request;
            var reqRes  = await ExtractRequestAsync(request);

            await _requestResponseCoupleService.Create(reqRes);

            var response = context.Response;

            using (var resMS = new MemoryStream())
            {
                var originalResponseBodyReference = response.Body;
                response.Body = resMS;

                await _next(context);

                response.Body.Seek(0, SeekOrigin.Begin);
                var responseBody = await new StreamReader(response.Body).ReadToEndAsync();
                response.Body.Seek(0, SeekOrigin.Begin);
                reqRes.Response = new Response
                {
                    StatusCode = response.StatusCode,
                    Body       = responseBody
                };
                await resMS.CopyToAsync(originalResponseBodyReference);
            }

            await _requestResponseCoupleService.Update(reqRes);

            _notificationPublisher.ToClients(TethysNotificationKeys.NewRequestResponseCouple, reqRes);
        }
        public async Task NotifyAsync(IEnumerable <PushNotification> notifications)
        {
            //stop previous notifications
            Stop();

            if (notifications == null || !notifications.Any())
            {
                return;
            }

            //setup database
            foreach (var n in notifications)
            {
                n.NotifyTimes     = Math.Max(1, n.NotifyTimes);
                n.NotifiedCounter = 0;
            }
            _notificationRepository.Create(notifications);

            //recreate cancelation token source
            _notificationsCancelationTokenSource = new CancellationTokenSource();
            var ct = _notificationsCancelationTokenSource.Token;
            await Task.Run((Action)(() =>
            {
                foreach (var notification in notifications)
                {
                    while (!notification.WasFullyHandled)
                    {
                        if (ct.IsCancellationRequested)
                        {
                            return;
                        }

                        Thread.Sleep((int)notification.Delay);
                        if (ct.IsCancellationRequested)
                        {
                            return;
                        }
                        notification.NotifiedOnUtc = DateTime.UtcNow;
                        var body = JsonObject.Parse(notification.Body);

                        _publisher.ToClients(notification.Key, body);
                        notification.NotifiedCounter++;
                        _notificationRepository.Update(notification);
                    }
                }
            }));
        }