HNHacker News
TopNewBestAskShowJobs

sa46

1,425 karma · joined December 2, 2015

Building AI for distributors, contractors, and manufacturers.

Paratrooper to programmer.

http://github.com/jschaf

hn@schafer.dev

submissionscomments
sa46··on An Amazon programmer’s perspective (2015)
In the military, we had a 2 hour recall for a large chunk of our battalion, about 200 people for a few months at a time. If you got a call, you were expected to be ready to go in less than 2 hours. Social norms meant the expectation was closer to 45 minutes than 2 hours.

I think oncall is a common requirement for anything involving large sums of money, treatment of high risk injuries, or geopolitical power struggles.

sa46··on What every software engineer should know about Apache Kafka
Do you have any advice for setting up a test Kafka environment? I'd love to be able setup a lightweight in-memory Kafka for unit-y tests without going through the whole Docker compose rigamarole.
sa46··on I deploy, therefore I am
A programmer will fight long and hard for a bit of colored ribbon.

- Napoleon

sa46··on Every software system used at Gitlab
Interesting, I’ve only went through the effort of checking out a pull request for review a couple times. What’s the workflow like? Any tips for reducing friction? I avoid checking out PRs because it’s much higher friction and because I trust CI to catch most bugs so the crappy code forge interfaces are good enough.

Personally, I would kill for a one click to step review interface in IntelliJ that synced comments back to the review.

sa46··on Pentagon official: FCC decision on 5G threatens GPS, national security
You might like Ghost Fleet [1] (or [2] for more colorful review). Ghost Fleet is essentially a white paper turned into a Tom Clancy style techno-thriller on what war might look like between China and the United States. Tactics from Ghost Fleet include:

- Infected microchips from Chinese suppliers used to target and destroy the US Pacific fleet.

- Disabling GPS with anti-satellite missiles.

- Cyber attacks to disrupt the DOD communications networks.

[1]: https://en.wikipedia.org/wiki/Ghost_Fleet_(novel)

[2]: https://morningconsult.com/2015/09/08/the-defense-wonks-who-...

sa46··on The Safety Boat: Kubernetes and Rust
I wasn't sure. After a bit of research, this seems to be a debate [1]. Using the common definitions, it's possible to have a data race that doesn't cause a race condition. [2] It's also possible to have a race condition without a data race.

[1] https://en.wikipedia.org/wiki/Race_condition#Data_race

[2] https://blog.regehr.org/archives/490

sa46··on Distributed transactions are not microservices
> Don’t try to build two-phase commit, instead go for an arbitrator pattern which essentially supports resiliency, retry, error handling, timeout handling, and rollback.

What’s the arbitrator pattern? Google failed me.

sa46··on Show HN: Errorship, use datadog as an error tracker
I’m going to make the classic engineer mistake and assume that it’s almost as easy to implement this myself. My understanding is that errorship does something like:

- register a global exception handler, probably tweaked to hook into framework specific exception mechanisms.

- make the exceptions “pretty”

- send the exceptions to the datadog event log.

The benefits of rolling my own is avoiding a soft dependency on errorship and that I can tweak exception aggregation and reporting. Is the primary defense that errorship only costs $10 per month or is there additional complexity I’ve missed?

sa46··on Show HN: Errorship, use datadog as an error tracker
This looks like an admittedly clever hack to avoid the fantastically expensive APM and still get some useful exception logging. I really wanted to use Datadog’s APM but $31 per host was too much. The downsides to logging to the event stream like Errorship is that you can’t associate exceptions with requests and aggregation is limited to tags. I think event tags have a low-ish cardinality limit similar to metrics.
sa46··on Google to Slow Hiring for Rest of 2020
I'd like to see an org-chart depth analysis for different organizations. It'd be interesting to map bureaucratic processes to the structure of an org chart and verify Conway's law.

The U.S. Army uses the concept of a span of control that dictates each level of hierarchy should have between 2 and 5 reports. There's about 10 levels between a private and the secretary of the army. The Active Duty Army is about 470k which works out to 3.7 reports per level from 470000^(1/10). There's about 1M total personnel which works out to 3.9 reports per level.

