Skip to content

Instantly share code, notes, and snippets.

@ArildF
Created Aug 27, 2012
Embed
What would you like to do?
using System;
using System.ComponentModel;
using System.Deployment.Application;
using System.Reactive.Linq;
using System.Threading;
using Castle.Core;
using ReactiveUI;
using Rogue.MetroFire.CampfireClient;
namespace Rogue.MetroFire.UI.Infrastructure
{
public class AppUpdater : IStartable
{
private readonly DisposableCollection _disposables = new DisposableCollection();
private readonly IApplicationDeployment _deployment;
private readonly Semaphore _operationInProgress = new Semaphore(1, 1);
private readonly IMessageBus _bus;
public AppUpdater(IMessageBus bus, IApplicationDeployment deployment)
{
_bus = bus;
_deployment = deployment;
}
public void Start()
{
if (!_deployment.IsNetworkDeployed)
{
return;
}
var updateAvailable = Observable.FromEventPattern<CheckForUpdateCompletedEventArgs>(_deployment,
"CheckForUpdateCompleted")
.Where(e => e.EventArgs.UpdateAvailable)
.Select(_ => new AppUpdateAvailableMessage()).Take(1);
_disposables.Add(_bus.RegisterMessageSource(updateAvailable.Do(_ => _operationInProgress.Release())));
_disposables.Add(Observable.Interval(TimeSpan.FromSeconds(10))
.TakeUntil(updateAvailable)
.Subscribe(_ =>
{
if (_operationInProgress.WaitOne(TimeSpan.FromSeconds(5)))
{
_deployment.CheckForUpdateAsync();
}
}));
_disposables.Add(_bus.Listen<RequestAppUpdateMessage>()
.SkipUntil(updateAvailable)
.Take(1)
.ObserveOn(RxApp.TaskpoolScheduler).
Subscribe(_ =>
{
_operationInProgress.WaitOne();
_deployment.UpdateAsync();
}));
_disposables.Add(Observable.FromEventPattern<AsyncCompletedEventArgs>(_deployment, "UpdateCompleted")
.ObserveOn(RxApp.TaskpoolScheduler).Subscribe(e =>
{
try
{
if (e.EventArgs.Error != null)
{
_bus.SendMessage(new ExceptionMessage(e.EventArgs.Error));
}
else
{
_bus.SendMessage(new RequestApplicationRestartMessage());
}
}
finally
{
_operationInProgress.Release();
}
}));
_disposables.Add(_bus.RegisterMessageSource(
Observable.FromEventPattern<DeploymentProgressChangedEventArgs>(_deployment, "UpdateProgressChanged")
.Select(e => new AppUpdateProgressMessage(e.EventArgs.ProgressPercentage))));
}
public void Stop()
{
if (!_deployment.IsNetworkDeployed)
{
return;
}
_disposables.Dispose();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment