HNHacker News
TopNewBestAskShowJobs

sagichmal

2,816 karma · joined April 16, 2014

e1b1ce94085da63902d7c51d8f1e0697
submissionscomments
sagichmal··on Faster CRDTs: An Adventure in Optimization
It would be a little bit strange to build a CRDT system on top of a more traditional data system. CRDTs solve problems at the network layer at enormous cost basically everything else. If you're not using them there, I can't quite understand what they're doing for you?
sagichmal··on Discord Launches Threads
Oh, sorry; I thought you were talking about Slack threads. I can't speak to Discord threads.
sagichmal··on Discord Launches Threads
> If I want to contribute to a prior discussion that happened a few minutes ago but another one is taking place now, then we have two separate conversations in the same linear chat stream.

Yes, this is the essential nature of real-time chat. The channel already serves as the demarcation of topic.

What you're describing is a forum, a totally different modality.

> Direct replies to the messages help but they still exist in that linear main chat stream, so there’s still a lot of clutter that everyone has to navigate through.

This isn't clutter, it's literally the point of the tool.

sagichmal··on Discord Launches Threads
They emphatically are not.
sagichmal··on Discord Launches Threads
Tell me how to (a) identify an interesting thread, (b) view its contents, (c) contribute to it, and (d) return to it after closing the app, without using the mouse.
sagichmal··on Updating the Go Memory Model
> Use `reflect.Value.Select`

Never really a good idea, and never necessary.

> create a single channel owned by the reader

Channels cannot be effectively owned by their reader(s), the contortions you have to bend the code into to make that work never really make sense. That's just a constraint of the type, but it's hardly a problem -- it makes the thing easier to model. So this isn't really an option on the table.

> a Merge function

Yes! The answer. And goroutine per channel is kind of the point of using them! Nothing inefficient about it.

> a function that takes two channels . . .

Now there's some inefficiency! ;) No reason to do this, given Merge.

--

> None of these options are particularly intuitive.

The merge option seems perfectly intuitive to me, assuming you understand channels have to be owned by a singular writer.

sagichmal··on Updating the Go Memory Model
> I still run into deadlocks and panics (writing to a closed channel) when I try to use channels beyond the simplest use cases.

Wild!

The rule is that channels are owned by a single goroutine, who's uniquely responsible for sending on them, and closing them. That's basically it. Do that and everything works fine, in my experience.

sagichmal··on Updating the Go Memory Model
> A channel can be buffered or unbuffered

Yes, with predictable results.

> it can be closed

Yes, by the owner/sender, who then understands it as invalid. The effect of receiving on a closed channel is well-defined and predictable.

> and there's different behavior of [recv/send] whether it's in a select or not

I don't think that's true? What do you mean?

> And you often end up with multiple channels as well

Sure! That's part of their power.

> Reviewing code with channels is often more confusing than code that uses mutexes

I totally agree that goroutines and channels are often over-used by new Go programmers. If what you're trying to do is simply protect concurrent access to some shared state, a mutex is the far better choice.

sagichmal··on Programming Language Memory Models
> GMM violation = UB

This is definitionally correct (shrug)

> Dilettante programmers certainly do not know [that] Go slices, strings, and interface values are unsafely non-atomic.

Yes. They do. As soon as a Go programmer learns that there is such a thing as concurrency and "thread safety" they learn that nothing in Go is "thread safe" by default.

> Go is not memory-safe.

"Memory-safe" is not a precisely defined concept. Go is memory safe by some definitions, not by others.

sagichmal··on Programming Language Memory Models
> They never say or imply something like "if you have a data race, anything can happen [including executing code on the stack]"

They absolutely do.

https://software.intel.com/content/www/us/en/develop/blogs/b...

Violating the memory model gets you undefined behavior.

> However, this does not rebuke my original argument, which assumes that most devs are not in the know. They do not know about slices being unsafe, nor do they know about happens-before

I just don't agree. Go programmers know that nothing is safe for concurrent access unless explicitly noted otherwise. They don't have any confusion about slices requiring synchronization.

