However, after calling this code, a 302 is returned to the browser for the redirect but it doesn't include the Location HTTP header pointing to the new location, so the browser does not redirect. Instead, the user has the click the link on the displayed page.

I thought this was very strange and dug into the code that produces the Redirect inside System.Web.HttpResponse and found that the Location was always added using the same url that was correctly inserted into the response body. Clearly something was removing the header after it was added and before the redirect took place.

After I commented out SignOut(), the redirect worked correctly so somehow, for some reason, IAuthenticationManager.SignOut() is removing the Location header, but AFTER it has been added in the next line.

I haven't found a reason on stack overflow but I might dig a bit deeper into SignOut to find out what is happening.

Monday, 26 September 2016

I bought some remote-control servos from China recently - got stitched up a bit with VAT getting added later and DHL charging me £11 for the processing, adding a total of 50% to my order so they ended up working out about £2.50 each. I think you can probably get them cheaper if you buy them in smaller numbers so they fly in under the radar as it were (legally!).

Anyway, I knew how they were supposed to work, connected one to my PIC prototype board and....it didn't work! Nothing.

While Googling the potential problem, I have learned the following, some of which is generally good advice for most things!

1) Start with the simplest PIC program you can and if possible, add some checks to make sure it is working as expected. For instance, I made a program that set two servo positions and changed every 2 seconds. I then connected the timer to another LED so I could make sure that the program was running at the correct rate and probably working.
2) Remember that the servo will draw a significant amount of power when it is moving (as little as 45mA but potentially much more). Most controller outputs cannot source that level of current so don't do what I did by connecting the power wire to a switched output of the PIC (I did it so the plug would fit somewhere useful on my board where I couldn't get 5V GND and a digital IO next to each other!)
3) If it moves but doesn't go where you want it, it is possible the pulse width to position is not what you think. See if you can find the spec for your servo - it is not always that easy. You could also experiment with different values.
4) Check (carefully) that the arm is not stuck at one of the extremes. Although the gearing will make the arm hard to move, even under no load, if you are careful, you should be able to move it away from either end.
5) It obviously could be broken so having a second spare one is obviously helpful.
6) Be careful with oscillator settings. If you have accidentally got the timings wrong, the pulses could be 1000s of times too long or short. Again, it is worth connecting a spare LED to an output to ensure the cycle times are as expected.

So we use Cloud Services, they were the most PaaS you could get 4 years ago when PixelPin started but they are a bit old hat. They are thinly veiled VMs, which are managed by Microsoft but they don't permit an auto scale to happen very quickly and because they don't make good use of shared hardwre, they are not the most cost effective.

Enter App Services, which supports API, mobile apps and web apps but for less money. They also, more importantly, provide a very quick therefore effective way to scale from 2 to 20 or 20 instances in only a few seconds, using hot standby services.

