public async IAsyncEnumerable <MessageContentGrpcModel> GetMessagesFromMessageId(string topicId, long fromMessageId,
                                                                                         int maxMessagesAmount, string reason)
        {
            var pageId = MessagesContentPagesUtils.GetPageId(fromMessageId);


            var maxPageId = pageId.Value + 2;

            var messageNo = 0;

            while (pageId.Value < maxPageId)
            {
                var page = await TryGetPageAsync(topicId, pageId, reason);

                foreach (var message in page.GetMessages())
                {
                    if (message.MessageId >= fromMessageId)
                    {
                        yield return(message);

                        messageNo++;
                    }

                    if (messageNo >= maxMessagesAmount)
                    {
                        yield break;
                    }
                }

                pageId = new MessagePageId(pageId.Value + 1);
            }
        }
        public async ValueTask <IMessageContentPage> TryGetPageAsync(string topicId, MessagePageId pageId, string reason)
        {
            var page = _messagesContentCache.TryGetPage(topicId, pageId);

            if (page != null)
            {
                return(page);
            }


            IMessageContentPage result = null;


            await _taskSchedulerByTopic.ExecuteTaskAsync(topicId, pageId, "Getting page: " + reason, async() =>
            {
                result = await TryGetPageTopicThreadSynchronizedAsync(topicId, pageId);
            });

            return(result);
        }
        public async ValueTask <IMessageContentPage> TryGetPageTopicThreadSynchronizedAsync(string topicId,
                                                                                            MessagePageId pageId)
        {
            var page = _messagesContentCache.TryGetPage(topicId, pageId);

            if (page != null)
            {
                return(page);
            }

            return(await LoadPageIntoCacheTopicSynchronizedAsync(topicId, pageId));
        }
        public async Task <IMessageContentPage> LoadPageIntoCacheTopicSynchronizedAsync(string topicId, MessagePageId pageId)
        {
            var page = _messagesContentCache.TryGetPage(topicId, pageId);

            if (page != null)
            {
                return(page);
            }

            return(await _restorePageFromBlobOperation.TryRestoreFromCompressedPage(topicId, pageId)
                   ?? await _restorePageFromBlobOperation.TryRestoreFromUncompressedPage(topicId, pageId));
        }