CORS Errors while playing with the HTML Canvas

In this post, I wrote about how you might draw a graph using the HTML canvas; my next step was to make that more efficient; however, upon trying to import a Javascript module into my script:

import animatedGraphics from './animatedGraphics';

I started getting this error:

Access to script at ‘file:///C:/repos/webanimations/animated-columns-optimised/columns.js’ from origin ‘null’ has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

After a bit of digging, I uncovered a feature of ES6 that prevents opening this directly in a browser.

Hosting the site locally

The issue is caused because the file is being opened directly; so there seemed to be a couple of ways around this: one is to disable the security in Chrome, although try as I might, I couldn’t manage to get it to give up the ghost: I tried various combinations around the –disable-web-security flag of Chrome.

The second option is to host the site locally. For a brief moment I considered using something like IIS Express; but fortunately, I came across this tool that hosts a site locally for you.

It can be installed as an npm package:

npm install --global http-server

Once installed, you just navigate to the relevant directory, and type http-server:

C:\repos\webanimations\animated-columns-optimised>http-server
Starting up http-server, serving ./
Available on:
  http://192.168.1.79:8080
  http://127.0.0.1:8080
  http://172.17.230.225:8080
Hit CTRL-C to stop the server

You can then navigate to your specific page; for example:

http://127.0.0.1:8080/columns

And no more CORS error (doesn’t quite work yet, but that’s a whole different story).

Drawing Custom Graphs in HTML and Javascript

While recently playing with the HTML Canvas again, it occurred to me that this power could be used for evil (or statistics are it is commonly known these days).

In this post, I’m going to draw an animated chart using the HTML Canvas and Javascript.

Let’s start with the HTML:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="test.css">
    <script src="test.js"></script>
</head>
<body onload="doDrawing()">
    <canvas id="canvas">
    </canvas>
</body>
</html>

Again, as with my previous post (linked above), I’ll remind you that this will not cope with screen resizing. The CSS, again, isn’t much to write home about:

* { 
    margin:0; 
    padding:0; 
}
canvas {  
    display: block;    
}

Javascript

Finally, we come to the Javascript: this is a bit more involved, so I’ll break it down into the individual functions; we’ll start with the top level one:

const doDrawing = () => {
    var c = document.getElementById("canvas");
    
    c.width = window.innerWidth;
    c.height = window.innerHeight;
    var ctx = c.getContext("2d");    
    drawGraphTop(50, 5, 500);
    drawColumn(100, 500, 4, 'January');
    drawColumn(150, 350, 5, 'February');
    drawColumn(200, 150, 6, 'March');
}

All we’re doing here is getting a handle to the canvas, setting the height and width so that we fill the screen, and then calling some functions to do the drawing. The helper method to get the context is trivial, but for completeness:

function getContext() {
    var c = document.getElementById("canvas");    
    var ctx = c.getContext("2d");        
    return ctx;
}

There’s not much to explain here, we’re just getting the context from the canvas and returning it – thereby saving 3 lines of code each time we do that. The drawGraphTop function is a little more interesting:

const drawGraphTop = (top, interval, width) => {
    let ctx = getContext();
    ctx.beginPath();
    ctx.rect(1, top, width, 2);
    let stage = width / interval;
    for (let i = 0; i <= interval; i++) {
        ctx.rect(i * stage, top, 2, 5);
    }
    ctx.stroke();
}

The idea here is that we display a flat, horizontal line across the top of the screen, with markers. There is no line method on the canvas context, so a flat rectangle is the best we can do.

The more complex method is the drawColumn method (technically, it isn’t actually drawing columnns – but they still feel like columns – at least, more than rows):

const drawColumn = (top, target, speed, label) => {
    let ctx = getContext();
    let x = 10;    
    let directionHorizontal = speed;

    let intervalHandle = setInterval(() => {
        const buffer = 15;
        const height = 30;
        let showText = false;
        ctx.beginPath();
        ctx.clearRect(1, top - 1, target + buffer + Math.abs(directionHorizontal) + 2, height + 2);

        if (directionHorizontal === 1 && x <= target + buffer) {
            
        } else if (directionHorizontal > 0 && x >= target + buffer) {
            directionHorizontal = -1;
        } else if (directionHorizontal < 0 && x <= target) {
            clearInterval(intervalHandle);
            directionHorizontal = 0;
            showText = true;            
        }

        x += directionHorizontal;
        ctx.rect(1, top, x, height);
        ctx.stroke();

        if (showText) {                        
            ctx.fillText(label, 10, top + 20);
        }
    }, 1);
    
}