You have to learn the concepts and setup of App Services on Azure. You need to learn about plans - shared and dedicated and how you can then have multiple apps hosted on the same plan (which is cool, because you aren't paying more to host more apps, just adding more load to what you are already paying for).

You can theoretically deploy directly from Visual Studio using "Publish" but this always crashes on my machine, which leaves either publish to Git and get App Services to pull in the changes (works OK but you have to use Git, which I hate, as well as spend time working out the deployment workflow). You can also use VSTS, but only if you use Git or otherwise you have to push the deployment from VSTS onto App Services, again, more learning required.

You cannot run your startup script like you used to before because you are basically sharing an environment docker style. For instance, we setup cipher suites by running our startup script on Cloud Services but we are paying for the whole system so that's OK. You can't do that on App Services, you can only control your web.config settings (and I can't guarantee that some of these might not work as expected/be overridden/locked by the parent config). You must CAREFULLY consider what your startup script does and whether it can be done another way or you can accept the risk of not doing it.

Things like certificates and app settings are done differently. App settings work in a similar way, except you no longer access them with the Azure Runtime functions but instead, simply access them as App Settings. It also means if you want to deploy them, they are specified as App Settings in config instead of settings in your cscfg file. There might be security considerations because of this and there are various ways to workaround that.

Certificates are more a pain. You no longer specify them in your cscfg files and you don't have direct access in the same way. What you have to do is add an App Setting to expose the certificate to your app, which is then done in the CurrentUser store (since you are sharing hardware!). An article describes it here: https://azure.microsoft.com/en-us/blog/using-certificates-in-azure-websites-applications/ but it looks like you can either expose 1 or all certificates using the App Setting.

All of the stuff you used to set in your cloud project (VM sizes, numbers etc.) is done in the portal or using an Azure Resource Manager (ARM) Template. This decouples the development process from needing Visual Studio and a specific project type etc. and opens up the use of things like Kudu or docker to deploy code directly to Azure.

If you used cloud services for session then you will also need to change that to use Redis, which to be honest is probably cheaper and easier than the Azure Cloud Service provider anyway.

No doubt I will find some more things that are different but be warned! Spend some time on it, attempt to move a really cut down version of the app so you can see the sorts of issues you are having and then spend some time planning how you will need to change things to move forwards.

That said, I am excited about moving to App Services and think we will eventually get a much more responsive and cheaper system as a result.

Friday, 16 September 2016

I have had a terrible week at work. I have basically done nothing for 4 days due to a whole raft of issues related to mostly Microsoft Technologies. Partly due to bugs and partly due to lack of understanding (or both). What people don't always realise is that bugs are annoying to experts but fatal to newbies because when you don't know what something is supposed to do, you cannot spot the bug.

My problems this week have included:

Attempting to get a Load Balancer and Scale Set configured on Azure except the interface was allowing invalid configurations and there is no obvious feedback on healthcheck probes. Needed MS support.

Trying to deploy directly from Visual Studio to Azure App Services except VS publish crashes due to a weird dll reference problem (its looking for an old method in a new DLL). If MS hadn't CHANGED the interface to the dll, there wouldn't be a problem. Spent a DAY removing old visual studio installs and installing VS 2015 again and still no dice. Broken out of the box.

Trying to deploy to Azure instead via VSTS. This doesn't support TFVC, although the docs don't say this, you just wonder why your project is not listed in the portal. Roll on a few days and have finally worked out that you have to use Git on VSTS.

Create a Git repo, check in all my code and get the system to auto deploy to Azure. Deployment error - nice and esoteric, basically means it can't access my private repos but this is not obvious. I can't even remember how I realised this.

Tried to work out how to get Nuget working properly in my project. The project seemed to be OK according to the 10 different versions of documentation, decided I needed feed credentials that were not encrypted to use on App Services but the VSTS portal has changed and the Get Credentials button isn't there any more, despite the documentation being based on the old dialog which worked. So no credentials and no articles describing what must be App Services 101 - using custom NuGet packages. Decided I would have to copy the NuGet dlls into the project manually and reference them locally to the project for now.

Finally get my app up on App Services and a big fat error. No site, just a random 500 error. Tried to remotely debug as per the helpful guide. Doesn't work, can't connect.

DNS outage on Azure for about 4 hours affecting our production system!

Decide the only way this is going to work is to start from a vanilla app in Visual Studio and add the stuff in bit-by-bit until something breaks. Of course, I can't use the Publish mechanism, that's still broken even on a new project.

The vanilla app loads OK, I set up SSL and a public DNS so this should be good right? Add some files, try and do as few as possible but of course the references quickly spider and I end up with half the app in place. Deploy it - compile error. This time, the generously supplied gitignore file for Visual Studio excludes pfx files, which seems reasonable except my system uses them so I had to include them. The app still displays (it doesn't do anything but hey).

Copy the rest of the app over and commit, error 500, 502, all kinds of stuff like that. Custom errors off (doesn't work) turn on all the supposedly wonderful diagnostics, none of them say anything useful. Try and upload debug version etc. eventually find that there is a duplicate web config entry. Why does this work locally? So it will work now? Nope, just more and more server errors and no way to debug them. Remote debugger still doesn't work and all attempts to enable logging and everything else is futile. I find a nice article about debugging errors using App Services SCM endpoint but these also don't match the reality. The "capture now" button simply doesn't exist.

I decide there is only one thing to do. Revert back to the last good deployment that was still looking like the default MVC app (without CSS!) and add in items in much smaller stages, if possible. It's clearly a configuration type issue to make it 500 instead of getting an Application error so this should be doable.

And then there was GIT. I'd forgotten how much I hated it and locking horns at 8pm on Friday evening is not comforting to the soul! Subversion and even TFS are easy enough to revert but, remember, I HAD to use Git to deploy to Azure App Services so what do I do?

I'll show the log first (Tortoise Git) to see where to revert to. Choose the right point and "Reset master to this". OK, soft, medium or hard? No idea but let's copy the entire folder first - I have been burned before. OK, medium looks good.

Hmm, it says it's done something but all my files are still here - what a pile of crap. Why would I ever want to reset something and leave the files here? OK, let's try again. Reset hard right? OK, some things seem to have been reverted but I still have a load of files present that were not present when this was committed!! Why are they here? Copy the entire directory again, I know I am going to be loud swearing soon!

Try and open the project into Visual Studio to see what it is looking like and it won't open - some IIS config problem. Why? It was working fine when I committed this code. Fixed that and it looks OK but still has all these uncontrolled files. Why are they there? Git - I hate you.

Manually delete the files I don't need, commit the ones that should belong to this build. It looks like a pretty early cut but I can handle that, I have all the files elsewhere (please God, let me have the files elsewhere and Git not trying to also reset the other files since I copied a git folder!).

Now. Git push. FAIL. Oh for f**k sake. Pushed files were rejected because your branch is based on an earlier part of the remote branch. Oh really? Well I did f**king reset it so perhaps you could simply ask me, like a sane product, do you really want to overwrite everything with this. Nope. Talks about another load of crappy commands I might have to use to get this to work.

Git I hate you. After looking at the (futile) attempts at newbie Git tutorials, which still leave me utterly confused, even the ones with nice pictures, do you know what I am going to do (and this is VERY damming of the cult of Git and its contempt of people like me who don't get it): I am going to start again. That's right. I am going to delete the entire Git repo, create a new one and copy files in manually. Won't that take a while? I've already lost about 4 hours and have moved on precisely zero knowledge so why not burn 4 hours doing something manually that VCSs are supposed to automate.

Sourcesafe used to just about work as long as you used it in the Sourcesafe interface. Trying to use Sourcesafe from inside Visual Studio was fraught and it still is. TFS, VSTS, TFVC, whatever you want to call them are basically still Sourcesafe, you can see by the files that are dumped in controlled directories and the weird entries that are added to project and solution files.

As with many decisions in life, to know we are doing it properly, we need to ask the most pure questions: What is source control supposed to do?

Answer: It is supposed to provide protection for code

It also provides a record of changes but fundamentally it is about protecting code from accidental changes - which can be reversed if needed and also from intentional changes that can be traced easily by check in comments. If your Source Control does not ALWAYS protect code, it is not good.

Let's look back to good old Microsoft who have somehow managed to mangle Sourcesafe into several different forms and somehow keep its geriatric body alive. How does Source Control work in Visual Studio?

1) Connecting a project to source control. This is a complete ball ache in Visual Studio. In VS2015, there is a Team Explorer, a Source Control Explorer, Context Menus, Menus under File->Source Control and workspace mappings. Do I create the project first in VSTS and then connect or can I simply "create new project" from my uncontrolled source? This is so hard to follow that even though I have done it about 20 times on different projects, I still can't do it right first time. Also, why is it that sometimes you "Add solution to source control" and not all of the projects show that little green plus symbol? Answer - no idea.
2) Disconnecting a project from source control. The short answer is that I think this is largely impossible UNLESS you disconnect, move the project to another folder and rename the destination project in Source Control. You can select File->Source Control->Advanced! and then choose to unbind the project. Why this is advanced, I do not know. Unbind it and guess what? There are still source control binding files on the disk, it is just pretending to be unbound. Try and bind it to another project in Source Control? Good luck, you will get that infamous message, "The item blah is already under source control at the selected location". What? I just disconnected it! No you didn't, we were just pretending.
3) Deleting a project on the server. Be VERY careful when you do this. Do you know what happened last time I did that? Visual Studio decided that since I deleted the server project, I obviously didn't want any of my local files. Yes, it deleted everything on my local disk, which is the OPPOSITE of what anyone ever wants. At minimum, you would ask, by default it would keep whatever was there. Another gotcha is basically Visual Studio being completely unable to handle the deleted project when there are local changes - how does it know there are local changes if the project was deleted in SCC? It basically forces you to undo the pending changes, even though they are irrelevant and if you don't? You get errors every time you try and edit workspace mappings. What happens if you undo your changes? You guessed it, you lose all the changes which you cannot undo because the project is now deleted!
4) Moving a project from one SCC binding to another? Forget it. Best way is to great a new project and manually copy stuff over. Honestly, that is Source Control 101 but for some reason, MS still haven't got the basics right.

Other options? You can use the command line or some tool outside of VS to manage source control, it's annoying but it seems to work much better than VS does and makes more sense because everything is in the same place.

The truth is, if you do this all the time, you will HOPEFULLY not delete anything but for the rest of us, be prepared to lose your job...oh yeah and ALWAYS make backup copies of folders before doing anything other than checking-in changes to files.

Thursday, 15 September 2016

So we have an authentication-as-a-service product called PixelPin. We want to load test it so we can a) tell our customers that it can definitely handle their X,000 customers logging in at the same time, and also to benchmark performance to find any bottlenecks and let us see the effect of architecture changes.

So far, so good.

When it comes to planning the load test, it is actually really hard. Setting up the tests is easy enough using Visual Studio Team Services and Visual Studio Enterprise Edition but actually working out what to test and how is hard.

Why? Because there are so many variables. Various cloud services, bandwidth, CPU, memory and even dependent services that are used for testing like a dummy OAuth login site. If the test site cannot handle enough user load then the load test won't be stressing the tested system anywhere near enough.

In fact, our first step is to try and work out which variables can be ignored. If a certain system is hardly struggling to manage the load, let's not spend any time with that and instead work on the really slow parts.

Another question that can be hard is how to simulate a realistic load test. There's no point saying we can handle 5000 requests per second hitting the home page when that is not what people will be doing. We need to think about the mix of journeys, the effect that caching and browser mix might have on things and a whole host of other reality checks.

You also get another problem if you are not careful about setting up your test environment. We created 5000 test users and put them into a spreadsheet that the tests use to fire at the test site but if you aren't careful (and we weren't), then the same user account is hit twice in VERY quick succession and causes an error that would never happen in real life (unless a real user and an attacker happened to do that). You start having to really understand what the load test is doing under the covers, how is it selecting the users from the spreadsheet? Can I have 2 test agents running at the same time or will that cause parallel errors that shouldn't happen?

