Showing posts with label systems. Show all posts
Showing posts with label systems. Show all posts

Tuesday, 9 July 2024

Code Locality & Concurrent Systems

Let us talk Software Design, let us talk about code locality.  What do I mean by locality?  Well, in Software Engineering we often talk about code being self documenting, a fabulous place to be if the code performing the work is right in front of you.  But to be honest systems get pretty big pretty quickly.  So you're very much more likely to me making calls to API's or just bunched of functions you have to blindly trust, unless you have the leisure of digging into them.

And there's usually precious little time in development which is invariably taken up with writing new code, not going over the old (unless you're very lucky - but that's a conversation for another day).

Now, these API's can encapsulate large features, and they don't always achieve the amount of descriptive power we'd like in the call site location we're at.  I therefore advocate for a comment around that point.

And so we are immediately at odds with the wish for our code to be as accessible, local, as it can be, but also encapsulating the large unrelated tasks elsewhere.  For me this is the dichotomy of code locality in a nut shell.

Where can it come unstuck?  Well, back in the day (and I have to be honest with most engineers still thinking linearly even today) you could be forgiven to writing out your big system block diagram, connecting things with events or signals and just going about your business, when your code called "BigFooFunction" in "BarBarBlackBox" library you didn't pay it much mind.  Today however, as Moore's Law runs aground on the rocks of pumping ever more cores into a system we have to think in concurrent terms and it is in just such a scenario that I want to pick up thinking about Systems Design and Code Locality.

Let us perform a thought experiment.  We have a system which progresses from Eggs to Birds, it controls the state of the entity laid as an egg, being incubated, then hatched, fed and tended until they start to fledge and ultimately turn into a bird.  All this transmogrification of the state from Egg to hatchling to fledgling to bird happens asynchronously in the background in a big slap of system you do not have to worry about.

All you worry about is a signal coming into you saying "predator", and when this signal arrives you need to stimulate all the little birds you have into action, they all need to take flight.

for(auto& bird : flock)

{

   bird.TakeFlight();

}

This is the locality of our change to the property flight on each bird, we are absolutely unaware of each individual possible state the bird can be in and so we rely on the API and code backing our call to "TakeFlight".

Now, let us assume the members of "flock" are all of the base type "Bird", so they all have a TakeFlight function?  Well, they might, if Bird looked something like this:

class Bird

{
   public:

       virtual void TakeFlight() = 0;

};

Then at compile time all the derived classes would have to implement "TakeFlight".

class Egg : public Bird

{

    private:

        uint64_t mTimeLaid;

        float mTemperature;

    public:

        void Incubate();

        void TakeFlight() override;

};

And because we know this is an Egg we know it can't fly and so we know that this override of the function will do nothing.

This is perfect code-locality for that derived type, but for bird itself it leaves us the open question, well what does it do?  Does it do anything??  Should "TakeFlight" return us some code to indicate the bird took flight and an error if not, but an egg not flying is not an error, so must it be some compound it returns.

Now, I am straying into API design somewhat, and they are related fields, but really here we're thinking about where the active code sits, what is its locality compared to our callsite in the loop?

And for a function, you can see we can define this and know.

Now lets us change our example:

class Bird

{
    public:

       bool mInFlight { false };

};

and

class Egg : public Bird

{

    // As above

    public:

        void TakeFlight () override { 

            // Intentionally Empty 

        }

};

Our egg can not fly, or can it? for now with a public member we're flying somewhat in the wind of a contrived example, but anything can now set the value of mInFlight, our for-loop upon the predator signal can now achieve its aim:

for(auto& bird : flock)

{
   bird.mInFlight = true;

}

And this is correct, this loop in review would pass, who can argue?  The bird took flight, it did, it is true.  And this is code locality in action, for at the location we needed it the functionality was available to mutate the value and achieve our goals, no matter what the state of the rest of the system was.

This is a very dangerous place to be.

