AbstractPath | AbstractPath http://www.abstractpath.com thoughts from @tumtumtum Tue, 21 Jul 2015 20:52:57 +0000 en-US hourly 1 http://wordpress.org/?v=4.2.3 Apple watchOS beta 4 is looking goodhttp://www.abstractpath.com/2015/apple-watchos-beta-4-is-looking-good/ http://www.abstractpath.com/2015/apple-watchos-beta-4-is-looking-good/#comments Tue, 21 Jul 2015 20:48:49 +0000 http://www.abstractpath.com/?p=1119 Apple watchOS beta 4 is a huge improvement over beta 3!

Here’s things I’ve noticed already:

  1. Apple Pay is now enabled.
  2. The screen brightness at maximum has improved.
  3. Animations are very smooth again. Beta 3 was extremely slow.
  4. UI bug with customising a watch face while time travel is enabled fixed.
  5. Apps appear to load faster.
  6. Siri isn’t as slow as Beta 3 but isn’t as fast as watchOS1 or iOS9 (Siri on iOS9 dictates word-by-word in almost realtime like Google Now).
  7. Wrist detection for turning the screen on now works when you’re lying down!


IMG_7951  IMG_7949

http://www.abstractpath.com/2015/apple-watchos-beta-4-is-looking-good/feed/ 0
Automatically deploying TeamCity Azure Build Agents into specific virtual networks (vnets)http://www.abstractpath.com/2015/automatically-deploying-teamcity-azure-build-agents-into-specific-virtual-networks-vnets/ http://www.abstractpath.com/2015/automatically-deploying-teamcity-azure-build-agents-into-specific-virtual-networks-vnets/#comments Sat, 16 May 2015 01:09:58 +0000 http://www.abstractpath.com/?p=1108 Jetbrains has recently added support for using Azure as cloud build agents. It supports start and stopping existing virtual machine instances or start and stopping new virtual machine instances created from an image. Unfortunately the plugin currently doesn’t support creating new virtual machine instances within a specific virtual network (vnet) which can complicate setups where you want to keep all your development machines within a single vnet with all the associated benefits such as easy DNS lookups.

I’ve created an updated version of Jetbrains’ plugin to allow you to specify a virtual network. You can download the plugin directly here or browse the source code on GitHub.



http://www.abstractpath.com/2015/automatically-deploying-teamcity-azure-build-agents-into-specific-virtual-networks-vnets/feed/ 0
Strange Visual Studio 2013 debugger bughttp://www.abstractpath.com/2014/strange-visual-studio-2013-debugger-bug/ http://www.abstractpath.com/2014/strange-visual-studio-2013-debugger-bug/#comments Mon, 20 Oct 2014 21:41:54 +0000 http://www.abstractpath.com/?p=1098 var bar =... line. The code should throw an InvalidOperationException but instead gets to Console.WriteLine().It works fine if you don’t set a breakpoint or just run without the debugger attached.
using System;
namespace ConsoleApplication1
    public class Foo<T>
        public virtual T GetBar<K>(K foo)
            throw new InvalidOperationException();
    class Program
        static void Main(string[] args)
            var foo = new Foo<string>();
            // Place a break point on this line and then step over.
            // An exception should throw but it doesn't.
            // If you try to step into instead it will not go into GetBar()
            // The instruction pointer is buggered.
            var bar = foo.GetBar(new Guid());
            Console.WriteLine("Should not get here");
http://www.abstractpath.com/2014/strange-visual-studio-2013-debugger-bug/feed/ 0
Opening the back cover of a Tesco Nokia 100http://www.abstractpath.com/2014/opening-the-back-cover-of-a-tesco-nokia-100/ http://www.abstractpath.com/2014/opening-the-back-cover-of-a-tesco-nokia-100/#comments Sat, 19 Jul 2014 09:46:10 +0000 http://www.abstractpath.com/?p=1093 I just bought a Tesco Nokia 100 phone (only £9!!) to use for my apartment’s annoying GSM based intercom. It’s got 35 day stand by battery so that makes it a good for the job. Following the instructions for opening the back cover will make you extremely frustrated. Here’s a short video showing the easiest way to open the phone.

Click here to view the embedded video.

http://www.abstractpath.com/2014/opening-the-back-cover-of-a-tesco-nokia-100/feed/ 0
Gaining additional memory when running Linux on Azure Extra Small Instanceshttp://www.abstractpath.com/2014/gaining-additional-memory-when-running-linux-on-azure-extra-small-instances/ http://www.abstractpath.com/2014/gaining-additional-memory-when-running-linux-on-azure-extra-small-instances/#comments Sun, 29 Jun 2014 13:14:15 +0000 http://www.abstractpath.com/?p=1048 If you use Azure to host your Linux VMs (I prefer Azure extra-small instances over EC2 tiny instances because they allow you to put swap on ephemeral storage) you may notice that you only have 541MB of free memory rather than the 768MB promised by Microsoft. This is because the Linux crash kernel by default takes up ~128MB on an extra-small instance. You can change this by removing the crashkernel=auto reference inside your /etc/grub/grub.conf.