Concurrent programming isn't trivial but neither is it impossible. And data races are critical bugs that can be subtle, but are straightforward to identify, and straightforward to fix.

sagichmal··on Programming Language Memory Models
> I have no idea what point you are making. _Of course_ there has to be a bug in the code for there to be a buffer overflow vuln. Or are you objecting that they put contrived code to make the race work better (this is the concept of a PoC)?

The original claim was that "Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption." But that's not the whole picture, you have to violate the memory model, too. And that's not interesting, because if you violate the memory model, literally any consequence is fair game.

Maybe your point is (a) it's easy to violate the memory model, and/or (b) bugs that violate the memory model have surprising consequences? I don't agree with (a); the situation can always be improved, but it's easy to spot and fix data races, and Go provides plenty of tooling for that purpose. And I guess I agree with (b) in the basic sense, but that's just a truism, for the reasons stated above.

sagichmal··on Programming Language Memory Models
Er, your summary does not at all describe what is going on there. Like, all of that code violates the memory model, so whatever it accomplishes is irrelevant.
sagichmal··on Programming Language Memory Models
> Go has lots of weird edge cases, like sharing a slice across threads can lead to memory corruption (in the C / assembly sense, not merely within that array)

Source?

sagichmal··on Stop using your work laptop or phone for personal stuff, because I know you are
this_definitely_happened.txt
sagichmal··on Stop using your work laptop or phone for personal stuff, because I know you are
I know, right ;)
sagichmal··on Stop using your work laptop or phone for personal stuff, because I know you are
That’s fun! Yeah, I buy it, but to the extent it works as a counterargument I’d say it’s actually more of an inevitability.
sagichmal··on Stop using your work laptop or phone for personal stuff, because I know you are
I love my job and I love my life and I deliberately blend them together. This makes me substantially more productive as an employee, and incalculably happier as a human being.

If I want to see a friend in the middle of the day, I do it. If I want to take a 3 hour lunch, I do it. When someone 8 time zones away answers a question I asked earlier at my 1AM, and I’m awake and see it, I’m excited to learn the new whatever thing, and may take an hour (or three!) to chat with them about it.

Everything I do in life I have opted into and enjoy. I gain nothing by firewalling some parts of it from other parts.

I have tried every modality of managing work and personal life and this one is by far —- by far —- the best one for me. The notion that there is a work laptop and a personal laptop and naer the twain shall meet is a complete anachronism. It’s fine if that separation helps other people but it actively hurts me.

sagichmal··on JWT Tokens are NOT safe
> Note that the lightning emoji indicates a blazing fast speed. And the snail emoji indicates slow speed.

This article was embarrassing, and makes Redis Labs look childish and inept. Whatever process resulted in this blog post should be axed immediately, and this author should not be writing anything public facing.

sagichmal··on Medium sees employee exits after CEO publishes ‘culture memo’
Nobody believes this; your comment is embarrassing.
sagichmal··on A new ProtoBuf generator for Go
Depending on workload, Go also does sub-1ms p99 pretty easily. I'm getting sub-1ms p99.9.
sagichmal··on Fly’s Prometheus Metrics
I'm pretty confident that the end result would be simpler in an architectural sense (i.e. fewer components), it would be easier to understand and maintain, and it would behave both more predictably and more reliably.

But these are subjective claims! Not everyone thinks the same way!

sagichmal··on Show HN: We wrote a book about building business applications in Go
> The language authors did not work on large systems.

Um. Alright.

sagichmal··on Fly’s Prometheus Metrics
Oh, sorry, I misunderstood your meaning when you wrote "That pretty much works now?" — I thought it was a question as to whether a more traditional Prom architecture could do it, but I see now you're just saying you already have this set up.
sagichmal··on Fly’s Prometheus Metrics
> That pretty much works now?

Well, with the requisite glue code that would inform each user's Prometheus instance how to scrape the service instances -- yes, more or less.

> is not at all clear to me how doing a purer version of Prometheus would make any of our users happier.

