Performance and Thread Count

I have seen many mails and forum posts, which sort-of imply that increasing the number of threads working on a task will speed things up overall. This is a dangerous path to follow in many cases, because it has the major drawback of adding overhead.

In some cases there is a range where the increase of parallelism indeed improves the situation. But that is only because of very particular performance characteristics. Basically what needs to fit is the ration of in-system execution time vs. wait time for other systems. And the critical “side” condition for the other systems is that there is no resource congestion/conflict there: I.e. if you decide to add more load (by increasing the number of threads on your side) to an external database that is already maxed out, how do you expect your code to run faster?

Lastly, there is neither a one-size-fits-all number of threads to recommend, nor can one always say that adding threads will make things better at all. The opposite can happen quite easily and it always needs proper testing with full load. Putting the latter onto the system is harder than most people think, unfortunately. But the benefit will very often be a profoundly improved understanding about the application and especially its TRUE bottlenecks. Parallelism will almost always yield results very different from a single-threaded execution (e.g. when run from Designer).

Let me close by saying that in a surprisingly high number of scenarios, and again there is a number of pre-conditions associated, a single-threaded execution will give the highest performance (which we have not defined as a term at all here, by the way). This is because the overhead mentioned at the beginning kicks in. If you manage to have your code run such that you reduce or even eliminate cache misses on the CPU, you can see improvements by a factor of 10,000+ (and that is really not percent but a factor). But in general the effort to achieve that outweighs the usefulness; unless we talk about things like high-frequency trading of course.

New Notebook

After more than seven years my beloved MacBook Pro 15″ (late 2011) has died the GPU death. Before that I have had at least three replacement motherboards, the first after less than 24 hours of owning the thing. All these replacements were free-of-charge and without any hassle. So no complaints from that end. But given Apple’s abysmal product strategy in recent years, and particularly the butterfly keyboard, it was no option to buy a MacBook again.

To be clear on the keyboard topic: My primary objection against the butterfly keyboard is not its reliability, or lack thereof. For me it is simply a very bad keyboard with its short-travel keys. Yes, I am lucky to own an original IBM Model M and that sets a very high bar. But there are quite a few people I know who share that verdict.

Another factor not in favor of Apple was its pricing strategy and the fact that repair is next to impossible. Why would I want to spend enormous amounts of money (approximately EUR 3.500 for what I want) on a machine that cannot be repaired, upgraded, and is thermally constrained anyway? And quite honestly, with all the systematic product issue that existed for more than a decade, why would I believe this has changed?

I still own a Mac Mini from 2011 but it is months that I last used it. And after a number of years when I was really(!) happy with MacOS, I am finally departing from the latter. Overall, I got the impression that the management folks of Apple are going though the “harvesting” phase, where bean-counters have taken the reign after the founder(s) were gone. The same has happened to Hewlett-Packard, which I have had the privilege to work for many years ago. They, as so many others, had the same problem: People at the helm that do not really understand the business, but just apply methods they learned at business school. And for a number of years that works. Until it does not anymore …

So I ended up in the Windows camp, again. While Linux is my OS of choice on the back-end/server side, it has been failing to convince me for the desktop for the last 24 years. Yes, I started using Linux in 1995. And for special purposes I have used it on the desktop, usually via X11, where it made sense to me. In the 1990s that was technical development as well as authoring papers for university with LaTeX. And while a recent attempt, using KDE Neon, showed great improvements, there are still too many things that simply work better for me in Windows.

As to the actual notebook, I was pointed to the Razer Blade 15 (2018 base model) from various YouTube videos. It is a great machine and I had gotten a pretty good deal on Amazon for it. Everything was great – but the keyboard. The latter is something you can find mentioned in a number of reviews, but I must admit that I had underestimated it greatly. This is really sad, because otherwise it would have been the perfect machine for me. So where did I end up instead as keyboard afficionado?

Yes, a Thinkpad T model. What else! More precisely a Thinkpad T490 with a full-HD display, 16 GB of RAM and a 1 TB SSD. This blog post is actually the first one written on the T490 and the keyboard is an absolute treat. What drove IBM to sell this part of the business to Lenovo? Oh yes, the harvesting phase ;-).

webMethods Integration Server: How to Structure Packages

For the webMethods Integration Server (IS) packages are “containers” that bundle together various assets and get deployed as sort-of atomic units; this makes them more or less comparable to web apps in a servlet container.  So if you are given a certain task to solve, you need to figure out a clever way to organize the various parts of the overall implementation. Unless we talk about something trivial and short-lived (ever seen?), this is more complicated than it might appear at a first glance.

I did my first project on Integration Server 4.6 in early 2002 and can now openly confess, that the result, while working fine from a business perspective, was not something I would still be proud of today. To a small extent, the hardware equipment can be blamed. I was working with a notebook that had 256 MB of RAM, a single-core 800 MHz mobile Pentium III, a 20 GB hard disk with a whopping 4200 RPM, and a 14 inch display with a 1024×768 resolution.

You may now ask, how this can affect code quality. Most important in my case was performance. If pressing the save button literally sends the machine into a 2+ minutes period of frantic disk activity, you think more than twice before doing this. (Eventually, I got a memory upgrade to 512 MB.) And this is only the tip of the iceberg. In summary, refactoring is very hard if your concentration is constantly drawn away, because you have to wait for your machine to be ready again. Luckily we are past those issues today.

For the sake of this article let’s work with the following scenario, which is close to something I worked on about two years ago:

The business requirement is to automatically perform modifications to certain sales opportunities in the CRM system and report the result to the account manager.

