Working from home

Because of the pandemic I have been working from home for the past four months or so. In late March my company took the decision to let everybody that could work from home do so. Since then I have been sitting at my kitchen table with my laptop, but with an external mouse and keyboard.

So, what’s it been like? I must admit I like working from home a lot more then I thought. I like being in the office and talking to people, discussing things, but being a pandemic and all there’s just no way I would step on the train for my daily commute right now. It took about two weeks for me to get used to everything, but after that I’m quite happy working from home. But what about the small things? Let’s make a list, shall we?
Developers like lists!

Pros:

  • No daily commute means less interaction with people
  • Since I am not commuting I can work more hours
  • Blasting music on my Sonos speakers
  • Productivity is pretty much the same, maybe even better
  • Sitting at home all day is pretty good for my economy, I never realized I bought so much unnecessary stuff before

Cons:

  • Since I am not commuting for an hour a day I cannot find the time to listen to podcasts
  • I have no real chair to sit on or desk to work at and my body is suffering because of this
  • Small ass laptop screen to work on
  • Teams/Slack/Zoom calls have replaced face to face discussions and it’s quite tiring for the brain
  • Coffee expenses are through the roof
  • “Can you hear me?” / “Can you see my screen?” every god damn time

So the overall experience have been good for my wallet, but bad for my body. I’m still not sure for how long this will last, but at least two more months by the sound of things. I am ready to go on vacation for a couple of weeks anyway.

Figuring out Azure Alerts

Being vacation time and therefore not too much action, but with me still working, I decided to have a look at Azure Alerts to see if that would be something we could take advantage of in our daily DevOps routine.

I decided to set up an alert on average response times from one of our API:s being greater than X, and setting X to a low value (40 milliseconds) just to see what would happen.

Then I started to wait. And I waited. And I waited. Nothing.

I set it to an even lower value, this time to 20 milliseconds.
And I waited. Still nothing.

Surly there must be something wrong with Azure Alerts, right?
Nope. Looking closer at the GUI I noticed that even when the metric was in milliseconds, the threshold value was expecting seconds…
Now that’s a gotcha for ya!

If you look closely in the bottom right corner, it clearly states “seconds” and not milliseconds. I wish I had read that a couple of hours sooner than I did.

After that it worked just as I thought.

Copying strings in a less ugly way

So, for one reason or another, I was in a method that I had limited power to refactor. In this method there where two strings that, if certain conditions applied, needed to have the same value (Yeah, don’t get me started).

Let’s say it looked something like this:

s1 = "Hello";
s2 = "World";
s3 = "Hello Brave New World";

[...]
if(SomeCondition)
{
s1 = s3;
s2 = s3;
}
[...]

“So, what the hell can I do to make it less of an eyesore?”, I thought to myself.

After thinking about it, I came up with this:

private static (string, string) DuplicateString(string s)
{
    return (s, s);
}

And the end result looks like this instead:

s1 = "Hello";
s2 = "World";
s3 = "Hello Brave New World";

[...]
if(SomeCondition)
{
(s1, s2) = DuplicateString(s3);
}
[...]

Still not good, but a whole lot better!

Working with XML in C#

So, this is a post I’ve been meaning to write pretty much since I started the blog. In my adventures in programming I come across XML formats every now and then and I always forget how to create C# classes out of them. Instead of trying to find it on Google the next time, I’ll just read this post instead.

So, let’s say we have an XML file looking like this:

<?xml version="1.0" encoding="utf-8"?>
<Record>
<RecordArtist>Oasis</RecordArtist>
<RecordName>Be Here Now</RecordName>
<RecordYear>1997</RecordYear>
<RecordLabel>Creation Records</RecordLabel>
</Record>

Pretty simple structure, right? Let’s go through the motions of creating a class for this. First, you’ll need to convert the XML to XSD. Find the “Developer Command Prompt for VS 2019” and browse to where the above XML is located.

xsd.exe Record.xml

That’s it! Now you’ve got a XSD that can be used to create a C# class.
To create the class, go:

xsd.exe Record.xsd /c /n:RecordNamespace

Done! Use it in your project and you’re all set.

EDIT: A word of caution: You should always prefer having an XSD to start with instead of an XML. If the XML file doesn’t have all the fields they, naturally, won’t show up in the created class. But you already knew that.

Python and football

So, I haven’t been playing too much with Python recently but the opportunity came up today so I jumped right in!

To provide some context, we are using Octopus to deploy our stuff to Azure, and in Octopus I wrote a Powershell hack so that Octopus reported to Slack the name of the person doing the deploy. In our build chain we are using TeamCity to push our stuff to Octopus. In true CI/CD spirit some of our things are automatically deployed to Azure when a TC build is finished. When that happens, the person doing the deploy is some generic service account user in Octopus.

My colleague thought this was a boring thing: “When this happens, what about printing the name of a random footballer?” Said and done, one Google search later I found, and signed up for, Football-Data.org. They offered a couple of leagues free of charge with a rate limit of 10 requests per minute. Great! Let’s do some Python:

import random as r
import requests as req
import json as j

def Maximum(obj):
    return len(obj) - 1

def prettyPrintJson(obj):
    text = j.dumps(obj, indent = 4)
    print(text)

Minimum = 0
TokenKey = "X-Auth-Token"
TokenValue = ""
compUrlPrefix = "https://api.football-data.org/v2/competitions/"
compUrlSuffix = "/teams"
teamUrl = "https://api.football-data.org/v2/teams/"
competitions = [2000, 2001, 2002, 2003, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2021]
T = "teams"
I = "id"
S = "squad"
N = "name"