[root@localhost ~]$ free -m
             total     used     free     shared    buffers     cached
Mem:         541        306     235         0         12        175
-/+ buffers/cache:      118     422
Swap:         2047        0     2047


[root@localhost ~]$ free -m
             total     used     free     shared    buffers     cached
Mem:         670        299     370         0         12        165
-/+ buffers/cache:      121     548
Swap:         2047        0     2047

http://www.abstractpath.com/2014/gaining-additional-memory-when-running-linux-on-azure-extra-small-instances/feed/ 0
Bloom.fm technology stackhttp://www.abstractpath.com/2014/bloom-fm-technology-stack/ http://www.abstractpath.com/2014/bloom-fm-technology-stack/#comments Fri, 23 May 2014 22:14:32 +0000 http://www.abstractpath.com/?p=977 Bloom logoWith the unfortunate demise of Bloom.fm, a product I designed and developed as CTO for 2.5 years at a company I co-founded 5.5 years ago; I think it’s a good time to write a series on my learnings, decisions and experiences.

My development team (minus visual designers) varied from 6-13 developers over the years. With this size team we wrote a music streaming service backend, a music content ingestion system, 3 native mobile apps, a web app, an internal admin console and designed and built in-house infrastructure for hosting everything. We did not use cloud hosting because of the need to store over 700TB of content securely and without the massive on-going costs that cloud storage would incur. Here’s a quick list of the tech we used at Bloom…

Development tools

I spared no expense with our development tools. Each developer had a fast workstation with dual 27″ monitors. We had about 18 development servers which included simulated production environments (dev & test) and 9 Windows and OSX build servers for continuous integration and testing.

  • TeamCity for continuous integration
    • All builds and tests were run automatically and logged
    • Custom deployment tasks and services were written to allow one push deploy to dev, test and production
  • Confluence for documentation
  • Mercurial for source control
    • Branching was used extensively.
    • Commented out code was not allowed to be checked into the repository.
  • Visual Studio 2012 for backend and web development
  • Xcode for iOS development
  • IntelliJ IDEA for Android development
  • YouTrack for bug and feature tracking, project management
Backend web services

Everything ran on CentOS 6.5 except for the C# web services which ran on Windows 2008 R2. Each web service server (“AppServer”) was stateless with new servers able to be added at any time to increase capacity. Shared transient state (e.g. user session data, unique streaming request tokens, search queries) was stored using Redis. Web Services were accessed by  the mobile and web apps using JSON over HTTP. Every new web service written in C# triggered generation of the appropriate client-side JavaScript, C++, C#, Objective-C and Java code. At our peak we were handling over 10,000 concurrent API requests per second.

Every element of the backend was implemented with care and attention to detail to architecture and performance. For example, our caching strategy was to cache structured data (rather than blind output caching) which allowed caching of combined static (e.g. search results) and dynamic (e.g. user purchase state) data. We used a Redis pub/sub to support distributed cache invalidation which allowed us to use AppServer memory for local caching of shared data that would otherwise need to always be accessed via Redis.

Because we started a long time before tech like SignalR was released, we developed our own scalable real-time notification service based upon http.sys and Memcached (later Redis) back in 2008. This notification service allowed us to deliver hundreds of thousands of notifications without scalability issues. Users could edit a playlist on one device and see it change immediately on their other device.

(team size: 7 people including myself)

  • C# 4.5, WCF and IIS7.5 for web services
  • Postgres 9.4
  • Sqlite for simulated fast unit testing
  • Redis for structured caching (search results, user, artist, album data, personalised radios etc) and distributed state (session state, streaming tokens, etc)
  • Solr for search (we originally used NLucene)
  • RabbitMQ for queueing and request offloading
  • NUnit for unit testing
  • Booksleeve redis client
  • Shaolinq Linq provider for Postgres and Sqlite
  • Platform.VirtualFileSystem for file system access
  • StructureMap for dependency injection

There were 3 VLANS on the network. Management, Internet and Backend. The backend VLANs all ran on 10Gb ethernet. All of Bloom’s infrastructure was managed in-house at co-location facilities in central London and docklands. Bloom ran on 60 servers (approximately 40 physical servers and 20 virtual servers). All physical servers were Dell PowerEdge servers (R620s, R720s). Storage servers consisted of 14 clustered 4U SuperMicro storage servers running our own setup of CentOS and Gluster.

