HNHacker News
TopNewBestAskShowJobs

cakoose

1,103 karma · joined August 22, 2011

Work: https://anrok.com

[ my public key: https://keybase.io/cakoose; my proof: https://keybase.io/cakoose/sigs/gNz7dqjDBzs5anzP30jhCtr5bcogtlGjKLP2yghDN9I ]

submissionscomments
cakoose··on 120K distributed consistent writes per second with Calvin
Is the wire format roughly isomorphic to the structure above? Or does the Scala library convert this code-like structure into something simpler/flatter?

(BTW, would be nice if I could read your API docs without signing up for an account.)

cakoose··on Cloudflare and FastMail: Your info is safe
Just to be fair, this is an instance of pro-actively communicating good(ish) news. Not everyone does this, so of course it's good to encourage more of it, but it's much easier than pro-actively communicating bad news.
cakoose··on 120K distributed consistent writes per second with Calvin
How would you perform the classic "transfer money from one account to another" operation?

Would you create a single operation that reads one record, checks that it's enough, then adds the amount to another record?

Or maybe you'd first read both accounts, then issue a conditional write operation that makes sure the data hasn't changed before doing the write?

cakoose··on Using Immutable Caching to Speed Up the Web
Oh, interesting. Is that the only difference?

How often people actually do a hard refresh? I would guess most people don't know about that key combination.

cakoose··on Rust vs. Go
> As an aside, if ESR couldn't get Rust's ownership model, I wonder how long it took him to internalize how not to write memory bugs in C?

Rust's type system, like any type system, is limited. It enforces a certain style of safe programming and will reject other styles of safe programming.

The compiler is also not great at explaining why something is wrong. I'm not knocking the compiler writers, because it's a hard problem and they're putting serious effort into it. But from ESR's perspective, he's writing code that is safe (according to a style he's developed over decades of programming) only to have it rejected with an explanation that doesn't make sense. It's frustrating.

There are ways to improve the learning experience. You can improve documentation, improve compiler error messages, and improve the type system itself (e.g. non-lexical lifetimes). The Rust team appears to be taking all of these seriously.

I think the people who make it past the initial frustration are those who believe that it will be worth it. I'm a huge fan of type safety guarantees. I've also followed the development of Rust enough to know that the people making decisions are good at designing languages. So when I'm frustrated, I remind myself that this is probably all worth it.

But reading ESR's write-up, he's clearly not coming from the same place. He believes that Go and Rust both have "strong type systems", which is clearly false. He complains about Rust exposing an unsafe construct like mutexes without realizing that Rust mutexes are much safer than in C. But to be fair, he's also thinking about a specific project that needs an efficient epoll-style mechanism and Rust is just not there quite yet.

cakoose··on Ask HN: What manual processes would you automate in your company?
I'm not against remote work, but one thing I notice is that it's more efficient to hash out ideas with someone in person.

Why do you categorically say that something is broken if it requires personal presence?

cakoose··on Goroutines, Nonblocking I/O, and Memory Usage
Provisioning for the worst possible case is sometimes necessary (e.g. hard real-time use cases), but can also be very expensive.

Since HTTP connections are typically kept alive between requests, it's very common for them to be idle. It could be the case that 99.9% of the time, X bytes of memory is enough to avoid transfer delays, but to cover the 100% case, you'd need 10X that.

I think it's reasonable to decide that avoiding delays in the 100% case is not worth 10X the cost in memory.

cakoose··on Transitioning Firefox's rendering engine from Gecko to Servo
And the analogy is a bad one, too. I think it's trying to make the task sound more difficult than it is.

If we stick with the airplane analogy, maybe this is better: it's like incrementally converting an older model jet engine to a newer model jet engine in between flights. Every incremental version must work correctly, which isn't easy, but the upgrades are definitely performed on the ground.

cakoose··on Git 2.11 has been released
More importantly, the comparison is useless. The odds of running into issues with SHA-1 collisions in Git is a very different question from just the odds of two random SHA-1 hashes colliding.
cakoose··on Announcing TypeScript 2.0
> I'll never join a company that uses TypeScript unless I get to see the code base first.

