Parallel Batch Request Handling

 

Picture this:

You find yourself with a big list of resource identifiers

You want to make get information for each id via a http request

You want to batch the resource identifiers rather than making individual http calls

You want to make multiple parallel requests for these batches

You don’t want to manage multiple thread access to a single response collection

 

You have come to the right place!

 

There are multiple approaches I can think of, but here’s one that may fit your use case:

 

Get Method:

The code in the method itself is not that important!
what you should take from it is that it’s an ordinary async/await method that takes a list of Ids and returns the results for same.

 

To Parallelizm and beyond

 

Let’s unravel what’s happening above.

 

Firstly we are using .net6 where we have the Chunk method from the framework (gone are the days of writing this by hand thankfully!),
the chunk method basically takes the ids list and breaks it into a list of smaller lists of size ‘batchSize’ or smaller.

e.g.

If we chunked [1,2,3,4,5,6,7,8,9,10,11] with a batch size of 2, then we’d end up with

[[1,2],[3,4],[5,6],[7,8],[9,10],[11]]

 

 

Secondly we pass these smaller arrays to the GetIds call, by using a Linq Select expression.

We await the result of all these Selected tasks via Task.WhenAll

Lastly to combine all the individual batched responses we use the Linq SelectMany expression.

 

I like this approach as it is terse, concise and propagates exceptions without wrapping them in Aggregates.

Await forever – deadlocked so easily

Async/Await simplifies async code, use it everywhere and life becomes so simple right?
While this is true I’ve seen situations where users either chose to, or had to, mix async and non async code and got themselves into a world of problems.

 

One problem I’ve seen time over time is with Windows Desktop applications where a simple blocking call on a Task can deadlock an application entirely, here I demonstrate the problem with a contrived Windows Forms example.

Application simply downloads some html asynchronously and displays it in a web browser

Implementation of async function is:

(Let’s ignore the urge to make the click handler async, imagine the async call was in the form constructor if you must)


How can such a simple bit of code deadlock the windows application?

Well the problem occurs because of how Async/Await state machines work.
I’m really going to simplify this explanation as I want people to grasp it (so grit ur teeth if you already know the detail Winking smile)

 

The async keyworks is simply a compile instruction that doesn’t do much so lets ingore that and focus on the await call

The await calls an async function then waits on a call back, when the call back occurs the code resumes to the next step…

ok so far so good, this is what we expect… simple right…wrong!

 

A quick recap of windows UI threads and messages

Before we continue let’s have a quick recap of windows UI threads and message loops.
A message loop is an obligatory section of code in every program that uses a graphical user interface under Microsoft Windows. Windows programs that have a GUI are event-driven. Windows maintains an individual message queue for each thread that has created a window.

Now as anyone working on a windows application knows you always call any code that updates the UX on the GUI thread, try with any other threads and you’ll get presented with a cross thread exception.

Windows forms application code can call Invoke/BeginInvoke on a windows control and execute the code back on the GUI Thread, in WPF we would use a dispatcher, in UWP/Wintr it’s something else.

Another approach is to use the SyncronizationContext contruct, this is aware if it should call Invoke or Dispatch or something else on our behalf.

 

Back to await

The callback I mentioned above is smart in that it tries to use the existing Syncronization context if it exists, so when that await finally returns we’re back on the GUI thread can can update the UX without those pesky errors.
In our calling code above we never left the GUI thread as we were blocked on the Result of the task.

The crux of the problem is that the await call back puts a message on the windows message queue to tell it to continue, but the message queue is bocked in that call to .Result on the task, so we’re well and truly deadlocked.

 

Solutions

I’ll avoid telling you to embrace async/await everywhere! and offer some alternate solutions..

1) ConfigureAwait(false)


This works as it tells the task not to continue on the current syncroniztion context (which let’s remember is the GUI thread), another context is used to complete the async await state machine call back and allow the task to be completed.

2) Run on another syncronization context you create

 

3) Use Async/Await everywhere

Summary

This is a very dumbed down explanation of how you might encounter a deadlock with async await.

If it happens then don’t panic it can be easily fixed once you know what’s happening, best practise is nearly never to work around the problem and always use async await entirely.