compResponseJson = req.get(compUrlPrefix + str(competitions[r.randint(Minimum, Maximum(competitions))]) + compUrlSuffix, headers={TokenKey: TokenValue}).json()
#prettyPrintJson(compResponseJson)

randomTeam = compResponseJson[T][r.randint(Minimum, Maximum(compResponseJson[T]))][I]

teamReponseJson = req.get(teamUrl + str(randomTeam), headers={TokenKey: TokenValue}).json()
#prettyPrintJson(teamReponseJson)

randomName = teamReponseJson[S][r.randint(Minimum, Maximum(teamReponseJson[S]))][N] + " (" + teamReponseJson[N] + ")"

print(randomName)

So basically, I pick a random league from the free ones, pull all the teams, pull a random team and then pull a random player for that team.

The output looks like this:

Matteo Raspa (UC Sampdoria)

I figured it was a nice touch to add the name of the team as well since I sometimes had no idea what player it was. Suddenly, Emre Can showed up in the result. Seems like the coaches are in there as well!

Playing with Python

At work we have some dedicated time each week to learning new things or improve on old things, and earlier this week I had randomly read some stuff about Python. Since I have never gotten my hands dirty with Python I decided that it was time to change that.

I started out by following this guide to install Python in my VS Code environment and played a bit with the examples provided.

Then I decided to write a function to base64 encode username and password to be used for basic auth, just to see if I could:

import base64

EncodingAsString = "utf-8"
BasicPrefix = "Basic"

def GetBasicAuth(username, password):

    encodedString = str(base64.b64encode(str(f"{username}:{password}").encode(EncodingAsString)), EncodingAsString)

    return str(f"{BasicPrefix} {encodedString}")

print(GetBasicAuth("ebolakid", "blog"))

I guess it turned out alright for being written 15 minutes after a Python installation.

EDIT: Please note that the intendation didn’t quite fit the blog…
But copy-paste into your favorite editor should work just fine.

Stop a triggered Azure WebJob

In a post way back here I wrote about temporarily stopping all Azure WebJobs within an Azure Web App. Single continuous WebJobs can be stopped manually one by one in the Azure Portal, but what about stopping a triggered WebJob?

After doing some research, and with that I mean stopping one of the triggered WebJobs in our test environment, I came to the conclusion that using the setting “WEBJOBS_DISABLE_SCHEDULE” and set the value to 1 does the trick without any fuzz.

Debugging of the Azure WebJob [Singleton] attribute

Earlier today I was debugging and chasing down a strange behavior in an ServiceBus triggered WebJob in Azure. Looking at the logs I could tell that the WebJob was triggered when a new message arrived, but after that it seemed like it was idle for quite some time before starting to process the message. Since it took (quite) some time the WebJob lost the lock on the message, and it went back into the queue for a second go at processing the same thing.

I initially thought it was due to some kind of intermittent issue with the ServiceBus, that it might be serving the contents of the message slowly and that made the WebJob look like it was idling before the lock expired.

Since I couldn’t track the issue down all the way, I introduced a AutoRenewTimeout policy on an arbitrary number of minutes and started to follow the messages more closely in the logs. What I found was really interesting: The WebJob triggered on a couple of messages that came in at the same time, but after that it started to process the messages one by one. That means that the last couple of messages had their locks lost because they were claimed way before the actual processing began.

Going back to the code I noticed that the WebJob had the Singleton attribute which guarantees that only one instance of the WebJobs runs at the same time. For some, still unknown, reason it honors this and only runs one instance, but at the same time also honors the MaxConcurrentCalls value. So what was happening was that the WebJob first claimed a lock on 16 messages, and them began processing them one by one. No wonder the lock had expired on the last couple of messages…

When the singleton attribute was introduced in the code it was probably the MaxConcurrentCalls value that they were looking for.

So, a word of caution: The singleton attribute, used by itself without other configuration updates, might give you some weird results that aren’t actually what you’re after.

The origin of ebolakid

“Ebolakid? I feel offended!”

First of all: It’s “ebolakid” with all lower caps.
Second of all: Don’t. It’s just a name.

When choosing an online handle you need to choose carefully. I’ve used ebolakid on and off for about 15 years now, and like all things it has an origin. Good or bad, it comes from somewhere.

About 18 or 19 years ago I was in an (for now) undisclosed band. The old songs are on Spotify, maybe I’ll write about it some day. For some reason, as part of our pre-show routine, we huddled up in a circle and put our hands in the middle just like your local sports team does. When everybody was ready we shouted “EBOLA KIDS!” from the top of our lungs. Why we did that I can’t remember. When I was registering for Xbox Live back in 2004 I needed a good gamer tag. For some reason I thought that “ebolakid” would be cool to register and It’d be funny to see how long it took Microsoft to make me change the name.

They never did, so 15 years later I’m still ebolakid on Xbox Live.

When I got into the hobby developer business in 2014 I needed a name to hide behind. For better or worse, I reused ebolakid and everything was set in motion. A year or two later I registered ebolakid.com and here we are.

Stop an Azure WebJob

After a couple of failures due to Azure WebJobs not stopping when I thought they were going to, I figured out the only fail safe (?) option that will stop both Triggered and Continuous WebJobs. Not just that: It’s dead easy!

You can try to stop the App Service itself, but for some reason that does not apply to the WebJobs, and God only knows why. Stopping an individual Continuous WebJob can be done from the Azure Portal, but what about stopping multiple WebJobs including a Triggered one? I’ve even experienced that deleting a WebJob didn’t stop it, I’ve actually seen that multiple times.

To stop all WebJobs, both Triggered and Continuous, add WEBJOBS_STOPPED with the value 1 via “Configuration” / “Application settings” in the Azure Portal. As far as I’m concerned this has worked beautifully every time I’ve tried it.