1分钟前恢复数据的时移序列

时间:2015-02-13 14:11:26

标签: system.reactive reactive-programming

此类累积值+当前时刻知道当前总和与1分钟前的总和之间的差异。它的客户端以这种方式使用它:为每个传入的数据块添加新值并获得差异。现在,恢复其状态存在问题。假设应用程序被回收,前一分钟泵中的这些数据丢失,回收后的第一分钟Change将等于0,所以我必须等待一分钟才能计算差异。如何解决?

public class ChangeEstimator
{
    private int sum;

    private Subject<int> sumPump;

    private IConnectableObservable<int> hotSumPump;

    public int Sum
    {
        get
        {
            return sum;
        }

        private set
        {
            sum = value;
            sumPump.OnNext(value);
        }
    }

    public int Change { get; private set; }

    public void Start()
    {
        sumPump = new Subject<int>();
        hotSumPump = sumPump.Publish();

        var changePeriod = TimeSpan.FromMinutes(1);
        hotSumPump.Delay(changePeriod)
                  .Subscribe(value =>
                  {
                      Change = Sum - value;
                  });
        hotSumPump.Connect();
    }

    public void AddNewValue(int newValue)
    {
        Sum += newValue;
    }
}

更新

在下面的代码中,您可以看到解释。客户端订阅事务流,并且每次新事务都会更新估计器。客户端还公开IObservable快照源,这些快照将数据快照推送到可以是UI或数据库的侦听器。问题是当回收发生时,UI将显示不是真正的变化而是0.如果这个问题对于Stackoverflow来说太具体了,请原谅我。我被建议使用RabbitMQ来保持持久的变化。你认为它可以解决这个问题吗?

public class Transaction
{
    public int Price { get; set; }
}

public class AlgorithmResult
{
    public int Change { get; set; }
}

public interface ITransactionProvider
{
    IObservable<Transaction> TransactionStream { get; }
}

public class Client
{
    private ChangeEstimator estimator = new ChangeEstimator();

    private ITransactionProvider transactionProvider;

    public Client(ITransactionProvider transactionProvider)
    {
        this.transactionProvider = transactionProvider;
    }

    public void Init()
    {
        transactionProvider.TransactionStream.Subscribe(t =>
        {
            estimator.AddNewValue(t.Price);
        });
    }

    public IObservable<AlgorithmResult> CreateSnaphotsTimedSource(int periodSeconds)
    {
        return Observable
            .Interval(TimeSpan.FromSeconds(periodSeconds))
            .Select(_ =>
            {
                AlgorithmResult snapshot;
                snapshot = new AlgorithmResult
                {
                    Change = estimator.Change
                };
                return snapshot;
            })
            .Where(snapshot => snapshot != null);
    }
}

2 个答案:

答案 0 :(得分:0)

您的应用程序重新启动并且没有前一生的内存(双关语)。没有Rx技巧(在此应用程序中)可以帮助您。

如上所述,您应该弄清楚业务需求并考虑启动期间的状态初始化。 您可能需要考虑通过I / O源存储最新状态或在消息发送方和消费者之间分离应用程序逻辑以实现队列。

答案 1 :(得分:0)

我必须回答我自己的问题,因为我得到了某人的回答,这在我的案例中有效。我同意正确的答案取决于业务逻辑,我认为我已经尽可能清楚地解释了它。

所以,这里处理可能的应用程序回收的正确方法是将类ChangeEstimator放到外部进程并与之交换消息。 我使用AMQP将消息发送到估算器(RabbitMQ)。关键在于,与包含其余部分的Web应用程序相比,外部进程关闭/回收的风险非常小。