HN user

bminor13

54 karma
Posts0
Comments25
View on HN
No posts found.

I think SQL is great for building everything

Are you saying that you prefer SQL over PromQL for metrics queries? I haven't tried querying metrics via SQL yet, but generally speaking have found PromQL to be one of the easier query languages to learn - more straightforward and concise IME. What advantages does SQL offer here?

  Location: Raleigh, NC (US)
  Remote: Yes
  Willing to relocate: Yes
  Technologies: Backend programming (Go, C++, Rust), scripting (Python), build tools (Bazel, Buildbarn), and infra (Docker, Kubernetes) (and more!)
  Résumé/CV: https://www.linkedin.com/in/scott-minor-a360a821/
  Email: jobs@scottminor.email

In order to be in the same G-node, they'd need to have the same rank and be close in value (such that they were not "broken up" by a value in the next highest rank), right?

Seems like brute-force search for adjacent values with the same rank is possible, but guaranteeing that intermediate higher-rank values dont also exist may not be (for an attacker). Maybe one mitigation on this sort of attack is to search for higher-rank extra values to insert to break up large G-nodes?

This also assumes they can know the hash function (if rank is chosen by cryptographically-secure hash); maybe also salting values before hashing could thwart these sorts of attacks?

it seemed natural to have a set of generations for items that have only been seen once, and then another generation for things that have been more active

Have you looked at ARC? It sounds similar - it is a cache split between LRU and MFU areas, where the split point changes dynamically depending on the workload. https://www.youtube.com/watch?v=F8sZRBdmqc0 is a fun watch on the topic.

Does anyone happen to have expertise/pointers on how ZFS' ARC interacts with Linux disk caching currently when using ZFS-on-Linux? It seems like the ARC space shows up as "used" despite being in a similar category of "made available if needed" - is that correct?

Is data in the ARC double-cached by Linux's disk caching mentioned in the post? If so, is it possible to disable this double-caching somehow?

proto3 messsage fields allow for detecting set vs. not set; other field types (repeated, map, int32, string, bool, enum, etc.) have this "default value if not set" issue. The canonical way of handling this is to use wrapper messages (because one can detect if the wrapper is not set), and there are "well-known" canned messages/protos one can import and use without writing their own: https://protobuf.dev/reference/protobuf/google.protobuf/

Whether the codegen/libraries for a particular language provides a more idiomatic binding for these well-known wrappers is up to the implementation - for example, golang libraries have conveniences added for well known libraries: https://pkg.go.dev/google.golang.org/protobuf/types/known. Rust libraries may have the same; I'm not as familiar with the ecosystem there.

I can definitely sympathize here - in every context, just straight JSON/YAML configuration seems never expressive enough, but the tooling created in response always seems to come with sharp edges.

Here are some of the things I appreciate about Jsonnet:

- It evals to JSON, so even though the semantics of the language are confusing, it is reasonably easy to eval and iterate on some Jsonnet until it emits what one is expecting - and after that, it's easy to create some validation tests so that regressions don't occur.

- It takes advantage of the fact that JSON is a lowest-common-denominator for many data serialization formats. YAML is technically a superset of JSON, so valid JSON is also valid YAML. Proto3 messages have a canonical JSON representation, so JSON can also adhere to protobuf schemas. This covers most "serialized data structure" use-cases I typically encounter (TOML and HCL are outliers, but many tools that accept those also accept equivalent JSON). This means that with a little bit of build-tool duct-taping, Jsonnet can be used to generate configurations for a wide variety of tooling.

- Jsonnet is itself a superset of JSON - so those more willing to write verbose JSON than learn Jsonnet can still write JSON that someone else can import/use elsewhere. Using Jsonnet does not preclude falling back to JSON.

- The tooling works well - installing the Jsonnet VSCode plugin brings in a code formatter that does an excellent job, and rules_jsonnet[0] provides good bazel integration, if that's your thing.

I'm excited about Jsonnet because now as long as other tool authors decide to consume JSON, I can more easily abstract away their verbosity without writing a purpose-built tool (looking at you, Kubernetes) without resorting to text templating (ahem Helm). Jsonnet might just be my "one JSON-generation language to rule them all"!

---

Though if Starlark is your thing, do checkout out skycfg[1]

[0] https://github.com/bazelbuild/rules_jsonnet

[1] https://github.com/stripe/skycfg

shifting default workflows away from the standard client is one of those changes that doesn't serve users

There is no "default workflow" for git - Git can be used in a variety of ways; everyone has their own personal preference, and some of these workflows are shaped by interacting with systems like Github/Gerrit/etc.

Every place I've ever worked at has either:

  - a home-grown wrapper around git to make common operations easy
  - a recommended set of git aliases around common operations
The fact that Github has created their own to interact with their own system is a net win for individuals/organizations who would otherwise need to spend time scripting their own.

Of all the capabilities of the Github CLI, `gh pr checkout` is the only one I use, because it makes it easy to fetch a PR locally by ID without configuring a remote per fork. I'm pretty glad I didn't have to write this myself.

Htmx in a Nutshell 4 years ago

Question about this part of the hypermedia vs data APIs essay: "This new end point is driven entirely by hypermedia needs, not data model needs. This end point can go away if the hypermedia needs of the application change"

Presumably these hypermedia endpoints are all equally accessible - couldn't the removal of one break another application if the latter app decided to depend on a particular hypermedia snippet from the first?

If there are multiple teams in an org that own HTMX endpoints, aren't the set of endpoints effectively a sort of interface boundary? Or is there a good way of declaring certain endpoints "private" and ensuring they're only fetched from particular applications? (Maybe separate domains for every app?)

but if we changed the culture to become more emotions-aware, people would know how to help each other and themselves far better.

Fixing psychological and emotional problems through cultural change just doesn't solve anything.

By my reading, the two quotes are in direct opposition to one other. It sounds like you are advocating for cultural change - just a different type/approach than is currently used?

My only short exposure to Prolog was trying to implement custom submission rules in Gerrit. It made an utter fool out of me at every turn - it really seemed like an insane interface, compared to e.g. a Python or Javascript function that could be user-implemented.

I get the feeling there's more to Prolog than I was able to unlock - can you recommend any reference materials for beginners?

No experience with Firecracker specifically, but if squashfs images are sufficient, one should be able to build a tar archive of the filesystem without root (where all the files have the correct owners, mode, etc.) and then convert it to squashfs using `tar2sqfs` in https://github.com/AgentD/squashfs-tools-ng, also without root - I've done something like this to create squashfs images in constrained build environments, which worked well.

Location: Remote from US (currently CA)

Remote: Yes

Willing to relocate: No

Technologies: C/C++, Embedded C/C++, Golang, Rust, Bazel, Docker, Postgres

Resume: On request via email

Email: hnjobs *at* scottminor.email

Hey, I'm Scott! I'm a versatile team member, having been a part of both small and large organizations alike. My skillset is diverse and skews towards backend + embedded programming languages and environments, though I have dabbled in frontend projects (Angular on web, Flutter on mobile), build tooling (migrating codebases to Bazel monorepos with custom rules), and deployment (Kubernetes).

I'm looking to transition into remote work so that I can stay clear of the Bay Area traffic post-Covid. Need a hand on interesting projects? Drop me a line via the email above and let's chat!

I'm a fan of consistent behavior, but actually I'm on the side of not sleeping with a display plugged in. Going to sleep when there are no peripherals plugged in is only a sane default because there's no way to actually use the device with no access to the keyboard/mouse/screen.

OTOH, one can still reasonably use a closed laptop if it has a display plugged in, so closing the lid no longer implies an intent to stop using it. Because of this alone, going to sleep in this context might not be the most sane default.

Some examples of when I've personally closed a laptop with the screen plugged in without wanting it to sleep:

* Working at a desk where the laptop doesn't fit with the lid open * Starting a video when connected to a TV in a dark room, where the laptop's screen is a distracting source of light

That's true; inside `hello_i_accept_pointers` there's no syntax at callsites to indicate that a mutable pointer is being passed. However, the variable being passed is of pointer type, which is readily apparent from the context of the function - the pointer parameter is declared in the same file, likely only lines above the callsite in question. This is still better than having to find the declaration of the called function, which is probably in a different file altogether.

the idea that Widget& implies something different about the likelihood of modification compared with Widget* is quite foreign to me. this is precisely what Widget const & is for.

The issue is not ambiguity in the declaration, but rather the callsite: it's rarely possible to tell if a parameter is passed as a value, ref, or const ref at a particular callsite without consulting the function declaration. Oftentimes, one reads code without comparing each function call to its declaration, so it's easy to miss instances where objects are passed around by mutable ref rather than the more common const ref.

Using a pointer for the mutable cases resolves this ambiguity by forcing different syntax to be used at the callsite, which reminds:

* code authors that the parameter they're passing can be modified by the function call (they should think carefully about whether this is desired)

* code readers that a function call is potentially modifying its parameter (which can aid in debugging)

I have some nitpicks with the advice given in the table:

Q1: Yes Q2: - Q3: No Argument: `Widget& widget`

...or `Widget* widget`, which has drawbacks but makes it more clear at the callsite that the argument passed may be modified. The Google style guide prefers this for this reason: https://google.github.io/styleguide/cppguide.html#Reference_...

Q1: No Q2: No Q3: - Argument: `Widget widget`

Q2 IMO should have an addendum to read "Is it expensive to copy a Widget and if not, will it always be cheap" because there is nothing to stop someone from adding to Widget until it crosses the threshold of "expensive", at which point someone needs to go through and update all the callsites to pass by const ref. Widget's copy cost really needs to be part of its API contract before pass-by-value can be allowed.

But this excerpt says that this technique obviates the need for a server process? Are they saving the contents of memory into files using mmap, and then using this state on every run?

A minor note in the article reads:

To minimize I/O and take advantage of operating system caching, csearch uses mmap to map the index into memory and in doing so read directly from the operating system's file cache. This makes csearch run quickly on repeated runs without using a server process.

Does anyone know some resources where I can read more about this technique? (how-to, pros/cons, caveats, etc.) I'm interested in figuring out the best way to have a commandline tool persist state that it can quickly access across multiple runs, but so far a background server process is the only technique I'm familiar with.

Factorio is one of the most stimulating games I've ever played. It forces one to think about not only layout/design of a system but also the project management aspects - which parts to build when, when to take on "technical debt" by building a temporary "good enough" version, etc.

...this is if you don't look up hints/other people's designs, of course.

I used to work for Google - voluntarily left earlier this year. I'm not sure how much I am allowed to disclose about internal tools and processes, so I'll refer you to this article: https://cacm.acm.org/magazines/2016/7/204032-why-google-stor... and call out some parts that you might care about.

The workstation is not connected to the codebase via SSH on a server, but rather the version control clients are remote and mapped into the local filesystem via FUSE. So the workstation is less of a dumb terminal; programs that access the code can run locally, even though the code itself is not stored locally. Therefore, version control clients can be accessed with various web-based tools as well.

Not all developers used a workflow that includes Piper/CitC, but most do. From my limited view, the Piper/CitC workflows were the most painless.

Debugging - I only ever used a debugger for Python, and in those cases the application I was running was local. Otherwise I never used a debugger but rather logging (printf debugging, essentially). I'm of the opinion that if you have to open a debugger to understand the code, you've already lost. Others might have better stories.

Remote machine - as mentioned above, there is no remote machine. Things are done on your workstation. The build commmands can build things locally (slow) or farm them out to a cluster of build machines in datacenters (fast). See https://bazel.build/faq.html#does-bazel-require-a-build-clus...

It may be only tangentially related to the genre, but Factorio has stolen far too many of my hours and is definitely worth the $20. It is engaging and challenging like no other game I've played in the past couple of years.

You can use the keyboard to move your army - moves get queued up as long as they're along friendly territory. Moving into enemy/neutral territory is more time consuming than along friendly, so part of the strategy involves conquering territory strategically to maximize mobility.