That seems reasonable. But wouldn't the same thing apply to Javascript? Terrible Javascript code bases are very common.

cakoose··on Having fun with Go's nil, interfaces and errors
Sometimes you try and make one feature work a certain way and that decision has unintended consequences. Most languages have surprises like this.

In this case, it's an implicit conversion from "nil" to the "nil value" of a given type. This is convenient in many cases, but causes confusion in other cases.

cakoose··on Scalable and secure access with SSH
> We do not place SSH certificates on laptops because it is difficult to control everything that individual employees run on them. Even though they are centrally managed, laptops are more prone to vulnerabilities than the bastion servers. Therefore, we do not trust them with SSH private keys.

If the laptop doesn't have an SSH private key, how do you SSH to the bastion host?

> In your .ssh/ directory, you'll see id_ecdsa and id_ecdsa.pub. Copy the latter to the CA server and get it signed. Because this is public information, the transport isn't important. You can copy and paste, or fax it; just don't copy id_ecdsa anywhere.

The transfer of id_ecdsa.pub doesn't need secrecy, but it does need integrity. You don't want to accidentally sign an attacker's public key.

cakoose··on DDoSCoin: Cryptocurrency with malicious proof of work
A primary feature of OTR-style communication protocols is deniable authentication. If Alice and Bob communicate via OTR, Alice can't can prove (cryptographically) to anyone else that the messages she received were actually from Bob.

Would an OTR-style protocol be immune any type of DOS proof-of-work? Are there disadvantages to having deniable authentication for the kinds of communication that TLS is used for today?

Edit: according to the paper, the attack only works on TLS 1.2+, and only works on the setup phase. Apparently, TLS allows you to forge the contents of the communication. Does OTR allow you to forge the setup phase as well?

cakoose··on Announcing TypeScript 2.0 Beta
The fact that the flag is global could actually slow down adoption of the new type system.

Let's say I want to use the new type system, but some library I depend on hasn't been updated. If I enable the new type system, I'll get both false positives and negatives when type checking.

If a library writer updated to the new type system, they'd break compatibility with callers that haven't updated. The safest option would be to maintain two almost-identical copies of the library -- one for the old type system and one for the new one.

A better option would be to allow specifying the type system mode at the top of each file (like "use strict"). This allows me to use the new type system even if not all my libraries have updated yet. This also allows libraries writers to use the new type system features without breaking existing users.

cakoose··on Goa: Design-First API Generation
Both Swagger and Goa can generate API client code from their respective spec languages. Goa additionally has the ability to generate a Swagger spec from a Goa spec.

This makes me wonder why Goa just doesn't rely on the Swagger code generators? Are they not very good?

The Goa page talks about generating Swagger so you can use the Swagger doc generator. Maybe that's the only part of Swagger that the Goa developers think is useful?

Also, Swagger has more traction right now. Maybe the ability to generate a Swagger spec lets people not feel so locked in to Goa, the newcomer?

cakoose··on WireGuard: next generation in-kernel modern VPN
This comment was marked 'dead', but I think it was a useful question (though maybe a little aggressive in its wording):

> So what's the point ? Linux is a niche market. Mac & Windows will be the vast majority of your users and won't enjoy your killer kernel-based feature...

Even when Windows/Mac are the vast majority of clients, each client only needs to process its own traffic. The VPN gateway is more likely the bottleneck, since it needs to process everyone's traffic. There are many organizations that would have no problem running Linux on the VPN gateway and could reap the benefits.

Also, the Linux in-kernel implementation is just the first(?) thing being released. WireGuard is a VPN protocol and its killer feature is good security that's simple enough to implement in 4000 lines of code. This simplicity makes it easier for someone to write a Windows/Mac kernel driver.