There is quite a lot to this; let’s focus on the interval; we take a handle to the interval, so that we can cancel it when we’ve finished drawing.

The first thing we do with the context is call beginPath – this allows us to group a series of updates into a single screen update; then we’re clearing an area, just wide of, the size of the rectangle.

We then have a conditional check – if we’re heading right, and have yet to reach the target (which has a small buffer appended for the purpose of animation), then this drops through to the code below; if we’ve reached that then we change direction; and when we’re back to the actual target, we cancel the update and set a flag to make the text appear.

Subsequently, we draw the (horizontal) column and, if we’ve finished, display the text.

Output and Caveats

It’s worth bearing in mind that the way this code is structured is probably not the best for performance – ideally, you would have a sort of game loop and draw, and then update the entire screen in one go.

Code

You can find the code for this here.

Playing with the HTML Canvas Again

I’ve previously written about how you can write games using tools like React. I’ve also written about creating a basic game in Html and Javascript, and things like rotating shapes.

In this post, I’m going to demonstrate a sort of Etch A Sketch type program.

The HTML is very simple here:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="test.css">
    <script src="test.js"></script>
</head>
<body onload="doDrawing()">
    <canvas id="canvas">
    </canvas>
</body>
</html>

Basically just bringing in a Javascript file, CSS and putting a canvas on the screen. I’m also calling a function onload – it’s worth bearing in mind that, as it goes, this won’t resize should you change the size of the browser. If you want that behaviour, then have a look at one of my previous posts mentioned above.

The CSS is even simpler:

* { 
    margin:0; 
    padding:0; 
}
canvas {  
    display: block;    
}

All we’re doing here is removing the default margin, and stopping scroll bars from appearing.

Javascript

The Javascript is where everything is happening; let’s start with some variables:

let x = 10;
let y = 10;
let directionHorizontal = 1;
let directionVertical = 0;

The four variables determine the position that we want to draw in, and which way we’re heading. We can now render this to the screen like this:

const doDrawing = () => {
    var c = document.getElementById("canvas");
    
    c.width = window.innerWidth;
    c.height = window.innerHeight;

    var ctx = c.getContext("2d");
    setInterval(() => {
        ctx.fillRect(x, y, 1, 1);
        x += directionHorizontal;
        y += directionVertical;
    }, 10);
}

The canvas width and height are the first things to note: when I started playing with this, I made the mistake of trying to set this in CSS; if you do, it actually doesn’t change the size of the canvas, but stretches it across the screen; this was the only way that I could get the canvas to display full screen without that stretching effect (if you know another / better way, please say so in the comments!)

Next we get the context from the canvas – this allows us to render to it, and then we simply set-up an interval, and draw a rectangle 1px x 1px each iteration.

Summary

That it – as with previous posts, there’s not a whole lot to using the HTML canvas, but I do like to re-experiment every so often.

Calling a Web API from a Console App and Creating a Performance Test

While working on a proof of concept, I needed to create a dummy API, and then run a stress test on it. Whilst the activity itself may seem pointless (creating a templated API and stress testing it), I felt the process might be worth documenting.

Create the API

We’ll start with creating the API:

dotnet new webapi

If you just run this, you should see the following:

The next step is to call that from a console app.

Create a console app to call the API

Add a new console app project to your solution, and replace the code in Program.cs with the following:

    class Program
    {
        static HttpClient client = new HttpClient();
        static string path = "https://localhost:44356/weatherforecast";


        static async Task Main(string[] args)
        {
            Console.WriteLine("Press enter to start test");
            Console.ReadLine();
            string? data = await CallWeatherForecast();

            Console.WriteLine(data ?? "No data returned");
        }

        private static async Task<string?> CallWeatherForecast()
        {            
            HttpResponseMessage response = await client.GetAsync(path);
            if (response.IsSuccessStatusCode)
            {
                string data = await response.Content.ReadAsStringAsync();
                return data;
            }

            return null;
        }
    }

It’s worth noting that I switched on nullable reference types here (in the csproj file):

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>

To test this, you’ll need to start both the projects (either select Set Startup Projects… from the solution context menu, or run the API, and then right-click the console app and select Debug -> Start New Instance).

Once you’ve checked that this works, build the solution in release mode (remember, we’re going to be running a stress test, so debug mode will show skewed results).

Call the console app from JMeter

For the stress test, I’m going to use Jmeter. You’ll need to download it from here.

I won’t go into too much detail about how to set this up, but briefly, extract the downloaded zip somewhere, and run the jmeter.bat file. You should be presented with the following screen:

Add a thread group, so we can simulate multiple users:

Then add an OS Process Sampler to run the console app:

Remember to run the API first, then click the green play arrow. You’ll see the users ramp up:

We don’t have any listeners, so the results are, unfortunately lost. Let’s add a couple:

As you can see, we now have some information. How long these calls are taking on average, the error count, etc. The throughput we’re getting is around 3/second… In fact, running a stress test locally on the same machine, it’s difficult to break it, because as the resources get used up, the JMeter process itself suffers, too. This is a good reason to run JMeter from a VM in the cloud.

Whilst it’s quite difficult to kill the service, I certainly managed to slow it down considerably:

These figures are in milliseconds, which means that 90% of calls are taking over 2 minutes. This entire test took around 15 minutes, and around 10 requests per second was about the best it got to (I ran 10 loops of 1000 concurrent users).

There’s a few things you can do to identify where the performance starts to degrade, but I’m more interested in what happens to these figures if I add DB access.

Note: when you’re playing with this, the reports don’t automatically clear each run, so you have to select each, right-click and clear.

Add calls to a DB

Let’s add Entity Framework to our project.

We can then change the controller to allow adding new records and retrieval by date:

        public WeatherForecastController(
            ILogger<WeatherForecastController> logger,
            StressTestDbContext stressTestDbContext)
        {
            _logger = logger;
            _stressTestDbContext = stressTestDbContext;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> GetNew()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
        
        [HttpGet("/[controller]/GetByDate/{dateTime}")]
        public IEnumerable<WeatherForecast> GetByDate(DateTime dateTime)
        {
            var forecasts = _stressTestDbContext.Forecast.Where(a => a.Date.Date == dateTime.Date);
            return forecasts;
        }

        [HttpPost]
        public IActionResult Post(WeatherForecast weatherForecast)
        {
            DailyForecast forecast = new DailyForecast()
            {
                Date = weatherForecast.Date,
                Summary = weatherForecast.Summary,
                TemperatureC = weatherForecast.TemperatureC
            };

            _stressTestDbContext.Add(forecast);
            if (_stressTestDbContext.SaveChanges() != 0)
            {
                return Ok();
            }
            return BadRequest();
        }

Finally, we can change the main program to call those functions:

        static async Task Main(string[] args)
        {
            Console.WriteLine("Press enter to start test");
            Console.ReadLine();

            ConsoleTitle("CallGetNewWeatherForecast");
            string? dataGet = await CallGetNewWeatherForecast();
            Console.WriteLine(dataGet ?? "No data returned");

            ConsoleTitle("AddForecast");
            string? dataAdd = await AddForecast(_rnd.Next(30),
                DateTime.Now.AddDays(_rnd.Next(10)), _summaries[_rnd.Next(_summaries.Length)]);
            Console.WriteLine(dataAdd ?? "No data returned");

            ConsoleTitle("CallGetWeatherForecast");
            string? dataGetDate = await CallGetWeatherForecast(DateTime.Now.AddDays(_rnd.Next(10)));
            Console.WriteLine(dataGetDate ?? "No data returned");
        }

        private static void ConsoleTitle(string title)
        {
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine(title);
            Console.ResetColor();
        }

        private static async Task<string?> CallGetNewWeatherForecast()
        {            
            HttpResponseMessage response = await client.GetAsync($"{path}");
            if (response.IsSuccessStatusCode)
            {
                string data = await response.Content.ReadAsStringAsync();
                return data;
            }

            return null;
        }

        private static async Task<string?> CallGetWeatherForecast(DateTime dateTime)
        {
            string dateString = dateTime.ToString("yyyy-MM-dd");

            HttpResponseMessage response = await client.GetAsync($"{path}/GetByDate/{dateString}");
            if (response.IsSuccessStatusCode)
            {
                string data = await response.Content.ReadAsStringAsync();
                return data;
            }

            return null;
        }

        private static async Task<string> AddForecast(int temperature, DateTime date, string summary)
        {
            var forecast = new WeatherForecast()
            {
                TemperatureC = temperature,
                Date = date,
                Summary = summary
            };

            HttpResponseMessage response = await client.PostAsJsonAsync($"{path}", forecast);
            if (response.IsSuccessStatusCode)
            {
                string data = await response.Content.ReadAsStringAsync();
                return data;
            }

            return null;
        }

To get a sensible reading, you’ll need to do this from an empty database:

For the first run, we’ll do 500 users, and 3 iterations:

The output from the first run is:

And let’s just check that that’s created the records we expected:

EF async calls vs non-async

To satisfy a curiosity that I’ve had for a while, I’m now going to change the update API method to async:

        [HttpPost]
        public async Task<IActionResult> Post(WeatherForecast weatherForecast)
        {
            DailyForecast forecast = new DailyForecast()
            {
                Date = weatherForecast.Date,
                Summary = weatherForecast.Summary,
                TemperatureC = weatherForecast.TemperatureC
            };

            _stressTestDbContext.Add(forecast);
            if (await _stressTestDbContext.SaveChangesAsync() != 0)
            {
                return Ok();
            }
            return BadRequest();
        }

Again, 1500 records were created:

Here’s the report:

What an interesting result. Making the update async seems to have slightly reduced the throughput. This is running locally, and I only have a 4 core machine, but I would have expected throughput to slightly increase here, rather than decrease.

Entity Framework 3.1 Gotchas

I’ve recently been upgrading an EF Core 2.x project to EF Core 3.1. In doing so, I came across the issues in this post. Hopefully, next time, I’ll look here first!

Include has changed

If you’re using .include in a lambda that’s based on a DbSet, you may have something akin to the following:

var result = animals
                .Select(a => a.Name)
                .Where(a => a.Type.Name == "Duck")
                .Include(a => a.Type)
                .ToList();

Whilst this does work in EF 2.x, it will not work in 3.x; you’ll may get the following error:

System.InvalidOperationException: ‘Include has been used on non entity queryable.’

The issue here is that you’re restricted as to how you can use Includes. You’ll need to use something more like this:

var ducks = animals
                .Include(a => a.Type)
                .Select(a => a.Name)
                .Where(a => a.Type.Name == "Duck")
                .ToList();

Should you wish to include multiple related entities, you can use the following syntax:

var ducks = animals
                .Include(a => a.Type)
                .ThenInclude(a => a.EnvironmentInformation)
                .Select(a => a.Name)
                .Where(a => a.Type.Name == "Duck")
                .ToList();

Beware of Unions

Unions don’t actually work in Entity Framework Core. They never have. What this means, is that in 2.1, when you issues this type of command:

var ducks = animals
                .Include(a => a.Type)
                .Select(a => a.Name)
                .Where(a => a.Type.Name == "Duck");

var geese = animals
                .Include(a => a.Type)
                .Select(a => a.Name)
                .Where(a => a.Type.Name == "Goose");


var combined = geese
               .Union(ducks);

What actually happened was that the two queries would be run, the results brought down to the client and joined there. In 3.x, you get something like the following error:

System.InvalidOperationException: ‘Set operations over different store types are currently unsupported’

Essentially, what this forces you to do is ether explicitly bring the results down to the client yourself:

var ducks = animals
                .Include(a => a.Type)
                .Select(a => a.Name)
                .Where(a => a.Type.Name == "Duck")
                .ToList();

Or run the query on the server by employing something like a Stored Procedure.

References

https://github.com/dotnet/efcore/issues/18091

Debugging an Asp.Net Core React Application in Azure

I’ve recently been working with an Asp.Net Core ReactJS application. When trying to debug this remotely, I switched on Development mode in order to get a stack trace when it crashed:

Instead of the stack trace, I got this:

An unhandled exception occurred while processing the request. AggregateException: One or more errors occurred. (One or more errors occurred. (The NPM script ‘start’ exited without indicating that the create-react-app server was listening for requests. The error output was: )) System.Threading.Tasks.Task.ThrowIfExceptional(bool includeTaskCanceledExceptions)
InvalidOperationException: The NPM script ‘start’ exited without indicating that the create-react-app server was listening for requests. The error output was:

This is, in fact, caused by the following code:

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (_env.IsDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });

This uses the setting “Development” to determine whether to start a local React server; which will fail on a remote server. However, I want to see a stack trace, which is here:

            if (_env.IsDevelopment())            
            {
                app.UseDeveloperExceptionPage();
            }

The problem here is that “Development” has two functions – it displays a stack trace, and it manages all these variables that should only run on your machine. What we need are two settings that both mean “Development”; one that means that we’re running locally, and one that we’re trying to debug. Start with an environment variable:

You can set this to anything you choose… But I’ve gone with “LocalDevelopment”.

The next step is to find all the places that check IsDevelopment, and replace them. What we essentially want is this:

                //if (_env.IsDevelopment())
                if (_env.IsEnvironment("LocalDevelopment"))
                {

However, we can create our own extension method, so that the code looks a lot neater:

        public static bool IsLocalDevelopment(this IWebHostEnvironment env)
        {
            return (env.IsEnvironment("LocalDevelopment"));
        }

Remember that IsEnvironment() is actually an extension method itself, so you would need to include:

using Microsoft.Extensions.Hosting;

In your extension class.

What to change

The following places will, at a minimum, need replacing for a standard web app. The stack trace should be displayed in either situation:

        public void Configure(IApplicationBuilder app)
        {
            if (_env.IsDevelopment() || _env.IsLocalDevelopment())                  
            {
                app.UseDeveloperExceptionPage();
            }

The React check that started all this:

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (_env.IsLocalDevelopment())
                {
                    spa.UseReactDevelopmentServer(npmScript: "start");
                }
            });

Also, if you’re using local secrets, you’ll need this in Program.cs:

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder
                        .ConfigureAppConfiguration((hostingContext, config) =>
                        {
                            if (hostingContext.HostingEnvironment.IsEnvironment("LocalDevelopment"))
                            {
                                config.AddUserSecrets<Program>();
                            }

Because, by default, local secrets are only added for Development only.

Summary

That’s it, you can now set the ASPNETCORE_ENVIRONMENT to Development on a remote server, and you should get a stack trace.

Configuration and Dependency Injection

In this post, I wrote about how to mock out the configuration for an application. What I did not cover in that post was whether it was a good idea to pass around IConfiguration. The answer is that, at least in my opinion, it’s a very bad idea.

In this post, I’d like to discuss why I think it’s a bad idea, and my take on a better idea.

Single Responsibility

The first reason is that you are, essentially, breaking the principle of single responsibility. Let’s imagine that we have a class that accepts an IConfiguration as a parameter. When you need an element from the configuration, you have to issue a command like this:

var myValue = new _configuration.GetValue<string>("MyValue");

So, what’s wrong with this? It’s not exactly complex code, and it’s intent is clear. However, your method is now doing two things: it’s doing what it was intended to do, and it’s reading from the configuration. If MyValue changes (say you want to call it “MyNewValue”) then you have to change your method – but your method should not care where, or how this value is retrieved! Let’s say my full class is this:

public class CalculateTemperature 
{
    private IConfiguration _configuration;
    public CalculateTemperature(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public bool IsFreezing(double temperature)
    {
        string scale = _configuration.GetValue<string>("TempScale");
        switch (scale)
        {
            case "Fahrenheit":
                return temperature == 32;

            case "Centigrade":
                return temperature == 0;

            case "Kelvin":
                return temperature == 273;

        }
    }
}

Okay, so I have a class, and a method – the class is responsible for temperature calculations, and the method for telling me if a given temperature is the freezing point of water. However, the IsFreezing method also gets a setting from the configuration file. What this means is that the method above already has a potential bug: what if the setting is not present, or it’s set to some other temperature scale, “Celcius” for example; so you now end up with a method that looks like this:

    public bool IsFreezing(double temperature)
    {
        string scale = _configuration.GetValue<string>("TempScale");
        switch (scale)
        {
            case "Fahrenheit":
                return temperature == 32;

            case "Centigrade":
            case "Celcius":
                return temperature == 0;

            case "Kelvin":
                return temperature == 273;

            case default:
                throw new Exception($"Temperature scale is unsupported");
        }
    }

Buy why should this method have to deal with what’s in the configuration file? A better implementation of this method would be something like this:

    public bool IsFreezing(double temperature, Scale scale)
    {
        switch (scale)
        {
            case Scale.Fahrenheit:
                return temperature == 32;

            case Scale.Centigrade:
                return temperature == 0;

            case Scale.Kelvin:
                return temperature == 273;
        }
    }

Now I can create a config full of ANSI art for all this method cares; and as a result, I can get rid of IConfiguration out of the class.

Testing

The second reason, as I think I implied, is that it is not straight-forward to mock out the IConfiguration class. That fact that I created a blog post on the subject means that it needs one (at least for me), which means it’s far too much hassle; which means that classes and methods that contain this are less likely to be tested.

The Real World

The example I’ve given above isn’t a very realistic example, and I’m sure that no-one reading this would create a method that read from the config for a setting that so clearly relates to the method; however, the following is a very common thing, and I’m sure that you have written something akin to this, somewhere (I know I have):

public class TemperatureRepository
{
    private IConfiguration _configuration;
    public CalculateTemperature(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public bool WasFreezingLastWeek(DateTime dateTime)
    {
        string connectionString = _configuration.GetValue<string>("ConnectionString");

        . . . 
    }
}

The exact same argument applies to this, as did for the method above, but this doesn’t feel so wrong. The reason is that you know what the Startup.cs call looks like when your class looks like this:

public class TemperatureRepository
{
    private string _connectionString;
    public CalculateTemperature(string connectionString)
    {
        _connectionString = connectionString;
    }

    public bool WasFreezingLastWeek(DateTime dateTime)
    {
        . . . 
    }
}

You either need to create the class before you inject it, or do something like this:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<ITemperatureRepository>(srv => 
    {        
          new  TemperatureRepository(Configuration.GetValue<string>("ConnectionString"));
    });
}

In fact, I don’t think this looks too bad but, recently, I’ve been using a slightly different approach, which allows you to avoid this: that is to register a class that contains your config. If you have three or four values, then maybe have one config class for your entire application; if there’s more then have as many as make sense:

public void ConfigureServices(IServiceCollection services)
{
    var configClass = new ConfigClass()
    {
        ConnectionString = Configuration.GetValue<string>("ConnectionString");
    };

    services.AddScoped<ConfigClass>(configClass);
    services.AddScoped<ITemperatureRepository>();
}

Summary

I’m not sure this warranted such a long blog post, but it’s a Saturday afternoon and the pubs are closed!

Caveat

None of the code in this post has been tested – it’s all been written in OneNote – I didn’t think the specific code syntax was particularly relevant, given it’s more of an opinion post.

Add Storage Queue Message

I’ve written quite extensively in the past about Azure, and Azure Storage. I recently needed to add a message to an Azure storage queue, and realised that I had never written a post about that, specifically. As with many Azure focused .Net activities, it’s not too complex; but I do like to have my own notes on things.

If you’ve arrived at this post, you may find it’s very similar to the Microsoft documentation.

How to add a message

The first step is to install a couple of NuGet packages:

Install-Package Microsoft.Azure.Storage.Common
Install-Package Microsoft.Azure.Storage.Queue

My preference for these kinds of things is to create a helper: largely so that I can mock it out for testing; however, even if you fundamentally object to the concept of testing, you may find such a class helpful, as it keeps all your code in one place.

 public class StorageQueueHelper
{
        private readonly string _connectionString;
        private readonly string _queueName;

        public StorageQueueHelper(string connectionString, string queueName)
        {
            _connectionString = connectionString;
            _queueName = queueName;
        }

        public async Task AddNewMessage(string messageBody)
        {
            var queue = await GetQueue();

            CloudQueueMessage message = new CloudQueueMessage(messageBody);
            await queue.AddMessageAsync(message);
        }

        private async Task<CloudQueue> GetQueue()
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_connectionString);
            CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
            CloudQueue queue = queueClient.GetQueueReference(_queueName);
            await queue.CreateIfNotExistsAsync();

            return queue;
        }
}

The class above works for a single queue, and storage account. Depending on your use case, this might not be appropriate.

The GetQueue() method here is a bit naughty, as it actually changes something (or potentially changes something). Essentially, all it’s doing is connecting to a cloud storage account, and then getting a reference to a queue. We know that the queue will exist, because we’re forcing it to (CreateIfNotExistsAsync()).

Back in AddNewMessage(), once we have the queue, it’s trivial to simply create the message and add it.

References

https://docs.microsoft.com/en-us/azure/storage/queues/storage-tutorial-queues

React, Redux, and Typescript – Why, What and How

This article covers adding Redux to an existing React application.

Redux is one of those technologies where you get introduced to it, and you think: this seems overly complex to solve such a simple problem. Quite often, this is, in fact, the case. I once read a post (which I cannot find) by Dan Abramov where he said a similar thing himself. Redux is a state manager, and if you’re using it for React, React does have facilities to manage its own state, so you may not need Redux.

In fact, from what I’ve seen, I’d say you’re better leaving it until you know you need Redux.

Why

So, how will you know when you need Redux?

Well, you’ll know because you’ll raise some state, and suddenly realise that you’ve raised it into a component that has no business managing that state. My specific example was trying to manage user permissions.

Imagine the following menu structure:

Layout.tsx
	NavMenu.tsx
		NavItem (React-Strap)
		LoginMenu.tsx (accesses the DB to get user info)

I needed to store a user permission, and conditionally display a menu option (NavItem); these are held in a LoginMenu component. This meant that my state would need to be in NavMenu.tsx – but that’s a strange place for the state regarding a user to live. Additionally, other parts of the application would need access to this, and so it’s time for a state manager.

What

Okay, we’ve talked about why you might want to add Redux. Let’s see, exactly what Redux is. Essentially, there are three concepts to Redux. Before I continue with my second rate explanation, I would strongly suggest you jump over to Dave Ceddia’s blog. If you’re trying to do this in Typescript, then come back afterwards – otherwise, stay there, there’s nothing I can tell you that he doesn’t cover in this article.

Actions

An action is simply an object that contains a property called type. It can contain other objects, too, and is used to send information from your application into the Redux Store.

Reducers

Reducers are the engine of Redux. They accept an action, and the existing state of the application, and they return a new state.

Store

The store holds the current application state. You cannot change this directly, but through an action.

How

(In this section, I’ll include some imports and file names – I’ll talk about project structure towards the end, and the imports and filenames will make sense then)

Let’s imagine that your application is a game, where you can move a character left and right; your application state might look like this:

export interface IStore = {
    position: 0
}

We’ll also need to create the store, which we can do in the same code file:

Store.tsx

import { reducer } from '../State/Reducer';
import { createStore } from 'redux';

export interface IStore {
    position: number;
}

const store = createStore(reducer);
export default store;

Okay, so we have a state: we said that actions are the only things that can affect state (in fact we said through an action): let’s see what an action might look like:

export const MOVE = 'MOVE'

interface MoveAction {
    type: typeof MOVE
}

This would be sufficient, at least, this is all Redux needs; however, we need to know which way to move, etc. Convention seems to be to add a payload property; let’s see what that might look like:

Actions.tsx

export const MOVE = 'MOVE'
export interface Message {
    user: string
    message: string
    timestamp: number
  }
  
interface MoveAction {
    type: typeof MOVE
    payload: Message
}
    
export type ActionTypes = MoveAction;

I’ve used a generic Message – you could make this specific to your action, but this sort of approach means that your messages are consistent across actions.

So, now we have a store (somewhere to keep the state), and an action something to indicate that we wish to update the state. However, looking at the action, it doesn’t seem to do too much updating… In fact, it’s just a message – it could even be just a string. We now need the final piece of the jig-saw: the reducer takes the action and updates the state; let’s see what that might look like:

Reducer.tsx

import { InitialState } from './Store';
import { ActionTypes, MOVE } from './Actions';

export function reducer(state = InitialState, action: ActionTypes) {  
    console.log (action);
    switch (action.type) {
      case MOVE:
        return {
            ...state,
            position: state.position + parseInt(action.payload.message)
        }
        
      default:
        return state;
  
    }
    
}

There’s quite a lot here: (we’ll come back to InitialState shortly). Let’s go through a piece at a time.

The first thing we’re doing is checking the type parameter:

    switch (action.type) {
      case MOVE:

In a real world situation, there would be many options: you’re unlikely to have a single action, so the switch statement is necessary.

Remember earlier, we defined the action as MOVE:

export const MOVE = 'MOVE'

Which enables us to check for MOVE, rather than the magic string “MOVE”.

Inside the MOVE block, we’re accessing the payload:

      case MOVE:
        return {
            ...state,
            position: state.position + parseInt(action.payload.message)
        }

The reducer must be a pure function: that is, it accepts and returns data, but it does not change anything; as a result, we’re returning a new version of the state that was passed in. We’re setting the new state to have a position which is based on the current position, but we’re not changing the state.

This code will crash if the message is set to “qwerty” (so if you’re doing this sort of thing yourself, you should do it better than I have!)

Finally, the default: block simply returns the same state that it was given; i.e. the state remains unchanged.

Initial State and Project Structure

I said we’d come back to initial state. In the reducer, we have the following:

export function reducer(state = InitialState, action: ActionTypes) {  

We have to define a starting state for the store; and you can do that like this:

Store.tsx

export const InitialState: IStore = {
    position: 0
}

Before we move onto the application changes, let’s quickly talk about where this all goes. The frustrating answer is, it’s up to you; however, I found a structure like this quite useful, as it keeps all the Redux plumbing in a single place:

Plugging this into your app

So far, we’ve created a lot of code, but it’s been completely separate from your React application. Plugging it in is actually quite trivial. Let’s start with Index.tsx; you’ll need to import your reducer:

import { reducer } from './State/Reducer';

In the render function, you’ll then need to add the store into the DOM:

ReactDOM.render(
  <Provider store={store}>
    <BrowserRouter basename={baseUrl}>
      <App />
    </BrowserRouter>
  </Provider>,
  rootElement);

We can then access the store inside any component by simply referencing the Store.tsx:

import store from '../../State/Store';
import { MOVE } from '../../State/Actions';

And then calling the dispatch function:

            store.dispatch({
                type: MOVE,
                payload: {
                    user: user.name,
                    message: "1",
                    timestamp: new Date().getTime()
                }
            });

We can also get the state by using this:

store.getState();

Connecting the State

This works okay, but there is an easier way; you can use the Redux Connect function. Essentially, instead of exporting the React class, you instead export a wrapper for it. Before that, though, you need to work out what you’re trying to map. You’ll need to split your props into three groups:

1. Props from the store that you want in your component
2. Props that you want to be passed into your component
3. Props from the store that are actually functions; that is, dispatch functions

You would then rewrite your component like this:

import { connect } from 'react-redux';
interface StoreProps {
   position: number;
}
interface OwnProps {
   ...
}
interface DispatchProps {
   ...
}

type Props = OwnProps & StoreProps & DispatchProps;
interface IState {
   ...
}
class GameComponent extends Component<Props, IState> {
   ...

Notice that you’re no longer exporting the GameComponent class. Instead, you add the following:

function mapStateToProps(state: IStore) {
  return {
    position: state.position
  };
}
export default connect(mapStateToProps)(GameComponent);

This allows you to expose only the properties relevant to the component, but not the properties that you take from the Redux store.

References

https://blog.logrocket.com/why-use-redux-reasons-with-clear-examples-d21bffd5835/

https://daveceddia.com/redux-tutorial/

https://daveceddia.com/access-redux-store-outside-react/

https://redux.js.org/recipes/usage-with-typescript

Using Kudu to Edit a Deployed app.settings file

When you deploy an Azure App Service, there are occasions when you may need to change the running values. Exactly how you may do this depends heavily on how the service was deployed, and how you are managing your variables. You can typically overwrite variables inside the app service; however, the running appsettings.json and web.config will be deployed with the app, and you can edit these directly (whether you should or not is a different question).

It’s your foot

These instructions let you change the deployed files on your App Service. Doing so may result in the behaviour of the site changing.

On with the show

Launch Kudu

When you select this, you’ll be given the option to select “Go”, or … not. Select “Go”.

This will take you to the Kudu console.

From here, select “CMD”; this will take you to a hybrid screen with a command console and a file navigator:

Navigate to d:\home\site\wwwroot:

Too Many Files

Initially, you may get the following error:

There are n items in this directory, but maxViewItems is set to 99. You can increase maxViewItems by setting it to a larger value in localStorage.

To get around this, select F12 and in the console window type:

window.localStorage['maxViewItems'] = 1000

After you’ve changed this, refresh the page (F5).

App Settings

To change the variables, you’ll need to locate the appsettings.json in the list (it’s alpha-numerically sorted, so it should be near the top). (Unfortunately, you can’t edit this from the command line).

When you find the file, click the edit button:

And then change the file:

When done, select Save and then restart the app service.

References

https://www.poppastring.com/blog/kudu-error-with-maxviewitems-in-localstorage