Standard documentation is great there are lots for really good articles floating about: e.g. https://devblogs.microsoft.com/dotnet/configureawait-faq/

VS2019 Docker ASP Core Environment Vars

Tip

If you are debugging with VS2017/9 and want to pass environment variables to your container then read this post, if you are looking for picture of cats then sorry but leave a comment how you got here

 

Step 1

Create a new text file, the name doesn’t matter, but i called mine Dockerfile.env

image
image

 

Step 2

Add this file to your .csproj file.

image

Step 3

Not really a step but you you can simply query your Environment variable in the usual fashion (Environment.GetEnvironmentVariable())

image

 

Note:

Needless to say when you run in production you’ll need to pass the Environment variable according to Docker documentation which I don’t cover here

Setting your C# language level

The C# compiler defaults to the latest major version of the language that has been released. You may choose to compile any project using a new point release of the language. Choosing a newer version of the language enables your project to make use of the latest language features. In other scenarios, you may need to validate that a project compiles cleanly when using an older version of the language.

This capability decouples the decision to install new versions of the SDK and tools in your development environment from the decision to incorporate new language features in a project. You can install the latest SDK and tools on your build machine. Each project can be configured to use a specific version of the language for its build

Screenshot shows me selecting C# 7.2 for a .net core 2.1 application by changing the advanced options of the project properties build pane

C# Concurrency lesson–SemaphoreSlim

In windows we have two types of semaphores, local and named system semaphores.

You can think of a semaphore as a bounder in a nightclub, the responsibility is to only allow a number of people into the club at any one time.

.net has a lightweight semaphore, ‘SemaphoreSlim’ that can be used for local communication (that is to say, system synchronization is not supported)

If you run the code above (e.g. in .net core 2.1 project) you will be presented with the following result

What is happening is that all the tasks try get access to the semaphore, they are all initially blocked until

semaphore.Release(3);

is called which allows 3 tasks to enter at any one time.

Serverless on my server

So I’ve been looking for a serverless framework that can run on-prem and in the cloud, I’ve been leaning towards OpenFaaS as it appears to be gaining more traction, however I love Azure functions and though let’s see if this is a viable solution.

I download what is a Preview, so I wasn’t expecting miracles, I’m sharing the reasons why I can’t use it for my own requirements below.

It might save some of you guys the effort, I must reiterate that this is still a preview so some of the stuff I say here will be out of date really quickly!

I have decided against Azure Function On Prem in March 2017 because:

  • It needs Sql Server, I can’t rely on having this at least not for some brown field projects I want to use serverless for.
  • It needs IIS, I have to run on Linux (might be a solved problem… especially as it’s using the new .net core runtime )
  • It only has Javascript and C# language support in preview, I need Java, and Go and Python would be nice to haves
  • The packaging was a windows installer, I was hoping for some docker images, I expect this is a solved solution and for now the MSI is a quick win for the developers.

Next it’s down the rabbits burrow with OpenFaas on Kubernetes, cross your fingers for me!

 

Aside from the above which are mostly external limitations it’s nice to see Azure Functions Running locally

image

NDepend

Hi all, I’d like to introduce you to what appears to be a great tool for the .net platform. http://www.ndepend.com/

image

I’ve promised to write a review on this tool, however, I’ll be perfectly honest and admit, that I’ve just not got the time right now, so I’m going to take a short cut.

Podcasts

I listen to a lot of podcasts mostly when driving or cycling, recently I’ve started listening to a new podcast http://www.codingblocks.net/ it’s a good podcast and I hope it continues to stick around. As it turns out this podcast did a review on NDepends http://www.codingblocks.net/podcast/ndepend-on-how-good-your-code-is/ and I encourage you to check it out. Moreover; in a more recent episode they mention that they’ve received feedback from Patrick Smacchia (Lead Developer and brains behind the tool) and the feedback they’ve received from Patrick on the few little niggles they encountered is quite positive and upbeat.

When I find myself looking for some tooling like this I’ll write a proper review of my own, but until then based on my interactions with Patrick and after listening to the podcast above, I encourage you, that if you’re in the market for such analysis tools to take NDepends for a spin, and let us know how you get on!