It is going to take weeks to sort through the random errors (errors which are usually caused by an underlying problem, the error itself doesn't show that) and then to decide how to measure what we are trying to measure in a suitable way.

Wednesday, 14 September 2016

Introduction

So we are trying to create a test environment for load testing our application. Unfortunately, we use older resources (Cloud Services and VMs) and these were all originally deployed manually so I have been trying to create a close to exact replica of our production system bit-by-bit.

Resource Manager is the new thing in Azure and it is basically a concept and set of APIs that allow you to group resources together and to script the deployment, which will be very useful going forwards for our multiple deployments.

One of the things I had to replicate was a VM set, which we were using to run a PHP app. The reason we used a VM was that the cloud service tools for PHP had various shortcomings and were not suitable so I went old-school. Although there are now App Services Web Apps for PHP, we want to load test the original architecture so that we can then benchmark that against changes, including moving to App Services.

Virtual Machine Scale Sets

To use the new portal, you have to use Resource Manager and resources that are compatible and the closest to classic VMs are called Virtual machine Scale Sets which are basically the same thing but with more configuration.

I assumed this would be a relatively quick and easy setup like it was on classic but the problem with all configuration-heavy features is that if it doesn't work - which it didn't - it is hard to know which bit is wrong.

I got it to work eventually so I thought I would describe the process.

Create the Scale Set

This is like normal. Go to your subscription in the new portal, click Add and choose Virtual Machine Scale Set. It will list several, I am using the Microsoft one. Select it and press Create.

Fill in the details. The password is what RDP is set to use. It is useful to choose a new Resource Group since there will be about 10 resources created so it is easier to group them into 1.

The next page gives you options for the IP address (you can use the default), a domain name, which must be globally unique and options like whether you want to auto-scale. Auto-scale is only useful if you are using an image that will automatically install and run when the instances are increased. In my case, I am installing the code manually so auto-scale isn't much use!

I think that the only way to correctly template the installation is to use a Resource Manager template which is not supported in the portal - so the portal just gives you the vanilla setup.

Setup your instances

By default, the load balancer is setup with 2 inbound NAT rules for port forwarding RDP to your specific instances. You should probably change the port numbers because they are always 50000 series. With these port numbers you can simply RDP to your public IP address (shown in the overview for the load balancer and several other places) and a specific port number. Obviously for each instance, they should be setup the same since they are to balance the load.

This can obviously take time, especially with things like PHP to install, but as with all installations, test it as you go along to narrow down what might be wrong. Once you've finished, access the web apps locally to ensure they work and another cool trick is to point once instance at the other in the hosts file and attempt to access one instance from the other just to make sure firewall ports are open. This takes place on the virtual network so won't give any public access yet.

Setup a probe

In order to load balance instances, the load balancer will need a way to probe the health of your instance. Your choices are HTTP or TCP and this probe(s) is setup in the Probes menu for the load balancer.

When you are first testing it, it might be tempting to use HTTP simply to your web site but be warned that there are some cases where this won't work and you will not know anything except it doesn't work! I'm not sure that https is supported (although you can type it into the Path box) and it doesn't appear to be happy with host headers.

Unfortunately, there is no obvious to test the probes in real-time, you can only enable diagnostics and hope for some useful information but it is very user unfriendly.

You can always start by trying an HTTP probe, if it doesn't work try the following trick.

Download psping from sys internals onto each instance and run it as administrator from the command line with the arguments psping -4 -f -s 127.0.0.1:5000 and it will run a TCP server that simply pings a response to a request on that port. You can then setup a TCP probe to point at the port you specified which worked in my case showing me that the HTTP part was the problem.

If you must use HTTP which is the most useful in most cases, you might need to create a default web site with no host header and put your probe endpoint in there. That worked for me (I used iisstart.htm, which was already in wwwroot). Note that ideally the probe would do more than just see a web page load but would also carry out other basic tests to make sure the instance is healthy - not too heavy though it will be called every few seconds.

Setup a Load Balancing Rule

The Load Balancing Rule is for endpoints that are load balanced across the instances (e.g. HTTP and HTTPS). To create the rule, you must have a probe but otherwise it is straight-forward. A name, a front and back port (these are likely to be known ports for public sites like 80 and 443). By default, there will only be 1 pool and the probe you just created to choose from and unless you need sticky sessions (best to design your system NOT to need them) disable session persistence which will round-robin requests to each server.

Other Things to Check

As with all of these things, don't forget things like public DNS settings to point to the correct location, SSL certificates and consideration of how you will update/fix/maintain your instances. It is possible for these instances to die so ideally you should have an automated deployment although for now, I am not going to bother spending time on that!

Friday, 9 September 2016

Hybrid Electric Cars

There is lots of excitement about both electric cars and hybrids. The hybrid has a petrol engine and an electric motor, which is basically to extend the range of the car since only a few electric cars have a useful range, unless used as a second car for local journeys only.

Within the world of hybrid, there are two main types. The cheaper standard hybrid like mine and the more expensive plug-in type which is only available on certain models. The basic difference is that to make use of cheaper and cleaner plugin energy, the car needs more batteries to store the energy which makes the car more expensive. I'm sure there are also design issues with fitting these extra batteries in. The non-plugin models like mine simply reclaim energy from braking or active deceleration (the same effect as taking your foot off of the petrol engine accelerator pedal), which is a much smaller amount and therefore needs only a handful of batteries.

So what it is like? Is it amazing? Is the fuel economy fantastic?

The simple answer is no. It's OK but it's not great and here's why.

What's bad?

Firstly, the MPG figures (or KPL) are vastly overstated as they are for many cars. Quite simply, and to the shame of the industry, the MPG factory tests are completely useless for any real-world usage and in the case of the hybrid, obviously the tests are not done over a long enough period to remove the effect of the stored energy in the battery, which is equivalent to extra petrol that is not being counted by the test. The book figures? 75MPG urban and extra-urban. The real figures? No more than 55MPG, and this drops in the winter to about 45 and I think this is partly due to some configuration that would be nice to fix!

The active deceleration - where the electric motor slows the car - seems way too weak compared to a petrol car. I don't know why they can't increase this. The problem is that it requires more braking when slowing down, which leads to the danger of bringing in the brake pads when the motor could be capturing the spare energy instead.

You will find it harder to get it maintained or fixed. Even my local Quik Fit wouldn't look at the exhaust because, "the only stuff we can do on Hybrids is tyres and wipers". This basically means main dealer for everything, which is potentially expensive (I do have a warranty which might or might not cover some of it) but also, their wait time is currently 3 weeks for a booking.

Another setting which seems strange is the setting which keeps the battery topped up really high (about 80/90% on the indicator), which means that sometimes, when you are for instance coasting down a long hill, the battery quickly charges right up to the maximum and then what happens? Any more energy that could be captured by the car is lost. This happens reasonably easily, especially in the hilly areas near where I live. It would make more sense to either keep the battery more empty or to do something cleverer, which perhaps switches modes on a longer journey to assume that long hills are more likely than needing the battery as full as possible for the next day. It could even have a button to stop charging it before a hill.

What's good?

Well a petrol car with 55MPG is not bad, although other cars can match this and some diesels can beat it soundly (but who wants a diesel?). This is to be expected since most of the time, the car is running on its petrol engine - the batteries could only power the car for about a mile. There is no reason why the petrol engine would be amazing so its a normal engine with the benefit of some reclaimed energy.

In the UK, the tax is free for electrics and hybrids, so that saves about £160 per year.

My insurance is cheap but I don't believe that this is because of the hybrid car. Most quotes were in the same ballpark as my last car, which was a Toyota Avensis petrol.

It drives smoothly, being an automatic, and the power mode is very pokey when needing some quick energy, although it can take a few seconds to kick in so don't rely on it for emergencies!

You can also switch to EV mode to run pure electric for short distances - useful if you know you are not travelling far, and if the battery gets too low or you put your foot down, the engine will cut in and it will switch back to eco mode automatically.

It's a generally nice car - in as much as it has a nice trim level, auto wipers and lights, nice seats etc. but none of that is because it is a hybrid.

Friday, 2 September 2016

So I've been on another Microsoft journey today. Journies that should be SOOOOO much quicker than they are due to ill thought-out documentation and unlayered documentation which means reading pages of stuff looking for things that might not be there because it's unclear what is going on.

I'm talking about multi-factor authentication (MFA), something that is a no-brainer for any admin accounts for cloud accounts.

Do this in AWS and its REALLY easy to find, setup and it works with Google Authenticator. On Azure? Nowhere near as useful.

Why? Because Microsoft do 3 sorts of MFA that are different but really similar: Office 365, Azure Administrators and a general systems for Azure AD users.

The first two are free - included in your subscription and the 3rd isn't. I wanted the second one only, to secure access to the portal.

Eventually after seeing a number of MS people confusingly pointing to links for the 3rd option which is much more involved I found a useful clue that if you use a Windows Live ID to access Azure (like I do) then you CAN'T set up the MFA that is part of Azure - wherever that is supposed to be done - and for reasons that are not really very clear. You have to set it up instead under accounts.live.com

So off to there, download the Microsoft Authenticator app and enter my password on that (which actually enables 2-step implicitly, which I found slightly confusing). If you then go to "enable 2-step verification" on the web site, it doesn't seem to do anything, just takes you through some screens asking if you do certain things (which I don't).