Of course you can put everything in one package. There will be no need to think about dependency management and much less work for setting up the DEV environment, the CI server, deployment scripts (Chef in my case), etc. And in fact this is how I started. Pretty soon I moved some really generic utility services like data type conversion or date calculation into a separate utilities package. But other than that things stayed quite monolithic.

It didn’t last long, though. When I was half-way through with the initial implementation, the next, more or less separate business scenario that involved the CRM system showed up. Obviously, there was no point in having connection details, services, and other configurations related to the latter multiple times. So I moved all CRM-related stuff to yet another package.

To be clear: I was not taken by surprise when this happened. Instead it was a deliberate decision to be very careful with upfront framework building. This has been one of my personal rules for a while and it has the great advantage of being efficient as well as effective. The efficiency comes from the fact that no time is spent on things that later turn out not to be needed a second time. More important, however, is the effectiveness. It means that the outcome is useful. If you ever came across an API that is cumbersome to use, you know what I’m talking about.

Coming to an end, here is the abstract description of how I structure my IS packages. There are certainly other ways, but this works really well for me and not once in many years has caused issues or created that gut-feeling, which tells you that something is not right, although you cannot say what it is.

  • Business logic: Here is where specifics of the business side are handled. What are the criteria to select an opportunity for processing? What changes shall be applied? Technical details of the CRM system are not in scope here.
  • System details: How to perform a query against the CRM system using the criteria coming from the business logic level above? What are the connection details for a given environment (DEV, TEST, PROD)? Not in scope is e.g. the implementation of auditing.
  • Common topics: How to send notifications (e.g. where is your mail server)? Auditing, dealing with data structures, date manipulation, logging, etc.

In terms of naming conventions I suggest the following

<COMPANY_INITIALS>_<TYPE>_<DESCRIPTION>

Here are a few examples for the famous Acme Corp.

  • AC_APP_CrmOppCheck   : Application that performs checks on sales opportunities
  • AC_CMN_Audit                     : Auditing
  • AC_CMN_Util                         : Utilities
  • AC_SYS_CRM                         : Connectivity and services for CRM system
  • AC_SYS_ERP                          : Connectivity and services for ERP system

If you have questions, please do not hesitate to ask in the comments.

webMethods Integration Server: Create non-printable characters

It is a common requirement (e.g. for search-replace operations on strings) to create characters that are non-printable, which also means there is no obvious way to type them in. In my case the situation was that I had to convert end-of-line characters  created on a Windows system (CR+LF) to Linux (LF only) for some unit tests to pass.

On webMethods Integration Server you have two options to do this. The first is to create a small Java service, which has the down-side that some people shy away from it. (I have even seen organizations that pretty much forbid them, which is probably a bit extreme.) The second way is to have a Flow service (Integration Server’s graphical programming language), which is what I demonstrate here.

So how do I create a LF character? For this you can use the pub.string:URLDecode service with “%0a” (without double-quotes) as input, which is simply the character with ASCII number 10 (0x0a).

And then you simply perform a replace operation using the pub.string:replace service and tell it to replace all CR+LF occurrences with LF. The search part is done best with a regular expression, in this case “\r\n” (again without the double-quotes). And don’t forget to set useRegex to true.

That’s it.

Simon Sinek: The Finite and Infinite Games of Leadership

Another very interesting talk of Simon Sinek, this time at Google. The full title is

“The Finite and Infinite Games of Leadership: Leadership, Business and Finding Purpose in the Workplace.”

The following points were interesting  for me:

  • Time code 7:00 :  Infinite players do not compete with the competition but themselves. This has an awful lot of strategic implications.
  • Time code 16:55 : Dealing with personal objectives and bonuses. Also see my post about this very topic.
  • Time code 33:00 : Why are small companies usually more innovative than big ones?

VLANs with pfSense, Unifi, and VMware ESXi

For setting up VLANs in my home network I basically followed the tutorial from Crosstalk Solution on YouTube:

The result, however, was not working as expected. As it turned out the critical difference was that I have my pfSense firewall running virtualized on VMware ESXi 6.5. By default the latter “removes” VLAN tags.

But it is very easy to change this and not even a reboot is required. So here are the steps you need to perform:

  • Log in to the admin web UI of ESXi
  • Go to the network port groups and open your internal network
  • Open settings for internal network
  • Change VLAN to 4095
  • Save change

That’s all 🙂

Larry McEnerney: The Craft of Writing Effectively

Mr McEnerney presents a really good “strategic” approach to writing in a professional context. On the one hand nothing really new, but the way it is presented and details being put into context, make this a wonderful framework for me.

In particular it became even clearer to me why knowing a lot about a subject often makes it more difficult to write about it or discuss things with non-subject-matter-experts. This is also described nicely in the course description for professionals.

And finally I want to direct your attention to this nice blog post about a personal encounter with Larry McEnerney.

pfSense Upgrade to 2.4.4 p1

Just a few short lines to let you know that for me the upgrade from plain 2.4.4 to p1 went really smooth.

I have the following plugins installed:

  • bandwidthd (0.7.4_1)
  • iftop (0.17_2)
  • net-snmp (0.1.5_2)
  • ntopng (0.8.13_3)
  • Open-VM-Tools (10.1.0,1)
  • suricata (4.0.13_11)

All plugins had been updated some time ago and thus prior to the pfSense core, which is not recommended. In my case, though, it did not cause any issues. This was a pleasant difference to the upgrade from 2.4.3 to 2.4.4 (also see this video on YouTube), where the fact that plugins had been installed was cause for a completely broken system after the upgrade.