The thing about micro-services

You might decrease the complexity of a monolithic application (I’m not actually sure that’s even a valid statement, that a “monolith application” is “complex”) but conversely you increase the complexity by adding in all the network hops, latency, asynchronicity, and having to debug strange timeout errors.

It doesn’t matter what architecture you user, you’re still going to encounter an equal number of problems to think about, debug and solve.

Being able to identify a problem doesn’t mean I have an answer

I’m a big proponent of asking questions. But one questions I hate is:

What’s the solution?

It’s a loaded question, intended to deflect.

The scenario where we most hear this is when someone says “X is a problem” to a creator, leader or manager of X.
Then the leader immediately replies: “Great. What’s the solution? How do we fix it?”

Similarly, some leaders will say: “Don’t just raise problems. Suggest solutions.”

This is a pure bullshit tactic by leaders to deflect the problem back on the person reporting it.

I look at it like this:

Just because a person can see a problem, doesn’t mean they have the vision to understand the cause or how to solve it.

Likewise, they probably do not have the vision to create the thing that caused the problem in the first place.

Humans are good at spotting problems. We’re not that great at finding solutions.

Yes, there are times when the person identifying the problem can offer a solution. These are times where their expertise is what allows them to see the problem in the first place.

But working in business, many times I’ve heard someone raise a concern that is immediately quashed by the “how do we solve it” question, the underlying subtext being “if don’t have an answer, don’t ask the question”.

And with a quiet flurry, we launched today!

I’ve just worked 15 days straight, with 12 hours being my minimum work day.
Some days were closer to 14-16 hours.
That’s a minimum 180 working hours in 2 weeks.
(And since I came back from a holiday on the 4th January, I’ve had a total of 3 days without working.)

Those are not figures to be proud of. Working massive hours as a software developer is not a badge of honour. It’s a bad of stupidity (usually).

But in this case it’s been worth it. The time has been spent on a last minute push as a new university year starts and we complete features for the rollout of a new Intranet for one of the local colleges.

It’s a project 2 years and 1 week in the making since first discussion.
And about 18 months in development.

The first 3 months were binned after the requested technology was deemed non-viable.
They specified SharePoint. It would never achieve what they wanted in the long run.

So I said – almost as a joke – “what about WordPress?”
The IT Managers said “evaluate it and let me know”. So I did. And we decided it was a better choice.
That was late November 2017.

I probably could have finished this project 9 months ago with the base WordPress and a collection of existing plug-ins.
And we would have spent the next 12 months fighting fires, hacking together fixes and losing a lot of sleep over security.

Instead, what started as a project evolved into a product and platform – one we plan on taking well into the future.

Over the course of 2018 – while also working full-time until September – I developed the web application platform designed with security, usability, customisation and extensibility in mind. And, of course, ongoing maintenance and support.
During that time I leant WordPress and PHP development. I also went through nearly 2 full evolution builds of the core architecture – effectively jamming 2-3 years of product life into about 3 months prior to initial release.

I don’t believe in traditional MVP (Minimum Viable Product), especially when security is involved.
Most small-team MVP projects are a “hack”.

Through most of the last 12 months of the project I have been at the helm of design, architecture and development. My business partner has been project manager and [a very excellent] chief tester. And our 2 developers progressively took on a growing share of the programming work as other work finished.

The weekend gone was one of last minute development, testing and bug fixes. Nothing that phased us – just the sort of things at usually come up or get left to the time of “launch”.
And in future projects we will even reduce that happening.

Yesterday (Sunday) afternoon I reset and our production environment (which was setup a couple of months ago). It was ready before dinner. We were at that point effectively live.

This morning I sent a message to the project sponsor telling him they can start the 2 week process of creating content.

And that was it.
No stress. No anxiety. No last minute deployments. Just a simple message and we were running.


The story doesn’t end here though. In different ways ways it’s just the start and the middle.

Today, already, there were a couple of inevitable bugs that come from a first-time “real life” use of new software.

We also still have a number of tasks to complete and progressively roll in over the coming 2 weeks.

Then the final phase of the project needs to be run to complete development for another set of workflows and some different types of user.

But, the system is running. And we are proud creators.


The product itself – outside of this particular project – already has a massive backlog of work planned for this year alone.

PWA (Progressive Web Application) optimisation, push notification services, a more responsive SPA-like (Single Page Application) interface, and an accompanying full API. Not to mention plenty of design and UX enhancements.

In a few weeks, as the semester starts and this phase of the project completes, I’ll start setting up fully-functional demo sites people can play with. We don’t have a proper DevOps pipeline yet, but I can still setup a new demo site in under 15 minutes, and most of that is waiting for files to transfer.

And then comes the process of marketing, sales and finding new customers with business needs we can solve.


Regardless of all that, here’s something I can happily take to bed tonight:

We designed, developed and delivered a working product that solves some very real business problems.

WordPress: Changing File Upload and Processing Sizes

[This is a post for self-reference]

Up front I’m going to say I got exactly the help I need from here:
The author of that post deserves all my credit.

I’m creating this post to summarise it in my own words and to give it a little educational context.

When allowing file uploads on a website there are 3 big things you need to think about:

  • The size of each file.
  • The total size of all files in an upload.
  • The time it takes to process the upload.

Actually, there are a couple of things to consider that are worthy of mention but I won’t cover in this post:

  • Asynchronous uploads (AJAX as we used to call them) can change the figure of an upload, because instead of uploading multiple files at one, you upload one file at a time (even if they are in parallel) so the “total size of all files” number will be different.
  • Tell users about the limits they face before they upload. Also, when uploading images a bit of guidance around things like “27MB images are a stupid side for most sites because 27MB isn’t going to be better than 7MB, and the site will trim the size down to a couple of hundred KB at most anyway.”
  • Trap, log and respond to any errors. This is on my mind because WordPress/PHP seems to like gobbling errors and not telling anyone about it (I’m in the process of hunting down how to handle this and will be a topic of another post).


There are 3 main ways in PHP to affect file upload sizes and times:

  • @set_init() in a PHP script itself.
  • php.ini file
  • .hataccess file.

Be aware, as a PHP/Linux novice I reckon there are other defaults and hierarchies that come into play.
This article is spawned by a situation where I was changing php.ini without realising .htaccess had a value overriding it.


How do you implement these values?

This is where I rip from the wpbeginner site I mentioned above for quick reference:

1. PHP script file (e.g. functions.php in WordPress themes)

@ini_set( 'upload_max_size' , '64M' );
@ini_set( 'post_max_size', '64M');
@ini_set( 'max_execution_time', '300' );

