Professional Services
Custom Software
Managed Hosting
System Administration
See my CV here.
Send inquiries here.
Open Source:
tCMS
trog-provisioner
Playwright for Perl
Selenium::Client
Audit::Log
rprove
Net::Openssh::More
cPanel & WHM Plugins:
Better Postgres for cPanel
cPanel iContact Plugins
Over the years I've had discussions over the merit of various forms of dependency resolution and people tend to fall firmly into one camp or the other. I have found what is best is very much dependent on the situation; dogmatic adherence to one model or another will eventually handicap you as a programmer. Today I ran into yet another example of this in the normal course of maintaining playwright-perl.
For those of you unfamiliar, there are two major types of
dependency resolution:
Dynamic Linking: Everything uses global deps unless explicitly
overridden with something like LD_LIBRARY_PATH at runtime.
This has security and robustness implications as it means the
program author has no control over the libraries used to build their
program.
That said, it results in the smallest size of shipped programs and
is the most efficient way to share memory among programs.
Given both these resources were scarce in the past, this became the
dominant paradigm over the years.
As such it is still the norm when using systems programming
languages (save for some OSes and utilities which prefer static
linking).
Static Linking: essentially a fat-packing of all dependencies into
your binary (or library).
The author (actually whoever compiles it) has full control over the
version of bundled dependencies.
This is highly wasteful of both memory and disk space, but has the
benefit of working on anything which can run its' binaries.
The security concern here is baking in obsolete and vulnerable
dependencies.
Examples of this approach would be most vendor install mechanisms,
such as npm, java jars and many others.
This has become popular as of late due to it being simplest to
deploy.
Bootstrapping programs are almost always using this technique.
There is yet another way, and this is to "have our cake and eat it
too" approach most well known in windows DLLs.
You can have shared libraries which expose every version ever
shipped such that applications can have the same kind of simple
deploys as with static linking.
The memory tradeoffs here are not terrible, as only the versions
used are loaded into memory, but you pay the worst disk cost
possible.
Modern packaging systems get around this by simply keeping the
needed versions online, to be downloaded upon demand.
Anyways, perl is a product of it's time and as such takes the
Dynamic approach by default, which is to install copies of its'
libraries system-wide.
That said, it's kept up with the times so vendor installs are
possible now with most modules which do not write their makefiles
manually.
Anyhow, this results in complications when you have
multi-programming language projects, such as playwright-perl.
Playwright is a web automation toolkit written in node.js, and so we
will have to do some level of validation to ensure our node kit is
correct before the perl interface can work.
This is further complicated by the fact that playwright also has
other dependencies on both browsers and OS packages which must be
installed.
Normally in a node project you could use webpack to fat-pack (statically
link) to all your dependencies.
That said, packing entire browser binaries is a bridge too far, so
we either have to instruct the user properly or install everything
for them.
As is usual with my projects, I bit off a bit more than I can chew
trying to be good to users, and made attempts to install the
dependencies for them.
Needless to say, I have ceased doing so. Looking back, this
willingness to please has caused more of my bugs than any other.
Yet again the unix philosophy wins; do one thing, do it well.
This is also a big reason why dynamic linking won -- it makes a lot
of things "not your problem".
Resolving dependencies and installing them are two entirely separate
categories of problem, and a program only has to solve one to run.
The long-term solution here is to wait until playwright can be
shipped as an OS package, as many perl libraries are nowadays.
It's interesting that playwright itself made an install-deps
subcommand.
I hope this means that is in the cards soon, as that's most of the
heavy lifting for building OS packages.