The total cost of infrastructure was a little over £200K (capex). I worked my ass off to make the most efficient custom built solution — and it was awesome fast.  This one off cost was less than the ongoing monthly spend our CEO allocated to banner ads with an insane CPC of over £200 per user. Cloud hosting is great for many startup business models where costs scale directly with user count (like Dropbox) but if we had hosted Bloom.fm on Amazon it would have cost well over £200K every month (not just a one off capex!).

(team size: 2 people including myself)

  • Linux LVS for load balancing
  • Zabbix for monitoring
  • Puppet for automation and server management
    • EVERYTHING was scripted. New servers were automatically setup in a just a few steps
  • Graphite for API logging and monitoring
  • NGINX for serving images and media content
    • PHP & PHP-FPM to manage streaming authentication via Redis (time limited tokens etc)
    • Validated requests were redirected back to NGINX using X-ACCEL-REDIRECT
  • GlusterFS for storage (two 800TB volumes storing over 400 million files each)
    • Each brick was used as an independent server and made failsafe using LVS allowing mounts to work right down to the failure of the last brick in the cluster
    • Each brick was formatted using xfs with 512 byte inodes
    • Insane performance which increased every time new storage was added
    • One-off cost was £140K. Would have cost over £70K a month if we had stored in the cloud (not even including data transfer costs!)
  • XenServer as the hypervisor for our VMs
  • FusionIO PCI flash storage for primary databases (excellent value)
  • Force10 10Gb switches (excellent performance and value)
  • Cisco ASR 1000 routers
  • Pingdom for SMS monitoring
Mobile apps

All mobile apps were written natively for performance and size.

(team size: 4 people including myself)

  • Objective-C for iOS
  • Java for Android
    • The UI used OpenGL for animation performance (rare for any app outside of games)
  • C# for Windows Phone
Web Apps

We had two web apps. The Bloom.fm music player web app and the internal admin system for managing and monitoring the system as well as user management.

(team size: 2 people)

  • C# 4.5
  • MVC
  • Razor
  • JQuery
Third Party Integration

Bloom integrated with many third party services including:


We built an extremely comprehensive music streaming service with a comprehensive feature set that easily handled 100,000 concurrent users with almost no load and could have handled ten times that without any additional servers or optimisations. This was all done (including computers, servers, salaries) on a technical and (graphical) design budget of £3M over 2 and 1/2 years. Many companies can easily spend upwards of £1M on storage alone (don’t use an off the shelf SAN for a music streaming service!). The key was to keep all design and development in-house (contractors are ok as long as they work in-house), hire only the best of the best and to be confident and capable enough to develop custom solutions when necessary. A tech startup creates tech right?

http://www.abstractpath.com/2014/bloom-fm-technology-stack/feed/ 1
Updating OpenSSL to Install Postgres 9.x on CentOS 6.xhttp://www.abstractpath.com/2014/updating-openssl-to-install-postgres-9-x-on-centos-6-x/ http://www.abstractpath.com/2014/updating-openssl-to-install-postgres-9-x-on-centos-6-x/#comments Sun, 12 Jan 2014 01:10:43 +0000 http://www.abstractpath.com/?p=937 The instructions provided here for installing Postgres on CentOS via yum don’t work for Postgres 9.x (Postgres 9.3 being the latest) if you’re stuck running CentOS 6.4 or lower. CentOS 6.4 and lower do not ship with OpenSSL 1.0.1 which is required by Postgres 9.x — they ship with OpenSSL 1.0.0 or lower.

You will most likely get the following errors:

 Error: Package: postgresql93-Server-9.3.2-1PGDG.rhel6.x86_64 (pgdg93) Requires: libssl.so.10 (libssl.so.10) (64bit)</p>
<p>Error: Package: postgresql93 -libs-9.3.2-1PGDG.rhel6.x86_64 (pgdg93) Requires: libssl.so.10 (libssl.so.10) (64bit)</p>
<p>Error: Package: postgresql93-9.3.2-1PGDG.rhel6.x86_64 (pgdg93) requires: libssl.so.10 (libssl.so.10) (64bit)</p>
<p>Error: Package: postgresql93-libs-9.3.2-1PGDG.rhel6.x86_64 (pgdg93) Requires: libcrypto.so.10 (libcrypto.so.10 ) (64bit)</p>
<p>Error: Package: postgresql93-Server-9.3.2-1PGDG.rhel6.x86_64 (pgdg93) Requires: libcrypto.so.10 (libcrypto.so.10) (64bit)

Follow the instructions here to build and install an RPM package for OpenSSL 1.0.1. Once that’s done, follow the instructions for installing Postgres again and it should work.


An even simpler approach