Especially with an asynchronous system, lets say this is not a trivial call, lets say that the call site is to loop through a series of resources and start them loading, and upon that call each is pending load, but not yet loaded?

for(auto& item : objects)

{
    item.StartLoad();

}

We can assume this code is starting the load, but now lets package this into some context, we like to have our code be self-documenting after all.

class Loader

{
    private:

        bool mEverythingReady { false };

        std::vector<Objects> mObjects;

    public:

        void Load()

        {

            for(auto& item : mObjects)

            {

                item.StartLoad();

            }

            mEverythingReady = true;

        }

   };

Can you already spot the problem?  The local code here is communicating that EVERYTHING READY, when it is anything but that, you have simply started some other action elsewhere, you have not checked the state, you have not deferred until ready, you have started load and that is all you know, but you code here locally is communicating something subtly different.

And in huge systems you must not fall foul of this kind of behaviour, you need your code locally to communicate what it intends, to do as it intends and if you spot silly public interfaces like this do not be affraid to fix them, the bravery to address an issue, if only to raise it to the owner, is a step in the right direction with massive software systems.

Monday, 26 February 2024

Tech Tribulations #1 : Smartcard Release Drama

It has been a very long time since a story time, so I thought I'd go over one about a software system I wrote from the ground up to secure the service to a machine; so I worked for a company which sold a whole machine to the customer (or leased them) while ever the buyer had the machines they would run.

In late 2014 the higher management realized this was an untapped revenue stream, and much to the annoyance of the customers, it was decided that a system update would go out; which the customer had to take to get any new content; and in this update they would have to also have a smart card reader installed and a card inserted which would count down time until it ran out.

Metering essentially, but "metering" had a whole other meaning for this system already, so it was just called the "Smartcard" system.

Really it was a subsystem, bolted into the main runtime as a thread check, which would wake at intervals, query if there was a card reader on the USB at all, check it was the exact brand of card reader (because we wanted to limit the customer just being able to put any in, they had to buy our pack).

And then it would query the card and deduce credit/count down if we were beyond a day.

We tried a bunch of time spans, hours, minutes etc, but deducting was decided to be after we accumulated 24 hours of on time, every 5 minutes an encrypted file on the disk would be marked, after 24 hours worth of accumulations the deduct would happen.

We tested this for months, absolutely months and to be honest we thought it was really robust.

Until it actually went into the customers hands, we suddenly had a slew of calls and returns, folks unhappy that they were inserting the card, "testing their machines" and suddenly all the credit was gone, and they were asking for a new card all the time.

At first we could simply not explain this anomaly, we had the written information about the service calls, replicated what the folks were saying, it all checked out fine, we got our increments, we could inspect the encrypted file and see we were accumulating normally and deducting normally.

I worked on this for days on end, we had to test for real, we did all sorts of things, power drop tests, pulling the card tests, all sorts.

The machine checked out, end of.

What had we missed?  What are the customers doing?  Testing the machine, okay, what are they testing?  The content, how does the content work for this update?  Well, seems that the customers didn't trust their testers or engineers, so what was happening was instead of testing for real they were doing what we called "Open door testing".

You see, when you close the door you accumulate and deduct, the machine is in operation normally as any user their end would have it operate....

Door open mode however, was intended to be used by service engineers, when the machine was deployed; so it is still in operation, the machine is in the field, but the door is briefly open to check things.

But these customers didn't trust their engineers in their warehouse, so they were not giving them credit to check the machine properly, they therefore tested in open mode... for days....

They accumulated massive operation debt with the machines in door open mode for days.

The moment they turned them off, happy they were working, and shipped them to sites they'd arrive on side immediately be turned on finally after so long in proper door closed operation and they'd instantly deduct the massive debt the warehouse team has accrued.

This was intentional.... But their use of the door open mode was an abuse, and one we had not even thought about.  We didn't even clock how long a machine sat in door open or door closed mode, worse still when in door open mode and test things on the machine ran at an accelerated update rate, we ticked over 10x faster to allow faster testing... The result was in just 3 days of warehouse door open mode testing they could accrue 30 days of operational debt.

