Допустим, у меня есть класс вроде MyClass {string id, string eventType, datetime ts}
ts - временная метка события, и Id - это то, на что я хочу рассчитать частоту
У меня есть горячая наблюдаемость MyClass, я хочу рассчитать количество событий, полученных за каждую строку за последние 30 секунд
Если число событий больше 5, я поднимаю еще одно событие MyClass (с тем же идентификатором и eventType = "New"), и если он снова падает ниже 3, мне нужно обновить ранее поднятое событие (с тем же идентификатором и eventType = "New").
Я думаю, мне нужно использовать скользящее окно, я дошел до этого
public static IObservable<MyClass> CountFrequency(this IObservable<MyClass> source, TimeSpan withinPeriod, string marker)
{
// var scheduler = new HistoricalScheduler();
// var driveSchedule = source.Subscribe(e => scheduler.AdvanceTo(e.Timestamp));
return source.Window(TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(5))
.SelectMany(sl => sl)
.GroupBy(a => a.id)
.SelectMany(go => go
.Aggregate(new MyClass(), (acc, evt) => CustomAggFrequency(acc, evt, marker))
.Select(count => count)));
}
Я не могу понять
a) Как связать планировщик с временной меткой данных, а не системным временем. b) Как закодировать логику CustomAggFrequency
Какие-либо предложения
Это не сработает? Ваш вопрос сформулирован так, что трудно понять, чего вы хотите.
var span = TimeSpan.FromSeconds(30);
var shift = TimeSpan.FromSeconds(5);
var query = source
.Window(span, shift)
.Select(window => window
.GroupBy(item => item.id)
.ToDictionary(g => x.Key, g => g.Count() / span.TotalSeconds));
Этот query
будет вызывать словарь каждые 5 секунд, который отображает каждый id
на его частоту в герцах в течение последних 30 секунд. Его тип IObservable<Dictionary<string, double>>
.