Amazon AWS Simple Workflow Service SWF C# Sample - c#

I was wondering if there are any SWF workflow C# sample code available for the AWS .NET SDK?
AWS Forum Post: https://forums.aws.amazon.com/thread.jspa?threadID=122216&tstart=0

As part of getting familiar with SWF, I ended up writing a common case library that I hope others can use as well. It's called SimpleWorkflowFramework.NET and is available as open source at https://github.com/sdebnath/SimpleWorkflowFramework.NET. It definitely could use a lot of help, so if you are interested, jump right in! :)

I have developed an open source .NET library- Guflow to program Amazon SWF. Here is how you can write a workflow to transcode the video:
[WorkflowDescription("1.0")]
public class TranscodeWorkflow : Workflow
{
public TranscodeWorkflow()
{
//DownloadActivity is the startup activity and will be scheduled when workflow is started.
ScheduleActivity<DownloadActivity>().OnFailure(Reschedule);
//After DownloadActivity is completed TranscodeActivity activity will be scheduled.
ScheduleActivity<TranscodeActivity>().AfterActivity<DownloadActivity>()
.WithInput(a => new {InputFile = ParentResult(a).DownloadedFile, Format = "MP4"})
ScheduleActivity<UploadToS3Activity>().AfterActivity<TranscodeActivity>()
.WithInput(a => new {InputFile = ParentResult(a).TranscodedFile});
ScheduleActivity<SendConfirmationActivity>().AfterActivity<UploadToS3Activity>();
}
private static dynamic ParentResult(IActivityItem a) => a.ParentActivity().Result();
}
In above example I have left out task routing for clarity.
Here is how you can create an activity:
[ActivityDescription("1.0")]
public class DownloadActivity : Activity
{
//It supports both sync/async method.
[ActivityMethod]
public async Task<Response> Execute(string input)
{
//simulate downloading of file
await Task.Delay(10);
return new Response() { DownloadedFile = "downloaded path", PollingQueue = PollingQueue.Download};
}
public class Response
{
public string DownloadedFile;
}
}
For clarity I'm leaving out examples of other activities. Guflow it supported by documentation, tutorial and samples.

Related

How do I create an IMediaPlaybackSource from a Stream, so as to set a MediaPlayer source without using the obsolete SetStreamSource method?

I'm trying to develop a UWP application that will speak text to the user via a Windows.Media.Playback.MediaPlayer. I have this code that currently works:
private async Task Speak(string text)
{
var audio = await _Speech.SynthesizeTextToStreamAsync(text);
player.SetStreamSource(audio);
player.Play();
}
However, this causes a compiler warning: 'MediaPlayer.SetStreamSource(IRandomAccessStream)' is obsolete: 'Use Source instead of SetStreamSource. For more info, see MSDN.
However, I can't find on MSDN how to convert the SpeechSynthesisStream that SynthesizeTextToStreamAsync generates to a IMediaPlaybackSource that the MediaPlayer wants. The Windows.Media.Core.MediaStreamSource class looks promising, but it wants a IMediaStreamDescriptor which I have no idea how to get...
How do I replicate the functionality of this simple three-liner without using deprecated methods?
you can use the MediaSource.CreateFromStream() method for this purpose.
private async Task Speak(string text)
{
var audio = await _Speech.SynthesizeTextToStreamAsync(text);
player.Source = MediaSource.CreateFromStream(audio);
player.Play();
}
SynthesizeTextToStreamAsync returns a SpeechSynthesisStream object that you can use. This example from the MSDN documentation should lead you in the right direction
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync("Hello World");
mediaElement.SetSource(stream, stream.ContentType);
https://learn.microsoft.com/en-us/uwp/api/windows.media.speechsynthesis.speechsynthesizer

How can I Lock an Azure Table partition in an Azure Function using IQueryable and IAsyncCollector?