(I haven’t tried this approach yet, but I have used @ini_set() in other instances (e.g. ‘memory_limit’) and it’s worked well.

2. php.ini

upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300

I’ve used this approach in development and it did the trick.

3 .htaccess

php_value upload_max_filesize 64M
php_value post_max_size 64M
php_value max_execution_time 300

Before writing this post I had to fix a production issue and after trying php.ini I got lucky and discovered .htaccess was where the value was coming from.
So the moral: .htaccess overrides php.ini.

Also, I did not need to restart apache for this change to take affect.


DISCLAIMER: I haven’t actually read in-depth how all this works. I’m a typical developer who expects other people’s shit to work, and when it doesn’t I’m usually in the middle of my own concerns so it’s a case of “search and scan by keyword until someone else’s solution works for me”.
Such is this age of software development.


Need to know what your current settings are?

It’s helpful in debugging and verification to know what your actual PHP settings are so you know what your starting point is (and  you have a number to search your files for).

A good way is to call phpinfo();.

For example, create a file in your site (I call mine info.php) and add the following PHP code:


You should see something like the following when you run it. This screenshot shows some output from the section titled “Core”, and the 3 columns are (from left to right): “Directive”, “Local Value” and “Master Value”. I can say from experience the “Local Value” is the one that matters.

phpinfo() output

Change a WordPress site URL (when copying or migrating a WordPress site)

This is a post for quick reference. But given 25% (or more) of the Interwebs run on WordPress I want to give it some love too.


Moving (migrating) or copying a WordPress site has some hidden complexity.

While it is easy, there are 3 things you need to do:

  1. Copy the whole website structure, starting with the folder than contains the wp-config.php and other files (it also contains the  “wp-admin”, “wp-content” and “wp-includes” folders).
  2. Change the URL of the site as defined in WordPress (ordinarily set during setup, or within the Settings area).
  3. Update all the saved URLs within the database.

Step 3 is the real gotacha. When you add a link to another page within your site, or insert media, or set a navigation item, it saves the full URL of that item in the database.

For example, if you have a site “” but want to change it to “” (or as a software developer, you may want to create a copy of the production site at “”) then after you change the actual URL of the site, all the internal links and images will still be pointing to the original



Many sites have covered how to change a WordPress site URL before, including the official Codex at

I like to keep things simple, so this post is my process:

  1. Backup your site database if you can (I connect directly to the database and run backup scripts, or use phpmyadmin and export).
  2. Update your site URLs by adding the following lines to the top of your active theme’s functions.php file:
    update_option( 'siteurl', '' );
    update_option( 'home', '' );
    1. Browser to your new site (via the IP or URL).
    2. Browse to it again and make sure it’s OK.
    3. Remove the lines from functions.php
    4. Browser to the site again one more time to make sure you can access it now you’ve removed the lines from functions.php.
  3. Upload the interconnect/it “Database Search and Replace Script” script to our site, found at
    1. Install it in a “not easily guessed” sub-directory of the site. This is for security reasons (so other people can’t scan and execute the scripts).
    2. Most fields are filled in. In the “search for…” enter your old URL or IP address, including “http” or “https” (e.g. “” – you should be using https by now). I don’t end with a trailing forward slash.
      In the “replace with…” field enter the new URL or IP Address (e.g. “”). Again, not trailing forward slash.
    3. Make sure you do “dry run” to start. This should tell you if you have any problems.
    4. If all is good, do a “live run” and update your database.
    5. At the end, delete the “Database Search and Replace Script” from your site. This is important. If you leave it there bad people may find it and execute it and break your site.

Microsoft All-in-One Media Keyboard: How to Print Screen

I have a backup “Microsoft All-in-One Media Keyboard” I need to use when my primary Ergonomic Wireless Desktop keyboard decides to die (possibly “concussion” induced at 11pm when technology decides to become my Nemesis).

The only problem is it does not come with a Print Screen button.

But thanks to some wonderful soul on the Interwebs we have an answer:

Print full screen: Fn + Windows Key + Space
Print current window: Fn + Alt + Space

Source: Microsoft Answers

Install XML RPC for PHP 7.2 on Ubuntu Linux


One of the components in a web application solution we’re developing uses xmlrpc_encode_request() in PHP.

It was executing fine in most of our systems systems – development and multiple test servers – but while trying to run it for the first time in my development environment I received the following error:

Fatal error: Uncaught Error: Call to undefined function xmlrpc_encode_request()

So off to Google I go and, find a few answers, have a couple of mis-starts, then finally get it working.



The solution was very simple.

  1. Install the xmlrpc extension.
    sudo apt-get install php-xmlrpc
  2. Restart Apache web server
    sudo service apache2 restart

As a sanity check, create a PHP file (e.g. info.php) and add the following:

echo 'XMLRPC is ', extension_loaded('xmlrpc') ? 'loaded' : 'not loaded';

When you run the file it you should see “XMLRPC is loaded” if all is good.

If you’re still having trouble, try updating your php.ini file to include:;


Unfortunately, if you still have trouble then I apologise and suggest hitting Google/Bing/DuckDuckGo/StackOverflow again and playing around with search terms that meet your specific Linux/OS/PHP versions.


More Background

I started with a search for “Fatal error: Uncaught Error: Call to undefined function xmlrpc_encode_request” then “lamp Fatal error: Uncaught Error: Call to undefined function xmlrpc_encode_request”, and had these results:

But they were aimed at PHP 5.x (by the way, if you’re still on PHP 5.x then update! It’s no longer supported and you’re now a security risk).

Then I refined my search to “apt-get php 7.2 xmlrpc” and had:

And I found the helpful suggestion for the info PHP file (you could also just run phpinfo(); in a file) at:

Upgade Cloud9 Workspace to PHP 7.2

Update: 05 May 2019

I’ve discovered a page at as an alternate source for updating PHP to version 7.2. Look for the section “Updating PHP 5.4 to PHP 7”. I haven’t tried the process, but it looks pretty good.


Updated: 14 April 2019

According to this announcement, the old Cloud9 service ( is soon to be no more, with all functionality ending 30 June 2019, and complete shutdown 30 November 2019.
What is the future of C9? It will be 100% within Amazon Web Services as AWS Cloud9.
I – like many others – am not a fan of AWS. In fact, I think AWS is one of the worst development services I’ve used, and Cloud9 proves it. They took an incredibly powerful and easy to use service and… well, totally fucked it to be honest. To the point I spent an hour of my Sunday afternoon swearing while trying to setup a new AWS Cloud9 WordPress environment.

As such, I am unsure at this time if I will continue to work with AWS Cloud9 or find an alternate cloud IDE (I now use I use IDEs in a professional capacity and I’m happy to pay for convenience and ease-of-development experience.

Anyway, I won’t be attempting any workspace upgrades in future. I will, however, create a new post when I decide which development environment to use.


Updated: 03 March 2019
After my original environment upgrade I started to see CPU maxing on page loads. I thought it was code changes, but it wasn’t. I run WordPress in my environment and even /wp-admin was causing a 5-20x increase in page load times with 100% CPU spikes.

I happened to find a copy of my environment that was still the original PHP 5.5.9 version and have been using that since a week after this original post. CPU has been fine.

Today I cloned my working environment, did some more searching, and tested a PHP upgrade again. The section “Updated Solution (03 March 2019)” below contains the results of that upgrade. So far, so good. The upgrade process is not that different to the original.

However, /phpmyadmin shows an error “The mbstring extension is missing. Please check your PHP configuration.” I’m not surprised because I my script excluded that (see notes within the 03 March section).
I will work on this next, but I wanted to publish updated results before that happens.

Updated Solution (03 March 2019)

Today’s results are modified from [and thanks to]

Run the following commands, but note:

sudo add-apt-repository ppa:ondrej/php -y
sudo apt-get update -y

#sudo apt-get install php7.2-curl php7.2-cli php7.2-dev php7.2-gd php7.2-intl php7.2-mcrypt php7.2-json php7.2-mysql php7.2-opcache php7.2-bcmath php7.2-mbstring php7.2-soap php7.2-xml php7.2-zip -y
sudo apt-get install php7.2-curl php7.2-cli php7.2-dev php7.2-gd php7.2-intl php7.2-json php7.2-mysql php7.2-opcache php7.2-bcmath php7.2-mbstring php7.2-soap php7.2-xml php7.2-zip -y

sudo mv /etc/apache2/envvars /etc/apache2/envvars.bak
sudo apt-get remove libapache2-mod-php5 -y
sudo apt-get install libapache2-mod-php7.2 -y
sudo cp /etc/apache2/envvars.bak /etc/apache2/envvars

sudo a2dismod php5
sudo a2enmod php7.2

sudo service apache2 restart





Original Post Solution

Cloud9 is a great online IDE (or it was before the Amazon AWS team got their hands on it).

The problem is the default PHP version in my workspace was 5.6, well out of date and unsupported.

It turns out, upgrading PHP version’s isn’t a simple matter. After much search in found this solution on StackOverflow that worked for me:

sudo add-apt-repository ppa:ondrej/php -y
sudo apt-get update -y

sudo apt-get install php7.2 php-pear php7.2-curl php7.2-dev php7.2-gd php7.2-mbstring php7.2-zip php7.2-mysql php7.2-xml -y

sudo mv /etc/apache2/envvars /etc/apache2/envvars.bak
sudo apt-get remove libapache2-mod-php5 -y
sudo apt-get install libapache2-mod-php7.2 -y
sudo cp /etc/apache2/envvars.bak /etc/apache2/envvars

sudo a2dismod php5
sudo a2enmod php7.2

sudo service apache2
sudo service apache2 restart

Bad UX: Microsoft Films & TV

This is a UX failure I experienced.

My default media player in Windows 10 is Microsoft’s “Films & TV” app. So most .mp4 or .mkv files I have or produce I play through this app.

The problem is, if my focus is on the app and I press the backspace button (which can happen if I’m working and switching between multiple screens), I go from a playing video to the following:

So, where the UX fails and I become lost is: how do I get back to the file I was just playing?

There is nothing on the screen that indicates this possibility.
And exploring the few extra options (including a back arrow that only appears after moving between “Explore”, “Purchase” and “Personal”) yields nothing.
In the end I have to go back to Windows Explorer and re-execute the file.
(Now I think about it, the application doesn’t even have a typical “File” menu to find and open a file directly.

I call this a fail because I cannot simply “go back” to the file I was playing.
I would expect this from a default operating system application in 2019.

Git: branch commit is in the future

I was just checking some branch commits from one of my developers and noticed the commits where 22 hours in the future.

It turns out they’d changed their system time for testing and forgot to revert it before pushing.

It makes sense when I think about it.

Because git is a distributed system, it would use the local system time when committing.
Git doesn’t track track off a server time.
That means you can be totally disconnected from other systems and still make commits – in that case the only time it knows is the system time.

That doesn’t make it any less confusing or counter-intuitive in an age of servers, synchronisation and centralisation.