That was a fault, one I could tackle with the team.  But changing the user habit of leaving the door open was harder...

We had to work with the user, and their patterns, we suspended the system for a short while and issued a new update, but the first customer taste of this "pay as you go" approach was a sour one.

Then things got bad....

Yes, you might think they were already bad, but they got worse.

A month later, all the above was resolved, and we thought things were settling down... Until we suddenly all hell broke loose.

EVERY MACHINE WAS LOCKED.

There were dozens of reports of their just not working, they had done their daily reboot and all of them reported a security fail on the smartcard....

All hands on deck, are our machines in the test pool doing the same?  Nope.

Is there something special going on?  Have clocks changed, is it a leap year, has the sky fallen on Chicken Little?

We honestly had no idea, there was no repeat in any of our test pool, no repeat on our personal engineering rigs, there was essentially no reason for this failure.

The only answer in such a situation is to observe or return one of the machines exhibiting the problem.

A lorry was sent and a machine brought back, under the explicit instruction not to open it nor change it, and the customer was not to keep their smartcard (it was theirs, but we would credit them a whole new card for the inconvenience).

Several hours spent staring at the code, and running checks by lowering cards so they would expire, or pulling the reader out and inserting it again we had no answer.

Before that arrives back with us however lets just think about the "smartcards" we used in our daily lives; our bank cards, they go into a machine we enter our pin and we remove them again.  Then how about cards like your gas meter, or you go see your GP, they have a card you insert into a machine and it stays there all the time to validate they are the GP, or they keep your meter in operation, if you have Sky TV and a viewing card; same thing, it is always in the device.

These machines are the latter kind.... Those cards are rated to have power on to them for long periods of time, as a consequence they cost more money than a card you only insert transiently...

And this company I worked for had very canny buyers, too canny.  Because they spotted a smartcard which used the same protocol... but was significantly less money to buy!

The difference?  You guessed it, it was the transient use variant.

The broken machine arrived, we powered it on, fail.  We open the door, remove the smartcard and sure enough on the rear of the plastic behind the chip the plastic is brown, burned.

The card can not be electrically trusted!

We highlight this and send it back to the buying department, they fouled up, they changed the hardware after we certified it, essentially sending an uncertified machine out.

A huge issue ensued about this, as this wasn't well understood that we had been provided and advised one card type into the update set, but of course the buyers would not accept it wasn't the same until we literally had the specifications of the card side by side we could see a digit difference in the part number and looked up the datasheet where clearly it said that the transient card was only rated to remain in a machine for 10 minutes.  More than enough for an ATM.  But a "security gating" card, as we wanted, they are rated to be inserted continually for 36 months.

Monday, 15 July 2019

Willful Ignorance (C++ Templates)

I had a moment last week where I was a little down on my C++, you see I'm a very old programmer, by programmer standards, and my experience with C++ stems from a time before templates, this may amaze and delight in equal measure as template use is so ubiquitous today, however I've been using find & replace style boiler-plate code in the form of both macros and code-gen for literally decades.

Templates however have not been my go to option, because of that weight of experience.  I actually find picking apart heavy template code quite hard going at times (I think a lot of us do).