I'm fiddling with Azure Functions, combining it with CQRS and event sourcing. I'm using Azure Table Storage as an Event Store. The code below is a simplified version to not distract from the problem.
I'm not interested in any code tips, since this is not a final version of the code.
public static async Task Run(BrokeredMessage commandBrokeredMessage, IQueryable<DomainEvent> eventsQueryable, IAsyncCollector<IDomainEvent> eventsCollector, TraceWriter log)
{
var command = commandBrokeredMessage.GetBody<FooCommand>();
var committedEvents = eventsQueryable.Where(e => e.PartitionKey = command.AggregateRootId);
var expectedVersion = committedEvents .Max(e => e.Version);
// some domain logic that will result in domain events
var uncommittedEvents = HandleFooCommand(command, committedEvents);
// using(Some way to lock partition)
// {
var currentVersion = eventsQueryable.Where(e => e.PartitionKey = command.AggregateRootId).Max(e => e.Version);
if(expectedVersion != currentVersion)
{
throw new ConcurrencyException("expected version is not the same as current version");
}
var i = currentVersion;
foreach (var domainEvent in uncommittedEvents.OrderBy(e => e.Timestamp))
{
i++;
domainEvent.Version = i;
await eventsCollector.AddAsync(domainEvent);
}
// }
}
public class DomainEvent : TableEntity
{
private string eventType;
public virtual string EventType
{
get { return eventType ?? (eventType = GetType().UnderlyingSystemType.Name); }
set { eventType = value; }
}
public long Version { get; set; }
}
My efforts
To be fair, I could not try anything, because I don't know where to start and if this is even possible. Id did some research which did not solve my problem, but could help you solve this problem.
Do Azure Tables support locking?
yes, they do: Managing Concurrency in Microsoft Azure Storage. It's called leasing, but I do not know how to implement this in an Azure Function.
Other sources
Azure Functions triggers and bindings developer reference
Azure Functions C# developer reference
Tips, suggestions, alternatives
I'm always open to any suggestions on how to solve problems, but I cannot accept these as an answer to my question. Unless the answer to my question is "no", I can not mark an alternative as an answer. I'm not seeking for the best way to solve my problem, I want it to work the way I engineered it. I know this is stubborn, but this is practice/fiddling.
Blob leases would indeed work pretty well for what you're trying to accomplish (the Functions runtime actually makes extensive use of that internally).
If, before working on a partition, you acquire a lease on a blob (by convention, a blob named after the partition, or something like that) you'd be able to ensure only a given function is working on that partition.
The article you've linked to does show an example of lease acquisition and release, you can find more information in the documentation.
One thing you want to ensure is that you flush your collector before you leave the lock scope (by calling FlushAsync on it)
I hope this helps!

Can Hangfire Handle Changes to Scheduled Tasks Without Redeployment