cakoose··on WireGuard: next generation in-kernel modern VPN
(I don't know much about networking.)

What are the advantages of doing UDP instead of IP?

It seems like, all else being equal, doing IP has the advantage of working with UDP and TCP out of the box.

cakoose··on Iris: Fast back-end web framework for Go
Right. But just to be clear, C++ was an implementation detail. You could treat the entire toolchain as a black box that read in PHP code and produced a single executable binary.
cakoose··on The Cloned-Consciousness-as-Continuous-Consciousness Fallacy
I think the fact that the original is kept around (and asked a question) might be complicating things.

For example, what if you were taken apart, your molecules were sent to Mars, and then you were reassembled exactly as they were? Would that be continuous consciousness?

If so, how is that different from the cloning option if your clone were assembled on Mars and the original were completely destroyed at the very same instant? (Or maybe the original were destroyed just an instant earlier.)

cakoose··on Iris: Fast back-end web framework for Go
There are two things here -- how fast can a language be in theory vs how fast a particular implementation is.

Interpreters are typically slower (though simple to write and portable). The standard Python/Ruby/PHP implementations are interpreters. (The Python interpreter doesn't interpret from source every time, though; it usually uses the bytecode from previous runs.)

Implementations that generate machine code are more complicated and less portable, but have the potential to be faster. However, while compiling "down to machine code directly" can help startup time, it has little to do with what allows a language to be fast. What matters is whether it's possible to generate efficient machine code.

Static typing, for example, allows a compiler (ahead-of-time or JIT/VM) to generate more efficient machine code [1]. The ability to monkey-patch code -- which is common in many dynamic languages -- makes things harder for a compiler.

That said, there are compilation techniques to make dynamic languages pretty fast -- much faster than the standard Python/Ruby/PHP interpreters. For example, Javascript VMs have gotten 10x (or more?) faster over the last 5 years. (One of the big ideas: <https://en.wikipedia.org/wiki/Inline_caching>.)

A great example of all this is Facebook's PHP compiler. The first version would compile to machine code ahead-of-time, but it wasn't that much faster than the standard PHP interpreter (and definitely slower than the Firefox/Chrome Javascript VMs). They eventually switched to a JIT compiler, which is a better strategy for a dynamic language. Later, they transitioned to statically-typed sorta-PHP-compatible language called Hack, which allows for even more efficient machine code.

[1] There are different levels of static typing, too. For example, Go is statically typed but doesn't have generics. A C# generic data structure can be converted to more efficient code than a Go "interface{}"-based data structure.

cakoose··on Spectre.css – a lightweight, responsive and modern CSS framework
I think "responsive" is a useful modifier (even though most CSS frameworks nowadays are responsive).

"Light" is definitely relative but at least they list the exact size pretty early on.

"Modern", however, is something everybody seems to use to describe their programming framework/library and it's useless. Think about it this way: if you removed the word "modern", what information have you lost?

cakoose··on Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're fixing it
Two things: 1. Why not just add client-side certificates to an OAuth-based API? 2. Client certificates do not prevent an attacker from pretending to the be server.

Let's say your API server followed the standard OAuth 2.0 protocol except required client-side certificates? Would that be as secure as TAuth?

If so, then the OAuth 2.0 option has the advantage of being well-supported by existing libraries and well-understood from a security perspective. It's less likely that a previously-unknown issue with OAuth 2.0 will crop up and force everyone to scramble for a fix.

And while client certificates prevent an attacker from forging client requests (i.e. tricking the API server) an attacker can still trick the client. An attacker capable of MITM'ing server-cert-only HTTPS can also trick TAuth clients into sending it's banking API requests the attacker's servers. It can respond to those requests with whatever it wants.

To summon the activation energy to adopt (or switch to) a new, less-popular protocol, I'd expect more security benefits.

cakoose··on Introducing TAuth: Why OAuth 2.0 is bad for banking APIs and how we're fixing it
oAuth 1.0 supports both PLAINTEXT and HMAC-based signature schemes. I assume the article is assuming HMAC-based signatures (the PLAINTEXT option seems to be less well-known). With an HMAC-based signature, the token will not be leaked.

But you're correct that eavesdropping is possible.

cakoose··on Swift 2.2 Released
> For example, in Java you can't write a generic method that instantiates an object based on the type of the generic. The workaround is typically to pass in the Class type as an additional parameter to the method, which in theory should not be necessary.

If a method needs to instantiate an object, the normal technique is to accept a factory function as a parameter. You can do the same thing with type-erased generics.

C# decided to create a shortcut for calling the constructor of a generic type parameter. But, for example, you can't call static methods of a generic type parameter (and a constructor is really just a slightly special static method).

cakoose··on How Badoo Saved $1M Switching to PHP7
"Given [a well-designed/balanced system], the processing power of the application cluster is arguably the most important factor."

That doesn't follow. You can have a well-designed system where the PHP code only contributes 10% latency and resource usage, in which case the PHP code is clearly not the most important factor.

"This might just indicate you better have 25 app servers vs 100 databases and spend the rest of money proportionally on both clusters."

Exactly. What matters is proportion of latency or resource usage contributed by the PHP code, and that can vary a lot between well-designed systems. The property of being "balanced" doesn't automatically make your PHP application cluster "the most important factor".

cakoose··on Protonet: secure, private, and beautiful cloud servers
What's if the device's local storage experiences hardware failure?

1. Can you configure it to make backups?

2. Can you configure it to replace data with low latency?

3. If you have multiple, can they work together to increase availability or data durability?

cakoose··on How we built Facebook Lite for every Android phone and network
Maybe it was a typo and they meant "minutes" instead of "seconds"? Later in the article they say:

> Downloading a typical app with 20 MB APK can take more than 30 minutes on a 2G network

Then again overstating accomplishments is pretty standard for tech blog posts.

cakoose··on Swift Protocols and the Promised Land
A lot of the generics/covariance complaints seem to be rooted in a misunderstanding of covariance.

  class Fruit {}
  class Peach: Fruit {}

  protocol FruitHolder {
      var fruits: [Fruit] { get }
  }

  class PeachBasket: FruitHolder {
      var fruits: [Peach] = []
  }
This doesn't compile because it is not type-safe. Even though "Peach" is a subtype of "Fruit", "[Peach]" is not a subtype of "[Fruit]".

If the above code were allowed, we could circumvent the type system:

  var h: FruitHolder = PeachBasket();
  var fruits = h.fruits;
  fruits.append(Fruit());
I just added a non-Peach to a "PeachBasket". When someone iterates through it later, expecting it to be all "Peach" instances, they're going to be surprised.

This reminds me of when Java 1.5 introduced generics. People were used to arrays being covariant even though that's not type-safe. The language designers decided not to carry that particular type system loophole over to generics, and people (including me) were surprised by the new behavior. (And then once we wrapped our heads around it, even more surprised we had never noticed the issue before!)

Objective-C had a bunch of holes in the type system and people got used to them. Swift is trying to be more type-safe. Interestingly, Dart made the conscious decision to retain this particular type system hole; their generics are always covariant.

BTW, Java's "wildcards" (existential types) get you roughly what you want in a type-safe way:

  protocol FruitHolder {
      var fruits: [? : Fruit] { get }
  }
This roughly means that "fruits" is an array of some subtype "Fruit", but it might not necessarily be "Fruit". Then, doing "fruits.append(Fruit())" would fail to compile but you could still read from the array.
cakoose··on Writing Cloud Functions
I don't think "not getting a server" is enough justification. With Gmail I don't get a server, but nobody calls it "serverless email". A server is still involved.

It seems like an ill-fitting adjective even in a vacuum, but what's worse is that "serverless" is commonly used to describe something that runs entirely client-side (e.g. p2p).

Just because AWS Lambda is a "mental shift" doesn't mean that "serverless" is a good way to describe it.

cakoose··on Facebook is closing Parse
I have no knowledge of what happened at Parse but based on other experiences I've had, a "sudden" shutdown could be a sign of things being done correctly.

Too often, products are in an extended state of limbo. Internally, the company has given up on it but has been dragging its feet on making the decision to shut it down (or just slow about making the decision public).

As a user, I like to know ASAP if a product I use is probably being killed.

From the company's perspective, keeping a product around half-assedly will probably lead to a slow death anyway; just kill it quickly.

← PreviousPage 7 of 8Next →