But I was down as a valued colleague (Hi D if you read this, you know it's you) described this approach of mine as "willful ignorance".  And he was right, I have to put my hands up and admit he's right.

As such I took a look over my old state machine repo on github and realised there was a bunch of boiler plate stuff I was doing with both macros, or not doing at all, which could easily be made to leverage templates.

Watch this space...

Friday, 16 December 2016

Software Engineering : Is not Engineering

Right I'm guilty, and annoyed at myself, and making a change... Though I might still keep this as a tab on posts... I AM NOT GOING TO USE THE TERM "SOFTWARE ENGINEER" anymore....

This makes my degree certificate wrong, as it clearly states "Software Engineering", but even though that is indeed what I do every day, and what I read about every night, it is not what; nor who; I am... I am a programmer, a hacker (in the traditional sense), a tinkerer and a student of all things software.

Many other writers have call us programmers out on this, and finally, I'm going to eat humble pie and agree, when one sits down to write code one is not doing what the great engineers did, we are not forging rail-ways, bridges, hulls of great ships or physical tangible results which must stand the test of time.

We are building a more ethereal, almost smoke and mirror concept, results through the action of our instructions through another, that is programming it is what I do.

Why do I want to make this distinction?  Well, as you may tell from some of the recent posts around here, I've been involved in merging parts of teams and companies, meeting both incoming and shifting personnel to fit them into the matrix that spells "results" for a company.

No code has yet been cut, but a new team, and new ideas might very well be needed.  In turn I have reached out there and been talking to others, to recruiters, to other companies, and indeed I've sat before other people.

My friends also call upon my expertise, as one of the few from our graduating class still working in Software or indeed technology, I am often called upon for a little technical guidance.

Results have been mixed, but the determinable difference I have had between success and failure has relied, nearly exclusively, on the other party understanding the term "Software Engineer", it does not mean we can programme your VCR, set the clock on your Microwave, or save your phone contacts to your SIM card.  It means we are able to employ structured methods, to define procedure, and to design, write and test then document code as products for use or sale.

This does not include our being Electrical, Mechanical or Structural Engineers!

I am not trying, willing, or able to build the next Channel Tunnel, or Skylab, or HMS Bullshit.  I am able to cut code to make an existing system, or device, bend to the will of requirements upon it, I am able to look at the said device and decide whether it is fit for the purpose or not, I am not creating that device!

Creating said device is Mechanical or Electrical Engineering, I am Software, the use of the "Engineer" moniker is causing some confusion, some blurring of lines and so to help delimit this boundary and stop this confusion from now on I will self identify as a Programmer, and cease to try to explain all that this entails.

I am a Programmer, a Lead Programmer, a Systems Programmer, a Device Programmer, a Prototype Programmer, a Senior Programmer, a Team Leading Programmer, a Development Provisioning Programmer, no longer am I an Engineer!

Thursday, 5 May 2016

Software Engineering with 252117761

What's with this strange number Xel?... Well, this is a very useful number to help you determine how a remote system, or your network, is presenting numeric values.

When we program, we generally stick to one system or one platform at a time, however, life is never always so vanilla, and we've had a problem in the office today of talking to a raw network connection from a remote system.  We didn't know anything about this remote system, through a combination of lingual differences and a total lack of documentation (SNAFU).

So, we didn't know what endianess the remote processor was treating numbers as, and we also didn't know if the network was doing conversion between endian settings.

Apparently someone else had puzzled over this for a few weeks before giving up.

I however, channelled the power of the number 252117761.

What's so special about this number?... Well, it's a 32bit number, so we have four 8 bit bytes in there, and it's binary pattern is:

00001111000001110000001100000001

If you can't see the use of this pattern already in checking your networking and endieness, then you might have a problem.

It helps you check out the received values back, if you know you assign a value on one side as this integer, and we call for it across the link, we can see whether we get the above, or a change of order:

00000001000000110000011100001111

For example was the return we had, which is a change or ordering.

But you can also see whether you get:

00000011000000010000111100000111

Which is a short reordering.

Why 32 bit?... Well in this case, because we did know that the word size of the remote system was 32bits, but you can use this trick with any number of bits, just total up your values...

111111101111111001111110001111100001111000001110000001100000001

Might be a good 64bit pattern, and has the value 9187131167487755009.



Friday, 31 July 2015

NHS Typo

I've had a mystery appointment text'd to me today from the NHS, nice to see them using some good technology, my GP surgery uses an SMS based reminder system and I think it's a fabulous addition to the NHS armoury to reduce wasted appointment times.

Unfortunately, I didn't recognise this appointment, so checked it out and came to this page...


I was so sad to read the paragraph:

"If you believe the hospital has incorrect phone numbers recorded you will need to ask them to change their systems as we are note allowed to make changes to that data."

They are 'note allowed' to make changes to the data?... NOTE!.. NOT... It's a mistake, a typo, a small one, but the thing that bugged me was there was no way to tell them.

This site is powered by ZenDesk, so that page is just an entry in their knowledge base, but there's no way to give feedback.

Monday, 27 October 2014

British Gas - Poor Systems

I have to just release this, because if I don't vent, I'm going to blow... The payment and billing systems at British Gas must be so archaic it's untrue, they seem to have different systems doing separate different parts of the same job, and these separate different systems don't share information, so they're out of sync or slow or just so fucking annoying.

I've commented to them directly about this several times and they've simply ignored me, but now I figure its beyond a joke.

Last night, I had a reminder to submit my meter readings, so I popped onto their website to put them in, as I logged in I noted last months bill was still not paid, so I checked and made payment in full.  Submitted the new readings and had an instant bill...

Here's my first beef, if my bill was a reading last time and a reading this time then the values are consecutive and they calculate a bill instantly, and I paid it instantly....

However, the previous bill went unpaid for a month because the bill prior to that was estimated, and they waaaaaaay over estimated, so the readings went in and they were lower than even the estimates that had been put in.

The system immediately has a brain fart and doesn't give a bill, so after waiting all weekend for it I clearly gave up and didn't pay all month, because their system is just so shit, I figure a human had to intervene somewhere and reconcile their stupid estimate bullshit and issue the bill, and I can say this happens because more than once I've had to call them and correct a bill, to have to manually intervene and call an Indian call centre just to get a bill is wholly unacceptable in my book, it's the online equivalent of standing up and waving for the waiter in a restaurant and him giving you the finger.

So what did the website do last night?... Well, luckily this time it generated a new bill, and so I paid the first, submitted and paid the second... right done?... All cool...

NO!!!!!!

Because fucking hours later another system at British Gas decides to e-mail me and tell me I need to submit my readings....

Time runs upwards here, earlier messages are lower...

I'm tempted to go give them a reading which is like 1kw/h different and watch their system's brain drop out... Or even, I might start submitting individual readings each time the gas and electricity meter changes value... You know proper spam that sucker, I've read their billing small print there's nothing which says how few readings one has to make, just that one has to submit a reading or allow access to the meters by reading taking staff at intervals...

So, I use say 301Kw/h of electricity per month, lets submit 301 readings, their system asked me to submit a reading 5 hours after I'd done just that for the month!

Sunday, 13 April 2014

Corsair Airflow (RAM Cooler) Getting Old

In my rig I have lots of silent fans (140mm silent fans, 120mm silent fans), I did a review fitting Knox silent  Fans a while back, as part of that same rig however I have a Corsair Airflot RAM Cooler:


I've never really liked this addition, but it does serve a good purpose, cooling my RAM significantly, but the fans are small and loud, very loud, as it has aged however, it is getting terrible.

I had heard some users mention this unit making noise, but they didn't have it fitted to Corsair ram, so I assumed it was just their unique problem.  Well I do have Corsair RAM, I purchased the RAM and cooler as a kit when I put the current Core i7 rig together myself

Over time, I've heard it making a bit more noise than normal, but last night whilst working, I had to actually open the case and pull the power cable on this, it was grinding, vibrating and generally grumbling like crazy, as I pulled the power on it my rig became almost silent instantly, and totally silent once I'd shut the case back up again.  This little fan had been causing such trouble.

I actually trouble shot this even more, and using my finger bravely, stopped the fan spinning (don't do that at home folks!), and figured out it was the fan to the top most position which was making all the noise, the other fan was silent...

I'm thinking after a server back up of my code, and doing some work on the house at the weekend, it might be time to strip the PC down and clean it, and see about replacing this fan unit.