I have been playing around with Hangfire in a Microsoft MVC application. I have gotten it to compile and schedule fire-and-forget tasks, but I am surprised that I cannot add/remove jobs while the program is running. Is it true that Hangfire cannot dynamically schedule tasks during runtime? Is there a well-known framework that allows one to schedule tasks even after the application has been compiled or deployed without having to change the C# code every time I want to add tasks?
I have also researched Quartz.NET, and it seems to have the same issue.
EDIT:
Windows Task Scheduler can allow tasks to be scheduled with a GUI, and UNIX's cron can have tasks added or removed by editing a file, but I'm looking for some sort of application running on Windows that would allow the user to add or remove tasks after the application has been deployed. I do not want to re-compile the application every time I want to add or remove tasks.
As asked, the question seems to rest on a misunderstanding of the meaning of "dynamic...during runtime". The answer is "yes," it can change tasks without redeployment (but that doesn't appear to be what your really looking for).
Hangfire will add a dashboard UI to your application if you configure it to do so, but it is not an end-to-end task management application itself. It is designed to give your application the ability to schedule work, and have that work completed in a very disconnected way from the point of invocation--it may not even be completed on the same machine.
It is limited to invoking .NET code, but by definition this fulfills your stated requirement to "dynamically schedule tasks during runtime." This can be done in response to any event within your application that you like. Tasks can be also be removed, updated and cancelled.
(Post-edit) You're correct: any scheduling UI or deserialization of task-file format you'll have to write yourself. If you are looking for a tool that gives you a UI and/or task-file OOTB, you may need to move up to a commercial product like JAMS. (Disclaimer: this may not even itself have the capabilities you require--I don't have direct experience with the product but folks I've worked with have mentioned it in a positive light).
Create an API to schedule jobs dynamically after runtime. Your API can accept input via an HTTP Get/Put/Post/Delete etc, then run an instance of anything within your code upon the API call, using the data that you give it.
For example, say you have a hard coded Task A and Task B in your code and you want to schedule them to run dynamically using different parameters. You can create an API that will run the desired task at the specified time, using the parameters that you choose.
[HttpPost]
public IHttpActionResult Post([FromBody]TaskDto task)
{
var job = "";
if(task.TaskName == "TaskA"){
job = BackgroundJob.Schedule(() => RunTaskA(task.p1,task.p2), task.StartTime);
}
if(task.TaskName == "TaskB"){
job = BackgroundJob.Schedule(() => RunTaskB(task.p1,task.p2), task.StartTime);
}
if(!string.IsNullOrWhiteSpace(task.ContinueWith) && !string.IsNullOrWhiteSpace(job)){
if(task.ContinueWith == "TaskB"){
BackgroundJob.ContinueWith(job, () => RunTaskB(task.p3,task.p4));
}
if(task.ContinueWith == "TaskA"){
BackgroundJob.ContinueWith(job, () => RunTaskA(task.p3,task.p4));
}
}
return Ok(job)
}
Then you can call the API using a JSON POST (example using javascript)
// Sending JSON data to start scheduled task via POST
//
var xhr = new XMLHttpRequest();
var url = "https://www.example.com/api/scheduletask";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
}
};
var data = JSON.stringify({"TaskName": "TaskA", "ContinueWith": "TaskB",
"StartTime": "2-26-2018 10:00 PM", "p1": "myParam1", "p2": true,
"p3": "myParam3", "p4": false});
xhr.send(data);
And for completeness of the example here is the TaskDto class for this example
public class TaskDto
{
public string TaskName { get; set; }
public string ContinueWith { get; set; }
public DateTime StartTime { get; set; }
public string p1 { get; set; }
public bool p2 { get; set; }
public string p3 { get; set; }
public bool p4 { get; set; }
}

Tring to get GitHub repo via Octokit

