HN user

pmahoney

632 karma
Posts1
Comments208
View on HN

I wrote some code to do almost this many years ago (if I recall correctly, it doesn’t cache anything to disk, but builds the hash fresh each time, which can still result in massive speed up).

Probably obsolete and broken by now, but one of my favorite mini projects.

(And I just realized the graph is all but impossible to read in dark mode)

https://github.com/pmahoney/fastup

If that phrase "for individuals" means "for individuals only", then it isn't GPLv3, but some bespoke non-free license.

My speculation: it was intended to mean: use it under terms of GPLv3 (for commercial purposes or not), OR contact to negotiate different terms.

But there's a built-in assumption that no commercial entity would _want_ to use it under GPLv3 terms.

I tried to like OCaml for a few years. The things that hold me back the most are niggling things that are largely solved in more "modern" langs, the biggest being the inability to "print" arbitrary objects.

There are ppx things that can automatically derive "to string" functions, but it's a bit of effort to set up, it's not as nice to use as what's available in Rust, and it can't handle things like Set and Map types without extra work, e.g. [1] (from 2021 so situation may have changed).

Compare to golang, where you can just use "%v" and related format strings to print nearly anything with zero effort.

[1] https://discuss.ocaml.org/t/ppx-deriving-implementation-for-...

Can you explain further? I'm not sure I follow.

How do you as a method author opt in to distinguishing between [break and next] after yielding to a block?

I don't use Ruby much lately, but if I yield to a block which calls break, control will pass to the code following the block (and not back to my method). If the block calls next or simply finishes, control passes back to me though I cannot know if next was called or not (but do I care? I can go ahead and yield the next element of a collection either way)

This paper, "Insufficient Sun Exposure Has Become a Real Public Health Problem" [1] states "thus, serum 25(OH)D as an indicator of vitamin D status may be a proxy for and not a mediator of beneficial effects of sun exposure".

That is, while vitamin D can be used to deduce someone's amount of sun exposure, the benefits of sun exposure are not coming from the vitamin D.

[1] https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7400257/

Many years ago (2011 or so?), I worked on a Rails app that used JRuby. The driving force was a small part of the app needing a Java library. I think we did see some performance benefit, or at least benefit from using multi-threaded web servers instead of process-per-request servers (like Unicorn).

However, we also ran into many problems that felt like we were the first to encounter them (few or no similar reports on project bug lists or StackOverflow etc.) which is never fun if you're under any kind of pressure to deliver.

In hindsight, if I had something small and reasonably isolated (a microservice?), it could make sense to use JRuby or Truffle (if you need some JVM lib; if it's purely for performance reasons I'd just grab a different language for that microservice). But for a larger app that pays the bills, I'd stick with the well-trod path (at the time that was MRI, Unicorn, single-threaded).

Coupled with an increase in food delivery efficiency, kitchenless flats could become the norm in densely populated areas.

Sounds dystopian. Hustle and bustle of life aside, physically cooking things can be enjoyable. On the other hand, when I cook "from scratch", I'm buying conveniently packaged ingredients (I don't grow or grind my own flour for example), so maybe I'm happy with my current level of effort from simple familiarity.

Not sure if this would help, and I'm not exactly sure I'm understanding you correctly, but when I tie hockey stakes, instead of a single "left-over-right starting knot" (using terminology from the post), I wrap around two or even three times. This provides enough friction for that first knot to stay put while I tie the loops of the standard shoelace knot (not the Ian knot, with which I'm unfamiliar).

I stopped using `set -e`. It is disabled if the function you're running is part of an `if` statement, for example:

    thingThatCanFail() {
      echo "step one succeeded"
      echo "step two failed"
      false
      echo "step three was run too"
    }

    if ! thingThatCanFail; then
      echo "thingThatCanFail failed!"
    fi
With or without `set -e`, step three is run, and the function returns success, even though you might expect the failure of step two to prevent step three from running.

If "thingThatCanFail" is called _outside_ of an if statement, then `set -e` causes different behavior (i.e. step three _is_ skipped).

I instead use lots of chaining with && (as in the article), or explicit checks after each command. I have two utility functions I define in nearly every script:

    warn() { >&2 printf "%s\\n" "$*"; }
    abort() { warn "$@"; exit 1; }
Then I do lots of:
    stepOne || abort "step one failed"
    stepTwo || abort "step two failed"
    ...
It can get a little verbose, but much better than trying to reason about `set -e` in my opinion.

Here is (I think) the example regex ported to OCaml's Re library [1]

    let my_regex =
      let open Re in
      seq [
          bos;
          opt (str "0x");
          repn (
              alt [
                  rg 'A' 'F';
                  rg 'a' 'f';
                  rg '0' '9';
              ]
          ) 4 None |> group;
          eos;
      ]
      |> compile
I'm familiar with standard (compact) regex syntax, but I've been using the above syntax recently in a couple small places. I'm a bit on the fence as to which is "better". The compact syntax is, of course, more compact. I think it's a very similar comparison between APL (which I've not used) and most other common programming languages.

One advantage of the expanded syntax is that it's a bit nicer to incorporate a string variable, e.g. "str some_string" vs. "/#{Regexp.escape(some_string)}/" (to borrow Ruby's syntax).

[1] https://github.com/ocaml/ocaml-re

This doesn't answer your question, but I'm piggy-backing with comments on k3s.

For me, using k3s for development (not prod), the killer feature is running it in --docker mode where the node uses the local dockerd to run containers (vs. managing its own containerd instance).

This allows building images locally with `docker build` and immediately using them in kubernetes pods _without_ first pushing to a (possibly local) image repository and having k3s pull the images.

Last time I investigated, none of kind, microk8s, or minikube supported this mode. For large images (gigabyte or more, and I've got a handful of these), it's very space-inefficient to have a copy in my docker and in a local registry _and_ in k3s's containerd at the same time. How is this problem typically solved?

(I note the kubernetes included in Docker Desktop on macOS works in the same way: images built with `docker build` are available to kubernetes without going through a registry.)

It's not a contradiction to state something is not a problem most of the time. (Though the next point, calculating checksums prior to build, is much more significant.)

Related example: on a cloud instance with SSD drive, I have scripts that generate a ~10GiB file, then immediately after (while it might still be in cache), calculating an md5sum still takes tens of seconds (maybe it wasn't in cache? I've not investigated deeply). It's just an example of a case that falls outside of that "Mostly" category.

Hi Paul, thanks for Ardour.

For anyone curious, this wiki page describes how to package and run some precompiled binaries on NixOS, particularly the section "The Dynamic Loader": https://nixos.wiki/wiki/Packaging/Binaries

NixOS tries to insist that programs reference only other paths within the nix store (e.g. /nix/store/9rabxvqbv0vgjmydiv59wkz768b5fmbc-glibc-2.30/lib64/ld-linux-x86-64.so.2 which is a specific version built by a specific compiler, rather than /lib64/ld-linux-x86-64.so.2). This is the source of the per-program isolation that enables all the nifty features of NixOS.

NixOS _does_ make exceptions to that though, for example providing both /bin/sh and /usr/bin/env at those paths.

That's an interesting point. But it's not just rpaths, there are many references to things within the nix store. I suspect it would quite difficult to make them bound at runtime or something, but would be nice if possible.

Hindsight is 20/20. It wasn't /opt/nix for reasons I do not know. In the context of NixOS, there's little reason to consider FHS. Only when using Nixpkgs outside of NixOS does the /nix choice look poor. I don't know which came first.

Nix living at a predefined path is integral to how it works. An executable does not dynamically link to a generic "ncurses" but (via rpath) links to a specific compiled version of ncurses (such as /nix/store/81rb87agmp9cbsvg2xm2n4kp9c6309lv-ncurses-6.2). This is the root of all the benefits of Nix such as being able to install things side-by-side that use different versions of things or upgrade and rollback without problems.

That predefined path being the same (/nix) across all users of nixpkgs is required to be able to share binary packages (you could perhaps build everything from source, but that's a lot of time, more time even than something like gentoo because package updates require all dependencies to be rebuilt as well).

You can call it an insane choice or bad design, but there aren't a whole lot of options here. Could Nix move to a different path? Maybe, but is there a path that all operating systems could abide? If the new path stops working in some future OS, will it still be insane and bad design? Again, maybe, but I happen to love Nix and I use is on macos because it makes my life easier (and I'm on macos for work reasons). I'm willing to bend and do a lot of legwork to be able use Nix, and I'm upset with the Catalina situation.

Can follow some discussion here https://github.com/NixOS/nix/issues/2925

This is a good question, and I think the article doesn't cover this topic well.

From the article: > The other one is to tell if during a pod's life the pod becomes too hot handling too much traffic (or an expensive computation) so that we don't send her more work to do and let her cool down, then the readiness probe succeeds and we start sending in more traffic again.

Well... maybe. Is it a routine occurrence that an individual Pod becomes "too hot"? If your load balancer can retry a request on, say, a 503 Service Unavailable, you may be better off relying on that retry combined with CPU-based autoscaling to add another Pod (it's simpler, tradeoff is the load balancer may spend too much time retrying).

If you can't or don't want to add additional Pods, then your client is going to see that 503 (or similar) anyway. I'd say, then, that the point of a Pod claiming it's "not ready" to get itself removed from the load balanced pool is to allow the load balancer to more quickly find an available Pod, but this adds complexity and may be irrelevant if you run enough Pods to have some overhead capacity.

A Rails app is a bit different from a node/go/java app in that (typically at least, if you're using Unicorn or other forking servers) each individual Pod can only handle a limited number of concurrent requests (8, 16, whatever it is). It's more likely then that any given Pod is at capacity.

But, liveness/readiness are not so simple. If these probes go through the main application stack, then they're tying up one of the precious few worker processes, even if only momentarily. I haven't worked with Ruby in a number of years, but I remember running a webrick server in the unicorn master process, separate from the main app stack, to respond to these checks. But I did not implement a readiness check that tracked the number of requests and reported "not ready" if all the workers are busy.

The article states the process was discovered

while investigating the crystallization rates of metal, Czochralski dipped his pen into molten tin instead of an inkwell. That caused a tin filament to form on the pen’s tip

And later, describes the process for silicon

Once the silicon melted, he placed a small piece of polycrystalline material—a seed crystal

It seems then, that the seed crystal is not anything special. A typical piece of metal (such as a the pen tip) is made of up multiple single-crystal "grains" with non-crystalline "grain boundaries" between them; this is a polycrystalline material.

The question then is, why does only a single crystal form, rather than multiple crystal filaments oriented at different directions according to whichever grain contacted the starting point of the filament...