Hacker Newsnew | past | comments | ask | show | jobs | submit | deepsun's commentslogin

Every formal verification depends highly on requirements. It's pretty easy to make a mistake in defining the task itself. In the end, you'd want to verify system behavior in real world, and it's impossible to completely define real world. You always make some assumptions/models to reason within, and it impossible to verify the assumptions are correct.

If Flock collects and processes PII data, then all their customers are "subprocessors". Flock should really have a Data Processing Agreement with their subprocessors, to legally ensure they follow the same PII handling controls as Flock does.

For example, if Flock receives a legitimate request to delete some data, then Flock must forward that request to all their Data Processors (e.g. including AWS/GCP/Cloudflare) and they must delete it as well.


It’s the other way around. Flock is the subprocessor for whoever hired them to collect data. If they are collecting data on behalf a city or municipality, those are the entities you need to address.

I'm not sure about that, I'm pretty sure any company that has your PII is obliged to follow the law, regardless of their contracts with their customers/vendors. Law doesn't make you investigate who's the end customer for your data, only who has it.

As for "subprocessor" -- it might as well be the case that both sides are subprocessors for each other, nothing wrong with that.


I don’t know this specific law, I just know how it works in the EU with the GDPR. Of course any company that has your PII has to follow the law, but it matters which entity is the one that has is the end customer for your data. They are the one that has to have a legal basis for even collecting that data and they are the one you as a use deal with. If they use a sub-contractor then that’s an internal matter for them and not something you as the subject has to deal with. Of course they have to have a DPA in place with the sub-contractor and they have the responsibility to make sure the sub-contractor follows the law. Likewise the sub-contractor has to make sure that their client has a sound legal basis for processing the PII.

For example: if a bank outsources part of their KYC process to a third party, that’s not something you have to concern yourself with, you only deal with the bank.


All true, but if the third party receives a delete request from you, they have to oblige (and may notify the bank). Otherwise it would be very easy to circumvent the law by saying "oh we're just keeping it for another customer, we're going to send it to them next year maybe". And that customer will say they need it for another customer etc.

Privacy law (in your case GDPR) does not concern with who's customer. If a company processes PII -- they are subject to the privacy laws.


Then why nobody forked minio?

Maybe nobody wants to spend effort maintaining it? I imagine it's simpler to build your own S3 alternative than maintain minio. Also nobody wants to test AGPL liability in court: https://www.reddit.com/r/minio/comments/1fnuv46/does_interac...

For me it went into the multi-node direction, where I'd use Ceph anyway (or build on-top of an existing solid distributed database) if I needed it.

Also think there is an abstraction mismatch with the object stores that store the objects with a 1:1 mapping into the file system. Obvious issues are that you only get good listing performance with '/' as delimiter and things like "keys with length up to 1024 bytes" break.


Btw, Go does have runtime exceptions, they just call them Panics and don't have any nice tooling around it. :)

Why not compiling it to Java source code (not bytecode)? Users would use their own Java compiler then.

Same as, say, ANTLR generates code to parse various texts to AST.


Great question, actually I tried that! m2cgen is a project that does that in fact.

It works fine for simple models, but breaks down for production-sized tree ensembles. The JVM has a hard 64KB method size limit, and javac controls how your deeply nested if/else trees get laid out. m2cgen's own FAQ says to reduce estimators when you hit recursion limits during generation. With direct bytecode emission I control the method structure precisely, I can split across methods exactly where needed and manage the constant pool directly. I also wrote much more efficient bytecode than m2cgen creates as equivalent source.

The source code is also a pretty useless step, sets off all kinds of static analysis alarms in your stack, and also I worry about source code injection (not that can't happen with petrify, it's just a lot harder).

Finally, I'm grateful for the sweat the authors of m2cgen have put in, but the project has gone without updates for 4 years. That doesn't mean it's useless (some mature software never sees updates), but it's not a positive sign either.


I code on both and they are just for different purposes. E.g. I think it's madness to develop desktop apps in Rust.

Development velocity is way greater in Java.


Why not compiling it to Java source code (not bytecode)? Users would use their own Java compiler then.

Same as, say, ANTLR generates code to parse various texts to AST.


All of that tooling and Rust will always be less efficient than Assembler.

I… didn’t think this makes sense :)

It makes perfect sense: Rust compilers will never beat a human at scheduling every single opcode perfectly based on the deepest microarchitectural analysis short of decapping the chip and breaking out the ol' electron microscope. Whether it's worthwhile to be that efficient over a whole program, as opposed to a preternaturally tight compute kernel, is definitely questionable.

> scheduling every single opcode perfectly based on the deepest microarchitectural

Is that even possible knowing OOE+ branch execution and many other CPU tricks?


Yes it does, that is why most serious games used to be written in Assembly, until BASIC, Pascal, C and C++ compilers got enough language extensions and compiler knobs to not having to do that all the time, and yet some Assembly is still required.

I hate when tools only produce generic "TLS Handshake failed" instead of saying why exactly it failed, where is the problem.

Sounds like you'd both be happy if the tool produced both.

And Java typically does produce both (see Exception "cause" field). So when an exception stack trace is printed it's actually list of stacktraces, for each "cause". You can skip stacktraces and just concatenate causes' messages (like people often do in Go).

