Bound version constraints (upper caps) are starting to show up in
the Python ecosystem. This is causing real world
problems with
libraries following this recommendation, and is likely to continue
to get
worse;
this practice does not scale to large numbers of libraries or large
numbers of users. In this discussion I would like to explain why
always providing an upper limit causes far more harm than good
even for true SemVer libraries, why libraries that pin upper
limits require more frequent updates rather than less, and why it
is not scalable. After reading this, hopefully you will always
consider every cap you add, you will know the (few) places where
pinning an upper limit is reasonable, and will possibly even avoid
using libraries that pin upper limits needlessly until the author
updates them to remove these pins.
Out of the many attacks that threaten web applications today,
XXE remains the one that is talked about the least. Although it
gets far less attention than
XSS
or SQL
injections,
it does carry its own risk and should not be taken as a slight.
Lossless compression is the act of making a dataset smaller than its
original form while still being able to transform the compressed
version back into the original source material. This contrasts lossy
compression which produces a derivative dataset that, while being
something humans can appreciate, cannot recreate the original source
material.
This post is about how and why my multiplayer card game GALGA uses a
Free Monad DSL for its game rules. If that’s gobbledygook to you,
read on and hopefully it’ll make at least a little more sense by the
end!
Defensive CSS is a collection of snippets that can help you in
writing CSS that is protected. In other words, you will have fewer
issues in the future.
SSH signatures in Git use the same mechanism as PGP signatures, thus
you can keep using the -S flag for commits and the -s flag for
tags. However, you need to change the signature format.
In the process of switching my shell to Haskell, I also got a lot
faster at writing Haskell. Haskell is now the primary interface
through which I use my computers, and it has been very pleasant. I
no longer have to deal with regexes, since I can whip out a full
parser combinator library any time.
Very often, making code easy to unit test tends to go hand-in-hand
with improving that code’s separation of concerns, its state
management, and its overall architecture. In general, the more
well-abstracted and organized our code is, the easier it tends to be
to test it in an automated fashion.
However, in an effort to make code more testable, we can very often
find ourselves introducing a ton of new protocols and other kinds of
abstractions, and end up making our code significantly more
complicated in the process — especially when testing asynchronous
code that relies on some form of networking.
But does it really have to be that way? What if we could actually
make our code fully testable in a way that doesn’t require us to
introduce any new protocols, mocking types, or complicated
abstractions? Let’s explore how we could make use of Swift’s new
async/await capabilities to make that happen.
A common problem in computer animations is rotating an object in
fully 3D space. Think objects, spaceships and heroes tumbling and
turning in complex sequences. This is usually accomplished with an
arcane mathematical object called a quaternion.
It happens a lot, you write a bash script and half way it exits due
an error. You fix the error in your system and run the script
again. But half of the steps in your scripts fail immediately
because they were already applied to your system. To build resilient
systems you need to write software that is idempotent.
Traditionally, Python has been a blocking language when it comes to
I/O and networking, meaning lines of code are executed one at a
time. With network requests, we have to wait for the response before
we can make another request. Meanwhile, our computers sit
idling. Luckily, there are ways to address this, the most exciting
of which is leveraging asynchronous requests with the
aiohttp package. This article
explains how asynchronicity can help solve these issues – and how
you can put it into place within your own code!
A goal of the async foundations working group is for async Rust to
be portable and
interoperable. I
want to dig in to what that means in this blog post. For a little
background, see my earlier post on async
runtimes.
You’re using multiprocessing to run some code across multiple
processes, and it just—sits there. It’s stuck.
You check CPU usage—nothing happening, it’s not doing any work.
What’s going on?
In many cases you can fix this with a single line of code—skip to
the end to try it out—but first, it’s time for a deep-dive into
Python brokenness and the pain that is POSIX system programming,
using exciting and not very convincing shark-themed metaphors!
One Git usage pattern that I think is underused is the “branchless”
workflow. The idea here is pretty intuitive if you’ve used
trunk-based development:
there’s just one “main” branch that everything gets merged into. No
feature branches, no release branches, no hotfix branches.
The “branchless” workflow is, in a nutshell: You work in a stack of
atomic commits which are all eventually intended to be merged into a
single trunk branch. Each commit can become a pull request, and each
pull request consists of a single commit.
How do you visualize performance data so you can easily spot
bottlenecks? Brendan Gregg’s flamegraphs are a great solution,
adopted by a large number of profilers and performance tools.
This is the second article in a series where I try to understand
systemd by creating small containerized examples. In Part
1,
we created a minimal systemd setup in a container. We are now using
this setup to continue our investigation of systemd, starting with
taking a closer look at dependencies.
We all know that indexing is important, but it can be difficult to
know where to start. In this post, my aim is to collate some of the
best advice I’ve seen for indexing Postgres, and simplify it for
folks just getting started.
When writing asynchronous code using Swift’s new built-in
concurrency system, creating a Task gives us access to a new
asynchronous context, in which we’re free to call async-marked
APIs, and to perform work in the background.
But besides enabling us to encapsulate a piece of asynchronous code,
the Task type also lets us control the way that such code is run,
managed, and potentially cancelled.
The Memory Image Pattern (MIP) is a novel approach to application
development. It rejects the idea of storing state in a database and
gains both developer productivity and run-time performance. If you
can fit your application data in memory, MIP might be for you.
A couple of years ago I wrote a somewhat controversial article on
the topic of Bringing the Unix Philosophy to the 21st
Century
by adding a JSON output option to CLI tools. This allows easier
parsing in scripts by using JSON parsing tools like
jq,
jello,
jp, etc. without arcane awk,
sed, cut, tr, reverse, etc. incantations.
It was controversial because there seem to be a lot of folks who
don’t think writing bespoke parsers for each task is a big
deal. Others think JSON is evil. There are strong feelings as can be
seen in response to the article in the comments and also on Hacker
News and
Reddit.