Install the ius repo:

 rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/6/x86_64/ius-release-1.0-11.ius.el6.noarch.rpm

Enable the ius-archive repo:

Edit /etc/yum.repos.d/ius-archive.repo and enable the ius-archive repo by changing enabled=0 to enabled=1.

Install the yum replace plugin:

yum install yum-plugin-replace

Replace the existing openssl package with openssl10:

yum replace openssl --replace-with openssl10

http://www.abstractpath.com/2014/updating-openssl-to-install-postgres-9-x-on-centos-6-x/feed/ 0
C# LINQ and Sum, Min, Max, Average behaviourhttp://www.abstractpath.com/2014/c-linq-and-sum-min-max-average-behaviour/ http://www.abstractpath.com/2014/c-linq-and-sum-min-max-average-behaviour/#comments Fri, 03 Jan 2014 22:38:01 +0000 http://www.abstractpath.com/?p=888 I’ve recently been improving support for aggregates in Shaolinq in order to make Shaolinq queries match LINQ to objects as closely as possible. The LINQ Enumerable<T>.Sum, Enumerable<T>.Min, Enumerable<T>.Max and Enumerable<T>.Average extension methods map to the SQL aggregate functions SUM, MIN, MAX and AVG respectively. In SQL, all these functions will return a null if there are no rows returned. In .NET, the behaviour when the enumerable is empty depends on whether the type T is nullable or not.

The .NET aggregate methods Min, Max and Average will throw an exception if the enumerable is empty and type T is not nullable (int vs int? etc). If type T is nullable then Min, Max, Average will return null. The exception to all this is Sum which will always return 0 regardless of the nullability of type T.

When performing a SQL aggregate query such as SELECT SUM(age) FROM PERSON, SQL will return a single row even if there are no PERSON rows and the SUM column value set to null.  This null value is used to detect empty result sets which can be mapped to the appropriate exception or null result depending on the nullability of the .NET required type. To match the behaviour of always returning 0 for Enumerable<T>.Sum regardless of whether the resultset is empty or not, Shaolinq wraps SUM aggregate calls in a SQL COALESCE. This is handled by the SumAggregatesDefaultValueCoalescer class along with SqlQueryProvider and ObjectProjector.


http://www.abstractpath.com/2014/c-linq-and-sum-min-max-average-behaviour/feed/ 0
Art Tech AT-6 Texan Replacement Retractshttp://www.abstractpath.com/2013/art-tech-at-6-texan-replacement-retracts/ http://www.abstractpath.com/2013/art-tech-at-6-texan-replacement-retracts/#comments Fri, 27 Sep 2013 14:52:43 +0000 http://www.abstractpath.com/?p=879 I have a Art Tech AT-6 Texan RC plane. The one big problem I’ve had with this plane is that the electronic retracts that come with it are prone to overloading, hanging and overheating. If you switch the retracts on/off too fast it causes a current surge which overloads the control transistor causing the retract to hang until it’s unplugged. Sometimes the “brake” switch at either end of the retract’s extents stop working causing the retract motor to continuously push, damaging the “brake” switch even further and causing the whole unit to massively overheat.

A set of replacement retracts for the AT-6 cost £35 but you can get the exact same retract system (sans the wheel and strut which you can move over from the broken set) for £5 each from HobbyKing. They have UK stock as well….

Art Tech AT-6 Texan RC Plane Replacement Retract Replacement retracts with original wheel and strut attached


http://www.abstractpath.com/2013/art-tech-at-6-texan-replacement-retracts/feed/ 0
iPhone exchange setup connection to server failed errorhttp://www.abstractpath.com/2013/iphone-exchange-setup-connection-to-server-failed-error/ http://www.abstractpath.com/2013/iphone-exchange-setup-connection-to-server-failed-error/#comments Wed, 26 Jun 2013 12:03:00 +0000 http://www.abstractpath.com/?p=865 I got a replacement iPhone 5 today and tried to setup my exchange account. It failed and all I got was a cryptic ‘connection to server failed’ error alert box. This error could mean a lot of things and I had no luck finding anything of substance in the Exchange 2010 or IIS logs.  

After a few hours of frustration an searching, I discovered that my problem was caused by having too many mobile devices attached to my exchange account (apparently I’ve owned 10 unique iPhone/iPads over the last 5 years). You can check this by using the exchange web mail interface. Log into web mail -> Options -> All Options then you’ll see a tab on the left named “Phone”. From there you will see a list of devices that have ever synced with your exchange account. Remove the old ones. You may have to delete and then recreate the exchange account on your iPhone for things to start working again.

Exchange Mobile Devices

http://www.abstractpath.com/2013/iphone-exchange-setup-connection-to-server-failed-error/feed/ 0