Created
May 3, 2016 21:48
-
-
Save AaronLenoir/4ce5480ecea580d5d283c5d08e8e71b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Akka.Actor; | |
using System; | |
using System.IO; | |
using System.Net; | |
namespace Akka.DownloadActor | |
{ | |
/// <summary> | |
/// Downloads a file from a given Uri. | |
/// </summary> | |
/// <remarks>Multiple download requests will be handled sequentially.</remarks> | |
public class FileDownloadActor : ReceiveActor, IWithUnboundedStash | |
{ | |
#region State | |
private WebClient _client; | |
private Guid _guid; | |
private Uri _uri; | |
private string _tempPath; | |
private IActorRef _self; | |
private IActorRef _downloadRequestor; | |
public IStash Stash { get; set; } | |
#endregion | |
public FileDownloadActor() | |
{ | |
_client = new WebClient(); | |
_client.DownloadProgressChanged += Client_DownloadProgressChanged; | |
_client.DownloadFileCompleted += Client_DownloadFileCompleted; | |
Become(Ready); | |
} | |
#region messages | |
public class StartDownload | |
{ | |
public Guid Guid { get; } | |
public Uri Uri { get; } | |
public StartDownload(Guid guid, Uri uri) | |
{ Guid = guid; Uri = uri; } | |
} | |
public class DownloadProgressed | |
{ | |
public Guid Guid { get; } | |
public double ProgressPercentage { get; } | |
public DownloadProgressed(Guid guid, double progressPercentage) | |
{ | |
Guid = guid; | |
ProgressPercentage = progressPercentage; | |
} | |
} | |
public class DownloadCompleted | |
{ | |
public Guid Guid { get; } | |
public string Path { get; } | |
protected DownloadCompleted(Guid guid, string path) | |
{ | |
Guid = guid; | |
Path = path; | |
} | |
} | |
private class DownloadCompletedInternal : DownloadCompleted | |
{ | |
public DownloadCompletedInternal(Guid guid, string path) : base(guid, path) { } | |
} | |
#endregion | |
#region States | |
public void Ready() | |
{ | |
Receive<StartDownload>(message => { | |
HandleStartDownload(message); | |
Become(Downloading); | |
}); | |
} | |
public void Downloading() | |
{ | |
Receive<StartDownload>(message => { | |
Stash.Stash(); | |
}); | |
Receive<DownloadCompleted>(message => { | |
Become(Ready); | |
Stash.UnstashAll(); | |
}); | |
} | |
#endregion | |
public void HandleStartDownload(StartDownload message) | |
{ | |
_self = Self; | |
_downloadRequestor = Sender; | |
_uri = message.Uri; | |
_guid = message.Guid; | |
_tempPath = Path.GetTempFileName(); | |
_client.DownloadFileAsync(_uri, _tempPath); | |
} | |
private void Client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) | |
{ | |
var completedMessage = new DownloadCompletedInternal(_guid, _tempPath); | |
_downloadRequestor.Tell(completedMessage); | |
_self.Tell(completedMessage); | |
} | |
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) | |
{ | |
var progressedMessage = new DownloadProgressed(_guid, e.ProgressPercentage); | |
_downloadRequestor.Tell(progressedMessage); | |
_self.Tell(progressedMessage); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment