void IAsyncLogProviderCommandHandler.ContinueAsynchronously(CommandContext ctx)
        {
            result = new DateBoundPositionResponseData();

            result.Position = PositionedMessagesUtils.LocateDateBound(ctx.Reader, date, bound, ctx.Cancellation);
            ctx.Tracer.Info("Position to return: {0}", result.Position);

            if (result.Position == ctx.Reader.EndPosition)
            {
                result.IsEndPosition = true;
                ctx.Tracer.Info("It is END position");
            }
            else if (result.Position == ctx.Reader.BeginPosition - 1)
            {
                result.IsBeforeBeginPosition = true;
                ctx.Tracer.Info("It is BEGIN-1 position");
            }
            else
            {
                ctx.Cancellation.ThrowIfCancellationRequested();
                if (userNeedsDate)
                {
                    result.Date = PositionedMessagesUtils.ReadNearestMessageTimestamp(ctx.Reader, result.Position);
                    ctx.Tracer.Info("Date to return: {0}", result.Date);
                }
            }
            dateBoundsCache.Set(date, result);
        }
        async Task IAsyncLogProviderCommandHandler.ContinueAsynchronously(CommandContext ctx)
        {
            result = new DateBoundPositionResponseData();

            result.Position = await PositionedMessagesUtils.LocateDateBound(ctx.Reader, date, bound, ctx.Cancellation);

            ctx.Tracer.Info("Position to return: {0}", result.Position);

            if (result.Position == ctx.Reader.EndPosition)
            {
                result.IsEndPosition = true;
                ctx.Tracer.Info("It is END position");
            }
            else if (result.Position == ctx.Reader.BeginPosition - 1)
            {
                result.IsBeforeBeginPosition = true;
                ctx.Tracer.Info("It is BEGIN-1 position");
            }
            else
            {
                ctx.Cancellation.ThrowIfCancellationRequested();
                if (messageRequested)
                {
                    result.Message = await PositionedMessagesUtils.ReadNearestMessage(ctx.Reader, result.Position, MessagesParserFlag.HintMessageContentIsNotNeeed);

                    ctx.Tracer.Info("Details to return: {0} at {1}", result.Message?.Time, result.Message?.Position);
                }
            }
            dateBoundsCache.Set(date, result);
        }
Exemple #3
0
        Task <DateBoundPositionResponseData> ITimeGapsSource.GetDateBoundPosition(DateTime d, ListUtils.ValueBound bound, CancellationToken cancellation)
        {
            var ret = new DateBoundPositionResponseData()
            {
                IsEndPosition         = true,
                IsBeforeBeginPosition = true
            };

            bool findSmallestDate = bound == ListUtils.ValueBound.Lower || bound == ListUtils.ValueBound.Upper;

            foreach (var r in EnumVisibleResults().Select(r => r.GetLastSnapshot()).Where(s => s != null))
            {
                var bnd = r.GetDateBoundPosition(d, bound);

                if (bnd.Date != null)
                {
                    if (ret.Date == null)
                    {
                        ret.Date = bnd.Date;
                    }
                    else if (findSmallestDate)
                    {
                        if (bnd.Date.Value < ret.Date.Value)
                        {
                            ret.Date = bnd.Date;
                        }
                    }
                    else
                    {
                        if (bnd.Date.Value > ret.Date.Value)
                        {
                            ret.Date = bnd.Date;
                        }
                    }
                }

                if (!bnd.IsBeforeBeginPosition)
                {
                    ret.IsBeforeBeginPosition = false;
                }
                if (!bnd.IsEndPosition)
                {
                    ret.IsEndPosition = false;
                }

                ret.Position += bnd.Index;                 // use sum of indexes as virtual position
            }

            return(Task.FromResult(ret));
        }
Exemple #4
0
 void IDateBoundsCache.Set(DateTime d, DateBoundPositionResponseData rsp)
 {
     lock (sync)
     {
         data[d] = new DateBoundsCache.Entry()
         {
             lastUsed = ++time,
             value    = rsp
         };
         int sizeThreshold = 512;
         if (data.Count > sizeThreshold)
         {
             // drop half of oldest entries when the threshold is reached
             data = data
                    .OrderByDescending(x => x.Value.lastUsed)
                    .Take(sizeThreshold / 2)
                    .ToDictionary(x => x.Key, x => x.Value);
         }
     }
 }
        bool IAsyncLogProviderCommandHandler.RunSynchronously(CommandContext ctx)
        {
            if (!userNeedsDate && (result = dateBoundsCache.Get(date)) != null)
            {
                return(true);
            }

            if (ctx.Cache == null || ctx.Cache.Messages.Count == 0)
            {
                return(false);
            }

            var cache = ctx.Cache;

            if ((date < ctx.Stats.AvailableTime.Begin && (bound == ListUtils.ValueBound.LowerReversed || bound == ListUtils.ValueBound.UpperReversed)) ||
                date == ctx.Stats.AvailableTime.Begin && (bound == ListUtils.ValueBound.UpperReversed))
            {
                result = new DateBoundPositionResponseData()
                {
                    IsBeforeBeginPosition = true,
                    Position = ctx.Stats.PositionsRange.Begin - 1
                };
                return(true);
            }
            if ((date >= ctx.Stats.AvailableTime.End && (bound == ListUtils.ValueBound.Lower || bound == ListUtils.ValueBound.Upper)))
            {
                result = new DateBoundPositionResponseData()
                {
                    IsEndPosition = true,
                    Position      = ctx.Stats.PositionsRange.End
                };
                return(true);
            }
            result = cache.Messages.GetDateBoundPosition(date, bound);
            if (result.Index == 0)
            {
                if (cache.MessagesRange.Begin != ctx.Stats.PositionsRange.Begin &&
                    (bound == ListUtils.ValueBound.Lower || bound == ListUtils.ValueBound.Upper))
                {
                    return(false);
                }
            }
            else if (result.Index == -1)
            {
                if (cache.MessagesRange.Begin != ctx.Stats.PositionsRange.Begin)
                {
                    return(false);
                }
            }
            if (result.Index == cache.Messages.Count - 1)
            {
                if (cache.MessagesRange.End != ctx.Stats.PositionsRange.End &&
                    (bound == ListUtils.ValueBound.LowerReversed || bound == ListUtils.ValueBound.UpperReversed))
                {
                    return(false);
                }
            }
            else if (result.Index == cache.Messages.Count)
            {
                if (cache.MessagesRange.End != ctx.Stats.PositionsRange.End)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #6
0
            bool HandleResponse(DateBoundPositionResponseData res, bool reversedMode)
            {
                using (trace.NewFrame)
                {
                    Predicate <MessageTimestamp> shouldAdvanceDate = d =>
                                                                     reversedMode ? d > currentDate : d < currentDate;

                    bool readerAdvanced = false;

                    trace.Info("reader returned ({0}, {1})", res.Position, res.Message?.Time);

                    trace.Info("reader's current position: {0}", currentPosition);

                    bool advancePosition = true;
                    if (reversedMode)
                    {
                        if (res.IsBeforeBeginPosition)
                        {
                            trace.Info("it's invalid position (before begin)");
                            advancePosition = false;
                        }
                    }
                    else
                    {
                        if (res.IsEndPosition)
                        {
                            trace.Info("it's invalid position (end)");
                            advancePosition = false;
                        }
                    }
                    if (advancePosition && res.Position > currentPosition)
                    {
                        trace.Info("reader has advanced its position: {0}", res.Position);
                        readerAdvanced  = true;
                        currentPosition = res.Position;
                    }

                    bool advanceDate;
                    if (res.Message == null)
                    {
                        advanceDate = false;
                    }
                    else
                    {
                        advanceDate = shouldAdvanceDate(res.Message.Time);
                    }

                    if (advanceDate)
                    {
                        trace.Info("reader might need to advance the current date from {0} to {1}. Getting writer lock to make final decision...", currentDate, res.Message.Time);

                        if (shouldAdvanceDate(res.Message.Time))
                        {
                            trace.Info("reader is really advancing the current date from {0} to {1}", currentDate, res.Message.Time);
                            currentDate = res.Message.Time;
                        }
                        else
                        {
                            trace.Info("false alarm: reader is not advancing the current date because it has been already advanced to {0} by some other reader", currentDate);
                        }
                    }

                    return(readerAdvanced);
                }
            }