Turn off tainting in brewed Perl.

I read that turning off tainting when building Perl can give you a speedup. Tainting also appears to be on the way out: it’s not needed for Mojolicious, for example. I brew my Perls so wondered how to do it. Some digging in the Perl distribution’s INSTALL file led me to a section on tainting. This suggested a flag. The next rabbit hole was how to get perlbrew to pass flags. Doing that and verifying with –verbose led me to:

export PERLBREW_CONFIGURE_FLAGS=-DNO_TAINT_SUPPORT 
perlbrew --verbose install perl-5.36.0 

And now some totally unscientific benchmarking using different Perl versions:

A simple benchmark suggested by David Farrell: https://www.perl.com/article/40/2013/9/29/How-to-benchmark-Perl-code-for-speed/

Perl-5.38.0 taint enabled:

equalsAssign: 11 wallclock secs 
(10.19 usr +  0.05 sys = 10.24 CPU) @ 200453.61/s (n=2052645)
shiftAssign: 10 wallclock secs 
(10.12 usr +  0.03 sys = 10.15 CPU) @ 202096.55/s (n=2051280)

Perl-5.38.0 taint disabled:

equalsAssign: 11 wallclock secs 
(10.52 usr +  0.02 sys = 10.54 CPU) @ 207983.40/s (n=2192145)
shiftAssign: 11 wallclock secs 
(10.51 usr +  0.01 sys = 10.52 CPU) @ 206375.10/s (n=2171066)
The code:

#!env perl

use strict;
use warnings;
use Benchmark qw/cmpthese timethese/;

timethese(-10, {
        shiftAssign => sub {    my @alphabet = ('A'..'Z');
                                for (my $i = 0; $i < 26; $i++){
                                    my $letter = shift @alphabet;
                                }
                           },
        equalsAssign => sub {   my @alphabet = ('A'..'Z');
                                for (my $i = 0; $i < 26; $i++){
                                    my $letter = $alphabet[$i];
                                }
                            },
});

So all-in-all about 10% in a handwaving kind of way.

Software anti-patterns

Python – Don’t be afraid of the dark

You may have an enormous ball of mud written in Perl but there are many benefits to introducing a new language like Python or Go:

  • The communities are vibrant
  • It’s easier to hire someone
  • They can do everything Perl can do

Documentation – Have some

  • Do not strip the comments from the code. That reminds me of WWII UK when signposts were removed to confuse the enemy.
  • Have documentation for each sub saying what the inputs are, the outputs and if you have a god object, what the side effects are.
  • Have documentation, preferably in POD in the code that reflects precisely what the code does. You can do lots with this. And test it.

Don’t have an overly complicated branching strategy

  • Don’t have a main branch that isn’t main/master.
  • Have a branch for each story.
  • Have branches for releases.
  • Do gitflow, it’s simple.

Jumphosts – They’re a PITA

  • Don’t be SO paranoid about security
  • Are you so locked down you have to ssh through a jumphost? And the jumphost won’t do ssh forwarding?
  • That breaks so much: no sshfs, no remote editing in your chainsaw of choice.
  • For bonus points, the dev machine can’t see the git repo. Please. I don’t like coding with a paper bag on my head.

CI on commit – Do it automatically

  • Once you have tests, run the CI pipeline when the code gets committed.
  • Preferably deploy (CD) that branch to the/a dev machine.
  • It exercises your deployment process. Remove a speed bump.
  • Deploy to dev and scheduled to test. It’s a computer: automate it.
  • Make friends with Docker. It makes life SO simple. Having laptops able to see the database is a BIG WIN.
  • Keep your dev database up to date.

No tests – a classic

  • Write your code so it’s testable. Don’t do everything through a God object. Have subs that have defined inputs and outputs.
  • When using Test::Perl::Critic::Progressive (or equivalent) to make sure your code isn’t getting worse, you’ll probably need to copy t/.perlcritic-history into and out of the artefact store between each run.
  • Can your CI machine see a test database? If not, you’re entering mocking hell.
  • Tests provide code examples. This is good.
  • Put the tests on a pre-commit git hook. Remember to chmod +x it.
  • Graph the progress if you can.

Running Oracle database server on a Mac.

Due to my upcoming job having a large part being Oracle, I figured I should install Oracle on my Mac. I found this article on the Oracle site that made running it in a virtual machine look easy. Simply, it’s:

git clone https://github.com/oracle/vagrant-projects
cd vagrant-projects/OracleDatabase/21.3.0-XE 
# Optional: download the Oracle Database installation file and place it in this directory
vagrant up

And that’s where the wheels fell off. I haven’t used Vagrant for a couple of years. My Vagrant fell into a wibbling heap. I needed to do the following to drag everything up to date:

brew install vagrant

And then install Virtualbox from the Virtualbox downloads page. Bringing up vagrant then refreshes the vagrant image, brings the oracle image up to date and runs it.

    oracle21c-xe-vagrant: INSTALLER: Started up
    oracle21c-xe-vagrant: Oracle Linux 8 BaseOS Latest (x86_64)           3.3 MB/s |  49 MB     00:14
    oracle21c-xe-vagrant: Oracle Linux 8 Application Stream (x86_64)      3.2 MB/s |  37 MB     00:11
.
.
.
    oracle21c-xe-vagrant: INSTALLER: Oracle preinstall and openssl complete
    oracle21c-xe-vagrant: INSTALLER: Environment variables set
    oracle21c-xe-vagrant: INSTALLER: Downloading Oracle Database software

You’re going to need the instantclient libraries. Do the following in the instantclient directory, you might want to have copied *.dylib* into /usr/local/lib:

$ chmod u+w *
$ xattr -r -d -s com.apple.quarantine instantclient_19_3

vagrant ssh into the Virtualbox, sudo su – to root, thence to the oracle user and sqlplus sys as sysdba gets you in. This isn’t wildly useful but it’s a start.

Fresh Ubuntu networking and host directories

Networking

When I installed ubuntu 20.04.3, I expected the ubuntu networking to Just Work. That was wrong. And apparently, there’s a new network management subsystem to worry about. A quick Google search led me to the Ubuntu docs and thence to create the file /etc/netplan/01-netcfg.yml:

network:
  version: 2
  renderer: networkd
  ethernets:
    enp0s3:
      dhcp4: true

Then this line enabled the interface:

sudo netplan apply

Host directory

I put all my GitHub/GitLab checkouts in ~/workspace, a hangover from BBC days, along with using VMWare Fusion. Although I tend to use docker more these days. I tried mounting it from within VMWare but no luck. A pointer from a chap on Reddit led me to these lines:

mkdir /mnt/hgfs
sudo mount -t fuse.vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other

Or alternatively, add the following to /etc/fstab:

.host:/	/mnt/hgfs    fuse.vmhgfs-fuse	auto,allow_other	0	0

And there we go. Disappointingly everything I wanted didn’t work out of the box, but I got it working in the end.

MySQL 8.0 oddity – passwords and password policy

These are all things you can find elsewhere but a couple of password issues came as a surprise to me

MySQL
These are all things you can find elsewhere but a couple of password issues came as a surprise to me when a legacy system got the MySQL 5.7 upgraded to 8.0.

Firstly, password policies are much tighter. There’s a plugin that by default demands an uppercase letter, a number and a punctuation character. That foxes our legacy system whose installer just generates lowercase letters and numbers. Uninstall it.

UNINSTALL COMPONENT 'file://component_validate_password';

Another good one was the the library I was using, and didn’t want to upgrade, didn’t know the default authentication to connect to MySQL. That was easily fixed:

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxxxxx';
Query OK, 0 rows affected (0.03 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

Having gone from a Centos 7 MySQL accidentally to MySQL 8.0 and back again, that’s a world of pain involving the recompiling of the Perl DBD::MySQL and finding the correct .so library.

Damn you linux reference counting.

GitHub logoSo this was an hilarious case of reference counting.

There I was, developing my Perl Catalyst app. I migrate to gitlab like all the other cool kids. I move the original development directory to .bak like a good boy.

But, my plackup is still running and because reference counting, the open files are all still there so I was still happily running. I check out the gitlab version, make changes and NOTHING HAPPENS. Until finally the penny drops, I quit the original, now renamed directory and re-enter the correct one.

Suddenly everything works and hilarity ensues.