I'm building simple tool for downloading .lua files from online public GitHub repos via link given by user. I started learning async methods so I wanted to test myself.
It's a console application (for now). The ultimate goal is to get .lua files in a repo and ask the user which ones he wants downloaded, but I'll be happy if I connect to GH for now.
I'm using Octokit (https://github.com/octokit/octokit.net) GitHub API integration to .NET.
This is the reduced code; I removed some of unimportant stuff:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Octokit;
namespace GetThemLuas
{
class Program
{
static readonly GitHubClient Github = new GitHubClient(new ProductHeaderValue ("Testing123"), new Uri("https://www.github.com/"));
static void Main(string[] args)
{
Console.WriteLine("Welcome to GitHub repo downloader");
GetRepoTry4();
}
private static async void GetRepoTry4()
{
try
{
Console.WriteLine("Searching for data"); //returns here... code below is never ran
var searchResults = await Github.Search.SearchRepo(new SearchRepositoriesRequest("octokit"));
if (searchResults != null)
foreach (var result in searchResults.Items)
Console.WriteLine(result.FullName);
Console.WriteLine("Fetching data...."); //testing search
var myrepo = await Github.Repository.Get("Haacked", "octokit.net");
Console.WriteLine("Done! :)");
Console.WriteLine("Repo loaded successfully!");
Console.WriteLine("Repo owner: " + myrepo.Owner);
Console.WriteLine("Repo ID: " + myrepo.Id);
Console.WriteLine("Repo Date: " + myrepo.CreatedAt);
}
catch (Exception e)
{
Console.WriteLine("Ayyyy... troubles"); //never trigged
Console.WriteLine(e.Message);
}
}
}
}
The problem is the await` keyword as it terminates the method and returns.
I'm still learning async methods so it's possible I messed something up, but even my ReSharper says it fine.
I used var to replace task<T> stuff. It seams OK to me plus no warnings nor errors.
I fixed the await issue. Now when I finally connected to GH and tried to get the repo it threw an exeption at both calls to GH (tested with commenting first then second call). e.message was some huge stuff.
I logged it into a file and it looks like an HTML document. Here it is (http://pastebin.com/fxJD1dUb)
Change GetRepoTry4(); to Task.Run(async () => { await GetRepoTry4(); }).Wait(); and private static async void GetRepoTry4() to private static async Task GetRepoTry4().
This should get you at least wired up correctly enough to start debugging the real issue.
Generally speaking all async methods need to return a Task or Task<T> and all methods that return a Task or Task<T> should be async. Additionally, you should get your code into the dispatcher as quickly as possible and start using await.
The constructor with the Uri overload is intended for use with GitHub Enterprise installations, e.g:
static readonly GitHubClient Github = new GitHubClient(new ProductHeaderValue ("Testing123"), new Uri("https://github.enterprise.com/"));
If you're just using it to connect to GitHub, you don't need to specify this:
static readonly GitHubClient Github = new GitHubClient(new ProductHeaderValue ("Testing123"));
You're seeing a HTML page because the base address is incorrect - all of the API-related operations use api.github.com, which is the default.
Install Octokit Nuget Package for Github.Then add below function
public JsonResult GetRepositoryDeatil(long id)
{
var client = new GitHubClient(new ProductHeaderValue("demo"));
var tokenAuth = new Credentials("xxxxxxx"); // NOTE: not real token
client.Credentials = tokenAuth;
var content = client.Repository.Content.GetAllContents(id).Result;
List<RepositoryContent> objRepositoryContentList = content.ToList();
return Json(objRepositoryContentList, JsonRequestBehavior.AllowGet);
}
Due to the use of the async/await you should change the definition of the method GetRepoTry4 to the following:
private static async Task GetRepoTry4()
EDIT:
Then in the Main method call it like so GetRepoTry4().Wait();. This will enable the method GetRepoTry4() to be awaited.

Use TAP with wcf EAP generated proxies

I have a Silverlight 5 app, that makes use of a WCF service. The proxy client that has been generated has only asychronous methods (by default, when generating from the SL client).
I want to make use of the Task-based Asynchronous Pattern (TAP), now within VS2012RC.
What is the best approach to consume the async methods from the generated client proxy ?
(the issue is, that the WCF proxy generator creates code that is based on the Event-based Asynchronous Pattern (EAP) and not TAP....)
Based on this document:
http://www.microsoft.com/en-us/download/details.aspx?id=19957
I have found a solution for this.
See code below:
public class MyDataListProvider : IMyDataListProvider
{
private <ObservableCollection<IMyData>> myDataList;
public Task<ObservableCollection<IMyData>> GetMyData()
{
TaskCompletionSource<ObservableCollection<IMyData>> taskCompletionSource = new TaskCompletionSource<ObservableCollection<IMyData>>();
MyWCFClientProxy client = new MyWCFClientProxy();
this.myDataList.Clear();
client.GetMyDataCompleted += (o, e) =>
{
if (e.Error != null)
{
taskCompletionSource.TrySetException(e.Error);
}
else
{
if (e.Cancelled)
{
taskCompletionSource.TrySetCanceled();
}
else
{
foreach (var s in e.Result)
{
var item = new MyData();
item.Name = s.Name;
item.Fullname = s.Fullname;
this.myDataList.Add(item);
}
taskCompletionSource.TrySetResult(this.myDataList);
}
}
};
client.GetMyDataAsync();
return taskCompletionSource.Task;
}
}
Client SL code:
private async void SetMyDataList()
{
this.MyDataList = await this.myDataListProvider.GetMyData();
}
I don't know if it was available in the RC, however as of the SDK 8.0A (the one included with VS2012) svcutil.exe will generate async methods using the TAP pattern.
It will use TAP by default so be sure to NOT include /async as that will make it fall back to the old APM method of generating the methods.
You can see if the version of svcutil is new enough to use the TAP by looking at the first lines of the program it will include that it is at least version 4.0 of the tool.
Microsoft (R) Service Model Metadata Tool [Microsoft (R) Windows (R)
Communication Foundation, Version 4.0.xxxxx.xxxxxx]

Categories