F# 4.1 / .netcore 2.0 on AWS Lambda

I’ve started with installing serverless on node and configuring it.

npm install -g serverless

then we have to configure credentials. You need aws account with IAM user with admin rights. Here is a short guide how to do it. When we have account keys we can configure credentials.

serverless config credentials --provider aws --key XXXXXX --secret XXXXXXX

it will create „.aws” folder in your home directory with credentials.

Then I’ve installed dotnetcore.  I’m using current linux mint 18.03 based on ubuntu 16.04.

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'

sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.1.101

Installing separate fsharp is not required but I want to have REPL. Apt will find it in Microsoft repository or as suggested on fsharp.org we can connect mono repository.
But from unknown reason from Microsoft repository I get older version. So I connect mono repository.

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/ubuntu stable-xenial main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt-get update

sudo apt-get install fsharp

We can verify installed versions

mono --version
dotnet --version
fsharpi

To create aws project we use serverless (in empty folder, or we can use –path and specify folder)

sls create --template aws-fsharp

Unfortunately it’s still creating .netcore 1.0 version, so I had to update it manually, but it was quite fast. Probably next version of serverless will be working with dotnetcore 2.0. You can find upgraded sample on my GitHub.

We execute build script „build.sh” and deploy it to amazon (add execution rights to build.sh). Then we can invoke our test function „hello”.

sls deploy
sls invoke -f hello --data '{"Data": "some data"}'

To remove all your project resources from aws call

sls remove
Reklamy
F# 4.1 / .netcore 2.0 on AWS Lambda

Install Atom on Linux

It seam that easiest way to do this is by snap packages manager. Currently it have to be installed in ‚classic’ way.

sudo apt install snapd

snap install --classic atom

snap run atom

It should be run by snap run, or at least I did not find other way (but I’m totally new to linux). Simple bash script with this command simplifies running.

Install Atom on Linux

Using curl in powershell

Remove curl alias

By default in power shell 5.x command curl is an alias for Invoke-WebRequest, so it’s not real curl. To replace it first I needed to remove an alias.

To change aliases a profile for powershell is required, it can be created with command:

New-Item $profile -force -itemtype file

to edit it run:

notepad $profile

then add alias remove instruction to file and save it

remove-item alias:curl

repeat last instruction in command line or reopen powershell to read it from profile.

Install real curl

I will install curl from chocolate package (https://chocolatey.org/). On chocolatey site are all information how to install from powershell (you need administrator mode). When you have it run:

choco install curl

Now you can start using curl.

Using curl in powershell

Discriminated union in C# with type safety

I’ve been updating some methods which returns as result small class. This class contains all success data and also all failure data. Small part is shared in both cases but mostly only part information is filed depending on a case. And I thought, what a shame I don’t have discriminated union in C#, perfect solution in such case. As a regular developer I’ve checked stackoverflow and there it was, excellent implementation with type checking at compilation time.

public abstract class ResultUnion<S, F>
{
   public abstract T Match(Func<S, T> fs, Func<F, T> ff);

   private ResultUnion() { }

   public sealed class Success : ResultUnion<S, F>
   {
      public readonly S Value;
      public Success(S value) { Value = value; }
      public override T Match(Func<S, T> fs, Func<F, T> ff) => fs(Value);
   }

   public sealed class Fail : ResultUnion<S, F>
   {
      public readonly F Value;
      public Fail(F value) { Value = value; }
      public override T Match(Func<S, T> fs, Func<F, T> ff) => ff(Value);
   }
}

and the example usage:

var result = new ResultUnion<int, string>.Success(0);
or
var result = new ResultUnion<int, string>.Fail("error");

Console.WriteLine(
   result.Match(
     sVal => sVal.ToString(),
     fVal => fVal
   )
);
Discriminated union in C# with type safety

Waitable dialog in async operation

I’ve started my first asynchronous app and there was one simple case on mvvm command show some options dialog and run async process. It seams easy, so I did it and compiler said there is no ‚wait’ on async operation. This was point where synchronous code integrates with asynchronous and my operation was simple method returning Task. I could call .Wiat() method to compile, but this had no sens, it should be async operation and I didn’t want to wait. So I ask team member how do they solve this case, and he said very simple just return void from your async method. .Net Framework allows to return Task, Task<> and void from async methods. After change I got wonderful ‚fire and forget’ operation, but wait if it’s fire and forget how do you test it, how do you know when it ends ? And they didn’t know and didn’t test it, because it’s not possible if it’s void.

public ICommand FooCommand = new DelegateCommand(Foo);
public void Foo()
{
   ShowDialog(viewModel);
   RunAsyncProcess(viewModel.Options);
}
private async Task RunAsynProcess(...)
{
}

So, I’ve had to find different solution. First changed command to async command and then I could put wait on my async operation inside, this give me possibility to control its end time.

public async Task Foo()
{
   ShowDialog(viewModel);
   await RunAsyncProcess(viewModel.Options);
}

But what to do with dialog ? I cannot continue process until it closes and return configuration and we are in async process which wont wait for it. I had to force it to wait.

In such situation helps class TaskCompletionSource, it allows to create a task and control when it’s completed. Process will wait on this task, and it will end when dialog close.

public async Task Foo()
{
   await ShowAsyncDialog(viewModel);
   await RunAsyncProcess(viewModel.Options);
}

private Task ShowAsyncDialog(viewModel)
{
   var tcs = new TaskCompletionSource();
   viewModel.Closed += () => task.SetResult(null); //end task on close event
   ShowDialog(viewModel); //standard sync dialog
   return tcs.Task; //returns task to wait
}

Update – simpler way

I’ve found a little bit simpler way to solve this. Instant of connecting to ‚close’ event I can end task as a second instruction passed to dispatcher. I need a dispatcher to show dialog on main view thread, so it can be done this way:

Task ShowAsyncWaitableDialog()
{
   var task = new TaskCompletionSource<object>();
   DispatcherService.BeginInvoke(() =>
   {
      someDialogService.ShowDialog(...);
      task.SetResult(null);
   });
   return task.Task;
}
Waitable dialog in async operation