Google has 114k employees. With your ideal of 7, that works out to 5.3 reports per level given by 114000^(1/7). I'd be pretty surprised if there's a depth of 12 at Google. That's 2.6 reports per level.

sa46··on Comparing the new Redis6 multithreaded I/O to Elasticache and KeyDB
The post covers all the points you mention. The benchmark only covers Redis forks so it doesn’t get a whole lot more apples-to-apples than this.

> So there are 3 offerings by 3 companies, all compatible with eachother and based off open source Redis: Elasticache is offered as an optimized service offering of Redis; RedisLabs and Redis providing a core product and monetized offering, and KeyDB which remains a fast cutting edge (open source) superset of Redis. This blog looks specifically at performance, however there is a section at the end of this blog that also outlines other key differences.

The last paragraphs give a good overview of the differences.

sa46··on Why Vertica Customers Adopt Apache Druid for Real-Time Analytics
The Procella[1] paper took a different approach to experiments. They embedded an experiment ID array in table rows and indexed the rows by experiment ID with a postings list.

Replex looks really neat. I've only skimmed the Acolyer summary so far. What's the difference between a replex and multiple projections of data with different partitions and sort-orders used in C-store and Vertica?

[1]: http://www.vldb.org/pvldb/vol12/p2022-chattopadhyay.pdf

sa46··on On Killing Tanks
I served in a light-infantry battalion, specifically in our heavy-weapons company. Most of the doctrine is available publicly. For a heavy weapons company, see Appendix D of https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN6672...

Going against tanks as an infantry unit is a tough spot. Tanks are significantly faster, more lethal, and harder to kill than any light-infantry unit. In a defense, light infantry uses engagement area development to attempt to even the odds. Engagement area development is similar to building a defense in depth. A quick summary:

0. Analyze the enemy composition and disposition to determine likely avenues of approach. After that, build your engagement areas on those approaches.

1. When the enemy is far away, attempt to disrupt or turn their movement into the engagement area. This is typically a combination of scouts, artillery, or obstacles to channel the enemy into the engagement area.

2. Once the enemy is in the engagement area, keep them there (fix) as long as possible. Use priority targets and sectors of fire to efficiently concentrate fires on the most valuable targets which almost certainly includes tanks.

3. Finally, you block the enemy with obstacles to move to secondary positions.

The author's first tactic of a trial shot of engaging at range is part of step 1. The goal is to force the enemy to change their movement, slow them down, or disable the active protection measures. This is a bit more difficult with a TOW missile than with a Javelin. Modern tanks will auto-rotate if you laser range find them directly. Since a tank round travels significantly faster than a TOW missile, a tank can kill you before the TOW missile reaches them. Since a TOW is guided by an operator via a wire, the missle with then miss.

The second tactic of multiple missiles would go in step 2. To avoid firing excessive missiles at targets, one technique is to "shard" the engagement area so subordinate units are responsible for parts of it.

The third tactic of using grenade launchers and mortars is questionable. We were taught that tanks are basically invulnerable to indirect fire (mortars and artillery). I don't think a 60mm mortar would have any significant effect on a tank unless you score a direct hit. The precision on indirect fire isn't good enough to directly hit a tank. Hoping to trigger the tank's active defense measure is a long shot. Also, if you're using a M320 grenade launcher with a max effective range of 320m against a tank, you're going to die soon unless you have some other significant advantage like urban terrain. The MK19 automatic grenade launcher is a much better weapon for trying to prematurely damage the tank's defense with a range of 1500m.

sa46··on Show HN: RudderStack, open-source CDI (a.k.a. open-source Segment)
How does the AGPL license interact with the enterprise plan? If a company pays for the cloud version that rudder hosts, is that company obligated by the provisions of the AGPL?
sa46··on Chelsea Manning ordered to be released [pdf]
The rights are not necessarily waived but are subordinate to military regulations (UCMJ) in order to promote "good order and discipline". Discipline is a critical factor in the effectiveness of military units. The courts have typically trusted rulings of military courts since civilian courts are not necessarily well equipped to understand how a ruling would impact the military.