Anyway, the main moan is about the screen that comes up when you try and login with your account:

You see the line that very helpfully says, "I sign in frequently on this device. Don't ask me to approve requests here". It is ALWAYS ticked by default. If you untick it, next time you login, it will be ticked.

Of course, the first time it happened, I wasn't reading this screen, I was clicking the approve button on the device, only to look up and see this checkbox just as the screen automatically navigated to the page I was going to. Too late to untick it.

Of course, I could not find any way to "un-remember" this selection anywhere, the only option seemed to be disabling 2-step and then enabling it again but the next time, I unticked the box, since I always want to use it with this email address but next time you login, it shows it ticked again.

Microsoft, and other companies, why do you KEEP getting these basics so wrong? Don't tick the box by default. If I want to tick it, I can and I'll not see the message again. If I forget to tick it, the next time it comes up, I can easily tick it and we're all good - this is just wrong - as if no-one thinks about these things in an objective way.

Which means that the award for the most recent example I have found of "unsafe by default" is Microsoft.

Sure, the attack vector is that someone would have to login from my device but for those of us in the corporate world, it is highly likely that an attacker would use my own device against my account and therefore this one poor decision has completely undermined 2-step security.

Followers

About Me

I work for PixelPin being in charge of all development for our company, which includes mostly .Net web applications but also PHP, Android and iOS programming as well as managing our hardware and cloud-based systems.

I live in Cheltenham, Gloucestershire in the UK which is lovely in the summer and miserable in the winter.