If the only things you care about when you build systems are "works" and "direct impact on customers" then there's not really a point to this conversation. The things I'm speaking about, the architectural soundness of a distributed system, are largely orthogonal to those metrics, at least to the first derivative.

sagichmal··on Show HN: We wrote a book about building business applications in Go
> They're working around a weakness in the language. Stack traces in exceptions are definitely a feature.

OK, I understand this is your position. I don't share it, nor do the authors of the language. So I guess it's not a truism.

sagichmal··on Show HN: We wrote a book about building business applications in Go
> Most languages that I know of have mature DI solutions, and those are needed for writing any non-trivial app.

Patently false.

> Also, one of said frameworks I was referring to generates mocks for your app and wraps errors so you automatically get stack traces in errors that are being passed around. Something already solved in Java and C# and practically any language with exceptions.

You're speaking as if generating mocks and adding stack traces to errors are... features? They're not! Generating mocks almost totally defeats the purpose of using them, and stack traces have no business being attached to errors in the general case.

Sometimes I truly don't understand the context that my peers are working in. Totally incoherent...

sagichmal··on Fly’s Prometheus Metrics
> I think you're reading a critique of Prometheus that isn't really present in what we're writing.

I'm observing that you've used pull-based, horizontally-scaled tools to build a push-based, vertically-scaled telemetry infrastructure. It can be made to work, sure, but the solution is an impedance mismatch to the problem.

sagichmal··on Show HN: We wrote a book about building business applications in Go
> Take a look at the major DI frameworks for Go, Wire [0] and FX [1]

I'm well aware of them. (There are several more, too, which see at least as much use as these two, unfortunately.) They also reflect a misunderstanding of the language. Wire less so than FX. (I'm also aware Wire is written by Googlers, no need to point that out.)

> Prior to DI frameworks we used global variables, often initialized in a package's init() method.

I don't understand how these things are related. DI frameworks aren't necessary for Go-idiomatic dependency injection, and global variables were never an appropriate way to manage dependencies.

> Generally you have a few layers: gRPC/HTTP/Kafka handler, business logic, and database or external service access.

Yes!

> Layers are unit tested individually against mocks of the layers below.

Yes!

> Because you're going to inject a mock, you can't depend on a concrete type, so you depend on an interface.

Yes!

> Often when you're developing you want to know what the concrete implementation of a lower layer does, so it's useful to have "go-to-definition" see through the interface declaration to its implementations.

...no?

There are basically two situations where you use an interface in this way. One, most often, in an application where the "production" code uses one implementation, which you know a priori and therefore have no need to go spelunking. Or, two, in a library where you by definition cannot know what implementation your users will provide to you. In the first case, your mock would model the implementation, which I guess is trivial. In the second case, your mock would reflect your expectations of the interface's implementations, explicitly without knowledge of any implementation.

sagichmal··on Fly’s Prometheus Metrics
> Our physical hosts have hundreds of services exporting metrics. And many of those exported metrics are from untrusted sources. So we can both rewrite labels and decrease the scrape endpoint discoverability problem by aggregating them in one place.

OK, but Prometheus can do all of this just fine?

> Because it works incredibly well, it's easy to operate, and handles multi tenancy for us.

Again, Prometheus itself ticks all of these boxes, too, if you're not trying to force it to be something it's not.

sagichmal··on Show HN: We wrote a book about building business applications in Go
> I worked at an employer who heavily used golang ... they ended up reinventing the wheel on so many different things, including DI and an entire application framework.

Sounds like they were trying to force the language to be something it's not. DI frameworks (I think what you mean) are basically incoherent in Go, dependency injection is naturally modeled with interfaces. In fact any inversion-of-control style "framework" is a mismatch to the language, it (intentionally) lacks the features that frameworks rely on to deliver benefits that outweigh their costs.

> The way interfaces are handled in golang makes it very annoying to try to find out which types implement said interface.

The desire to do this reflects a misunderstanding of interfaces.

← PreviousPage 3 of 34Next →