![]() |
|
![]() |
| Each of the pixels is actually a little shining eye which watches your every move. When the pixel’s eyelid closes, that pixel turns black. That’s why they call it putting a display “to sleep.” |
![]() |
| In case of a LCD, black pixel is turned ON to block backlight. It's clearly visible on monochrome LCD screens.
In case of e-paper, black pigment is attracted to the outer part of the screen. |
![]() |
| > Claiming you should not assume any name can be spelled in Unicode is absurd as well.
China (and Japan, and to a certain extent Korea and Viet Nam) exists? https://en.wikipedia.org/wiki/Naming_laws_in_China#Notable_c... I'm pretty sure that patio11, having spent his life in Japan, would know that technology like SING glyphlets exists because of this exact issue. (and before you answer "what are you talking about, it is in Unicode?", these characters are literally added after the relevant issue surfaced, and some characters like 𱅒 (U+31152) are recent additions that don't even render properly) |
![]() |
| Err. It still does by default change your name (if you're a woman). But you can ask and keep your 'maiden' (ugh) name or have both. It gets a bit trickier for kids' family names... |
![]() |
| George Herbert Walker Bush comes to mind as a native son of the US with multiple middle names. He used H. W. in politics, but that still includes some whitespace and non-traditional characters. |
![]() |
| I’m pretty sure originals that defined this format did have examples and citations.
But I do agree that some of the later entries have felt a little lazy. |
![]() |
| I think these lists are often primarily intended as humorous, and perhaps a way to get you thinking about exceptions, not as a way to teach you more about the topic. |
![]() |
| I noticed that too and thought I was missing something. Some cool resources that are actually decent for network programming:
https://beej.us/guide/bgnet/ -- Covers what abstractions the OS provides for network programming and the guarantees that are possible. https://www.madwizard.org/programming/tutorials/ - This is the very first ever good tutorial I read on socket programming. It's OG winsock. Introduces network programming from the most basic level. Aimed at C. When you understand these guides you'll learn that how you structure your entire programs networking depends on whether you want to use blocking or non-blocking sockets. If you go with blocking you'll probably be using threads or processes. Otherwise you can't do any other work. With non-blocking it will be more about polling sockets and eventually you might end up with something resembling an event loop. Until you come towards to the current approach to networking which is mostly async await -- an event loop works with non-blocking sockets, watches them for changes, and passes data from them to event handlers. There's a lot more that can be done on sockets to effect things like how data is flushed, how TCP errors are handled, and so on, but its a good start. |
![]() |
| Pedantically: TCP has segments, IP has packets, and Ethernet has frames. They are one-to-one in simple cases, but not always.
https://networkengineering.stackexchange.com/questions/50083... In particular, fragmentation by intermediate routers means that the server and receiver may disagree about the frame and packet boundaries. TCP is expected to make a "reliable" pipe-like service out of whatever happens, and the application layer doesn't have (shouldn't need?) visibility into that process. |
![]() |
| Yeah, that's basically the takeaway I had (and I failed to summarize as concisely, ironically enough). It seemed like there was some insight there, but I had absolutely no clue what it was. |
![]() |
| If what was originally a packet is fragged, the TCP headers may (likely) not be in all the frags. So if you're looking with wireshark and you think you can filter with TCP flags good for you, 90% of the world feels that way.
I work with DNS a lot and when a protocol which is datagram-oriented is translated to a stream-oriented medium and somebody wants to potentially handle multiple requests in that stream because "efficiency"... it's so important... they need a way to distinguish those embedded datagrams: "we should do it they way they did in HTTP, with a Content-Length: header, yea THAT's the ticket!" I'm sure that's what they were thinking. Then along come the 90% and when they try to process DNS requests in TCP streams it's "what's this two bytes in front of the request? I dunno, but I just skip over it" and I suppose it works well enough, because with frags they'll drop the tail of the requests because "corruption" anyways, and who on earth sends multiple requests in a single packet, amiright? You may think I'm kidding, but here's some really clever (really!) eBPF code: https://gist.github.com/oghie/b4e3accf1f87afcb939f884723e2b4... If you want more on this topic: http://consulting.m3047.net/dubai-letters/dnstap-vs-pcap.htm... |
![]() |
| What it really means is: Packets have well-defined boundaries between sufficiently-adjacent nodes. They are not guaranteed to keep those boundaries end-to-end over arbitrary middleware. |
![]() |
| But they assert whether or not something exists, as an absolute statement. Maybe TCP packets don't exist in a particular situation, but there is still such a thing as a TCP packet in that case. |
![]() |
| The point is that a lot of stuff in Networking (and Computer Engineering in general) is very context dependent, and that you cannot be extremely opinionated about this stuff. |
![]() |
| Depends on OS settings these days. Lots of OSes want to help and detect link down and reset all your connections. Kind of a pain when you just want to move a cable. |
![]() |
| .. on Linux. If you do that on Windows the MAC will detect the loss of link pulses, report the interface as down, and Windows will "helpfully" reset all your TCP connections. |
![]() |
| It's a tradeoff between robustness to transient errors and reporting errors quickly. "Most errors are transient" is a widely applicable rule of thumb. But both approaches have merit. |
![]() |
| With timeouts. You can’t unplug it for an hour and have this happen. But a few seconds is exactly what this is designed for. As another commenter pointed out, your OS could also try to be “helpful”. |
![]() |
| It may be your local gateway. Seeing no packets from your host. Attempting to refresh your MAC address via ARP. Getting no response. Generating an ICMP message as a result. |
![]() |
| That seems like a distinction without a difference to me. Why should I care if the thing I get exactly one of is called "processing" or "delivery"? |
![]() |
| The link I posted above explains the connection: https://blog.bulloak.io/post/20200917-the-impossibility-of-e...
Particularly: > The sender cannot know if a message was delivered since transport is unreliable; thus, one or more acknowledgement messages are required. Moreover, the sender cannot distinguish between message delivery errors, acknowledgement delivery errors, or delays (either in processing or because or network unreliability). > The recipient is forced to send the acknowledgement only after the message is either processed (or persisted for processing) because an acknowledgement before processing would not work: if the recipient exhibits a fault before processing that would cause the loss of the message. > In the case that that acknowledgement is lost, the sender can’t know (due to lack of insight in the recipient’s state) whether the recipient failed before scheduling the message for processing (in essence losing the message) or if the recipient is just running a bit slow, or if the acknowledgement message was lost. Now, if the sender decides to re-deliver, then the recipient may end up receiving the message twice if the acknowledgement was dropped (for example). On the other hand, if the sender decides to not re-deliver, then the recipient may end up not processing the message at all if the issue was that the message wasn’t scheduled for processing. |
![]() |
| Delivery is communication between two actors. Processing is what one actor (the receiver) does with a message.
Communication is when two actors exchange a message. Communication is generally done over an unreliable medium because in practice there is no way to communicate without the potential of failure. 1. Exactly once communication between two actors over an unreliable medium is impossible. At the very least you have to account for the possibility of failure of the medium, so you might need to re-send messages. 2. At least once communication between two actors is possible -- just re-send a message until the receive acknowledges the message. 3. Because a message might be re-sent, the receiver must be able to cope with duplicate messages. This is what you're describing. This might be done by making message processing idempotent or tracking which messages you've seen before. In either case, you have achieve exactly once processing. That is, if a receiver is given the same message multiple times, only the first receive of the messages changes the state of the receiver. --- > But exactly-once delivery is not only possible, it's trivial. Considering that many in the field consider this problem to be impossible (or, at best, extremely difficult, e.g. https://www.confluent.io/blog/exactly-once-semantics-are-pos...), this should be a huge red flag to yourself that you're missing something. Everyone has blind spots and that's okay, but hopefully you understand that there's a pretty big mismatch here. Alternatively, it's possible that this problem _really_ is trivial and you have some unique insight which means there's a great opportunity for you to write a paper or blog post. |
![]() |
| OK, I don't dispute that, but that is a very different claim than "you can't get exactly-once delivery." You can (if you have at-least-once delivery). |
![]() |
| > But not 100%.
Why not? > At some point, a counter move on the delivery has to be stored... -somewhere-. What is a "counter move on the delivery"? |
![]() |
| > Do you know what idempotency is? This is exactly what he described.
Is it though? It seems like a false equivalency, even if the outcome is approximately the same? |
![]() |
| I wouldn't, unless you've got a really solid understanding of your datacenter network and it's 100% good all the time. Which is unlikely, from my experience as a server person.
If you've got dirty optics between two switches, now you're getting packet loss and TCP rears its head. Hopefully it's not an issue now, but diagnosing microbursting[1] was lots of fun, and really wigs TCP out. I've also run into 'fabric congestion'. My true favorite though is when you've got 2x aggregation on servers, and 4x aggregation for top of rack switches to spine switches, so there's 8 paths in each direction between two servers in adjacent racks, and only one path (sometimes in only one direction) is only running at 99.9%. That's a real PITA to track down unless you have visibility into switching metrics. [1] https://en.m.wikipedia.org/wiki/Micro-bursting_(networking) |
![]() |
| Honest question: Why didn't you send the message's idempotency token back to the client? Then you're playing the familiar local database locking game. |
![]() |
| You can't imagine how desperately I asked for that. Backend guys came up with all sorts of excuses to not do it. As far as I know, they did do it sometime after I quit. |
![]() |
| 1. A SYN will receive a SYN-ACK or a RST 2. A host from my machine is the same as from your machine 3. An IP from my machine is the same as from your machine |
![]() |
| > Explainer for 1-4: https://en.wikipedia.org/wiki/Two_Generals%27_Problem. TL;DR: If the connection breaks while an ACK is outstanding, the sender will have no way of knowing whether the segment was received, and this turns out to be an insoluble problem no matter how much complexity you pile on top of it. You need something resembling Paxos or Raft to get a guarantee like that
The hashgraph algorithm is pretty sweet too and doesn't have the issue of a single write leader like Paxos and Raft. Basically multi-writers / leaderless https://www.swirlds.com/downloads/SWIRLDS-TR-2016-01.pdf But to be fair, I'm not certain that CAP theorem and partition tolerance really belong in a conversation about TCP anyway |
I find this "falsehoods programmers believe" format of making pointed claims that you intentionally don't clarify to be unhelpful and obnoxious