Here's a good overview of the context for limiting the rights of military personnel: https://mtsu.edu/first-amendment/article/1131/military-perso...

sa46··on New Features in Java 14
I don't understand what you mean by provably. The Java example does the exact same thing as the JS version: create a shallow clone with a different age. Do you mean the builder might do something different?

    // Java
    val emily2 = emily1.toBuilder().age(30).build()
As far as adding the spread operator to Java, I think you'd have to require a Spreadable interface to use it or limit usage of the spread operators to records. It's not clear to me that the expressive power is worth it over a builder.
sa46··on Where Sci-Hub Is
I don't follow your argument: "information creation is compensated prior to the information being given away for free." You can't give something away for free by requiring compensation beforehand.
sa46··on Yglu: YAML augmented with an expression language
I despise YAML but like Markdown. They serve different purposes. Markdown is a light-weight way to format prose. YAML is a config language. Markdown is pretty good at formatting prose. YAML is a disaster confusing syntax unsuitable for configs past about 100 lines.

We have a 1500 line YAML file for our test config because YAML is the one true method for setting up tests. The issues I've run into:

- Indentation errors. Luckily CircleCI has a YAML validator, but the fact that a validator is required isn't great.

- true, false, yes, no. Why?

- date and number coercion vs strings.

- YAML has aliases which in theory let you reuse config. Except you can't compose aliases, like have JavaTest inherit config from GitHubReporter and SlackReporter.

My view is that complex configs should be generated from a reproducible binary, preferable in a real programming language with loops, conditionals, and some form of easy composition. Dhall, jsonnet [2], or Cue [3] are all interesting languages in this space.

[1]: https://dhall-lang.org/ [2]: https://jsonnet.org/ [3]: https://news.ycombinator.com/item?id=20362951

sa46··on Alpine makes Python Docker builds slower, and images larger
It's certainly not an exaggeration:

Docker with a few idle containers will burn 100% of CPU. https://stackoverflow.com/questions/58277794/diagnosing-high...

Here's the main bug on Docker for Mac consuming excessive CPU. https://github.com/docker/for-mac/issues/3499

sa46··on Proposals for Go 1.15
I don't think NPM is an example of a good dependency management system. It works, but it doesn't spark joy. Some issues I've run into:

- npm install ignores package-lock.json and uses package.json. The work-around is to use npm ci. https://stackoverflow.com/a/45566871/30900

- Flakiness. An acceptable solution to npm difficulties is `rm -rf node_modules; npm i`. Admittedly, this has improved a lot in recent years.

NPM also inherits the design preferences of the JS ecosystem.

- Simple packages have deep dependency graphs.

- Functionality is spread across multiple packages, sometimes at a granularity of a function per package.

- If you want types, you roughly double the number of packages you need.

sa46··on Umbra: an ACID-compliant database built for in-memory analytics speed
I manage about a petabyte of data using a Citus as the distributed query engine on top of Postgres nodes. It’s nice because you can query with Postgres but there’s a decent number of sharp edges at scale.
sa46··on IntelliJ IDEA 2020.1 EAP is open
I adore IntelliJ. Some neat features I've discovered recently.

- Structural replace is sed with ASTs. It's really cool. https://www.jetbrains.com/help/idea/structural-search-and-re...

- Task tracking to report how long you spend on a task. This is nice to see how far off the estimate was and include integration with Jira.

- The database extension (datagrip) is awesome for figuring out Database structure and building queries with auto-complete.

I'm looking forward to performance improvements. I get bouts of ~150ms typing latency which are not fun.

sa46··on Rob Pike on good commit messages (2014)
Interestingly, in the 3rd post in the submission, Pike specifically avoids mandating a style guide.

> I would rather not turn this into rules and style guides, just a widespread understanding that a changelist description is worth taking some time to write.

sa46··on Kotlin vs. Java
I've inherited a large scale codebase and it's been interesting to put it mildly. I agree with GP that Scala's power lends itself to building unnecessarily complex systems.

- Scala has a lot of cool, but sometimes confusing features. Implicits, companion classes, apply/unapply.

- our compile times are 5-10 minutes in CI. I'm sure we can make it go faster, but it requires digging into a 500 line SBT file.

- Scala seems to encourage building tangled webs of actors with Akka. I understand the benefits of actors. I think the benefits are overstated vs threads when you need less than 10k threads or so.

sa46··on Facebook fired an employee who was paid bribes to reactivate banned ad accounts
> simply having a requirement that several independent people

You're asking for government mandated bureaucracy. Here's how I've seen this play out in the context of the world's largest bureaucracy, the Department of Defense.

Let's say the law requires someone in a powerful position, like a VP, to approve the un-ban request so you can hold someone "accountable". The following chain of events will occur:

1. The VP will be inundated with un-ban requests and become increasingly annoyed at requests that should obviously remain in effect.

2. The VP will delegate a subordinate to check that each request is sufficiently nuanced to require the full attention of the VP.

3. Repeat steps 1 and 2 until you reach a management level that's too over-burdened to add another review layer. You should have 2-4 layers of review at this point.

To properly route a request, each layer queues the request and runs some cheap processing and sends it up the chain where the process repeats. We can borrow some concepts from networking to model this process:

- buffer bloat: queues are typically unbounded in the real world. Requests are rarely dropped. Instead they accumulate.

- back pressure: the VP goes on vacation. All requests will pile up at the previous layer.

- latency: certain days have exceptionally high latency, notably Saturday, Sunday, and most parts of Friday.

- network partitions: often the transport layer (usually an intern to shuffle paperwork) will become unavailable as the scheduler (boss) repurposes the intern to higher priority tasks.

With a bit of tuning, a well-established bureaucracy can increase latency from minutes to months per request.

sa46··on Statically-typed error handling in Python using Mypy
> Type system's of typescript [...] are far better than type systems [than java]

TypeScript's type system is far more powerful than Java's but I'm not sure that's a good thing. A lot of the concepts in TypeScript are necessary to paper over gratuitously dynamic APIs in JavaScript.

While Java certainly has warts in its type system (no generics over primitives, arrays), Java's type system straight-forward compared to TypeScript. TypeScript stuffs a staggering amount of functionality into the type system. To name a few of the more esoteric features: literal types, const assertions, asserts modifier for type predicates.

sa46··on Advent of Code 2019
Those box plots use horizontal jitter within individual boxes to better show overlapping points. That's a neat technique I haven't seen before.
sa46··on DuckDuckGo Search Improvements
> Google actually honors that for you?

It works exactly as expected. If you want an exact match you need to quote the search terms.

    "Kubuntu" OR "KDE" -gnome site:ubuntuforums.com
sa46··on How we failed, then succeeded, at migrating to TypeScript
> How easy it is to digest

I’ve not had this experience. I’ve found the ambiguity in coffeescript a maddening adventure in syntax confusion.

- function call syntax doesn’t need parens except if a 0 parameter method

- commas are largely optional both in arrays and function parameters. How do you parse: [f, f(), f a b c]

- implicit returns are a terrible idea.

- the @ syntax refers to either a ‘static’ method or an instance variable depending on the context.

- I have to do a double take for the object literal syntax every time

sa46··on Working with GitHub Actions
I've recently dumped a lot of time into making our CircleCI pipeline faster. I'd love to hear why you switched to BuildKite because we're looking at doing the same thing. My understanding is BuildKite has the following advantages:

- You can have persistent workers since the build machines run in your cluster.

- Much better Docker layer cache hit rates. We use custom Docker images and I've never seen a Docker image cache hit on our CircleCI machines.

- Better download throughput. CircleCI appears to be bandwidth limited to about 15MB per second.

- It's much more straight-forward to programmatically generate workflows instead of hard-coding them in multi-thousand line YAML file.

Some of low-hanging optimizations on CircleCI I've used to reduce build time are:

- Using a shallow git checkout. Reduced checkout time of our 500MB repo from 30 seconds to 2 seconds.

- save_cache into /dev/shm. This cut our 1GB node_modules (yea, it's huge I know) save_cache and restore_cache from 30 seconds to 10 seconds. The HUGE downside is /dev/shm is mounted as noexec so you can't run anything in node_modules/.bin without some hacks.

← PreviousPage 12 of 15Next →