So the full message would be like "Cannot add item X to cart Y: Error connecting to warehouse Z: Error establishing TLS connection to example.com 127.0.1.1: PKIX failed".


Sounds to me that deepsun and I are in agreement that an error message should tell you what the actual error was.

I.E. ERROR: TLS handshake failed: <DOMAIN> certificate chain unverified


People give Go's error handing a lot of flak, but I personally love the errors that come out of a quality codebase.

Just like your example: single line, to the point and loggable. e.g.

  writing foo.zip: performing http request (bar.com): tls: handshake: expired certificate (1970-01-01)
Exceptions with stack traces are so much more work for the reader. The effort of distilling what's going on is pushed to me at "runtime". Whereas in Go, this effort happens at compile time. The programmer curates the relevant context.

What?

What you write makes zero sense, see my comment here: https://news.ycombinator.com/item?id=47750450

And come on, skipping 5 lines and only reading the two relevant entries is not "much work". It's a feature that even when developers eventually lazied out, you can still find the error, meanwhile you are at the mercy of a dev in go (and due to the repeating noisy error handling, many of the issues will fail to be properly handled - auto bubbling up is the correct default, not swallowing)


Different strokes for different folks.

The Go errors that I encounter in quality codebases tend to be very well decorated and contain the info I need. Much better than the wall of text I get from a stack trace 24 levels deep.


Apples to oranges.

Quality java code bases also have proper error messages. The difference is that a) you get additional info on how you got to a given point which is an obviously huge win, b) even if it's not a quality code base, which let's be honest, the majority, you still have a good deal of information which may be enough to reconstruct the erroneous code path. Unlike "error", or even worse, swallowing an error case.


> reconstruct the erroneous code path

This is only useful to the developers who should be fixing the bug. Us sysadmins need to know the immediate issue to remediate while the client is breathing down our neck. Collect all the stack traces, heap dumps, whatever you want for later review. Just please stop writing them to the main log where we are just trying to identify the immediate issue and have no idea what all the packages those paths point to do. It just creates more text for us to sift through.


grep "caused by"

Here you are.


Why not just make your errors more readable and not have to use an extra tool?

Well, just write more readable error messages?

How do you make this more readable:

ExceptionName: Dev-given message at Class(line number) at Class(line number) caused by AnotherCauseException: Dev-given message at Class(line number)

It's only the dev given message that may or may not be of good quality, the exact same way as it is in go. It's a plus that you can't accidentally ignore error cases, and even if a dev was lazy, you still have a pretty good record for where a given error case could originate from.


Again, I am a sysadmin, not a developer. Telling me line numbers in a files written in a language I don't understand is not helpful. I don't care where the error occurred in the code. I care what the error was so I can hopefully fix it, assuming its external and not a bug in the code.

Don't have to grep my go errors :)

Especially when they forget to properly handle an error case among the litany of if err line noise, and you get erroneous code execution with no record of it!

This is why stack traces exist. But I agree Java seems to not really have a culture of “make the error message helpful”, but instead preferring “make the error message minimal and factual”.

For what it’s worth, the rise of helpful error messages seems to be a relatively new phenomenon the last few years.


A stack trace that is >10 pages in less is not what I would call minimal.

And that's why you should have multiple appenders. So in code you write "log.error("...", exception)" once, but logging writes it in parallel to:

   1. STDOUT for quick and easy look, short format.
   2. File as JSON for node-local collectors.
   3. Proper logging storage like VictoriaLogs/Traces for distributed logging.
Each appender has its own format, some print only short messages, others full stacktraces for all causes (and with extra context information like trace id, customer id etc). I really think STDOUT-only logging is trying to squeeze different purposes into one unformatted stream. (And Go writing everything to STDERR was a really strange choice).

https://www.baeldung.com/logback#bd-appenders


Cool. Convince your fellow Java developers to do that and I'll quit complaining about the awful errors every Java app produces.

This is the kind of scenario that is served better by Go/C-style error values than exceptions. Error values facilitate and encourage you to log what you were doing at the precise point when an error occurs. Doing the same with exceptions idiomatically often requires an exception hierarchy or copious amounts of separate try/catches.

The difference really becomes apparent when trying to debug a customer's problem at 3am (IME).


This couldn't be further from the truth.

There is no ecosystem I would choose over Java when it comes to observability and it's not even close.

Good luck finding your segfault, oom, race condition or just simply lazy logging culture bug with a C/go codebase at 3am.

I will happily see my proper stack trace, heap dump, or connect directly to prod with a debugger with basically no performance penalty.


Your stack trace tells you where in the code the error occurred, but doesn't tell you what it was doing with what data. For that you need to pass context for the error up the chain of calls, adding to it as you go up. Exceptions are not a great way of doing it as you only have the local context, which isn't a great help when you're catching N levels up.

And if you're not catching N levels up but catching at each level, then you are emulating error values but with try/catch blocks.


That is great for you as a developer. As a sysadmin supporting other people's crap, stack traces and heap dumps are useless beyond forwarding them to the vendor.

You forgot about NaNs (all of them), infinities and positive/negative zeros. Tests warranted.

Don't forget the Intel floating-point division bug from the 90s.

https://en.wikipedia.org/wiki/Pentium_FDIV_bug


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: