7 ms·
Read up until author is confusing HTTP/1 with TCP, claiming that it's TCP's fault that we must make multiple connections to load a website. Actually, TCP allow
by culebron21 3y ago
Read up until author is confusing HTTP/1 with TCP, claiming that it's TCP's fault that we must make multiple connections to load a website.
Actually, TCP allows continuous connection and sending as much stuff as you want -- in other words, stateful protocol. It was HTTP/1 that was decidedly stateless.
Sessions in web sites are direct consequence of the need to keep state somewhere.
- fidotron 3y agoThe whole HTTP request/response cycle has led to a generation of developers that cannot conceive of how to handle continuous data streams, it's extraordinary. I have seen teams of experienced seniors using websockets and then just sending requests/responses over them as every architecture choice and design pattern they were familiar with required this. Then people project out from their view of the world and assume the problem is not with what they are doing but in the other parts of the stack they don't understand, such as blaming TCP for the problems with HTTP.
- culebron21 3y agoI switched from web dev to data science some years ago, and surprisingly couldn't find a streaming parallelizer for Python -- every package assumes you loaded the whole dataset in memory. Had to write my own.
- elashri 3y agoThere are many packages that can do that, like Vax [1] and Dask [2]. I don't know exactly your workflow. But the concurrency in python is limited to multiprocessing, which is much expensive than threads which usually a typical streaming parallelizer will use outside python world. [1] https://vaex.io/docs/index.html https://vaex.io/docs/index.html [2] https://docs.dask.org/en/latest/ https://docs.dask.org/en/latest/
- bboygravity 3y agoJust curious: why would you not load the entire dataset "into memory" ("into memory" from a Python perspective)? On an average desktop/server system the OS would automatically take care of putting whatever fits in RAM and the rest on disk. Or are the datasets large enough to fit on neither?
- ninkendo 3y ago> On an average desktop/server system the OS would automatically take care of putting whatever fits in RAM and the rest on disk. This is not true, unless you’re referring to swap (which is a configuration of the system and may not be big enough to actually fit it either, many people run with only a small amount of swap or disable it altogether.) You may be referring to mmap(2), which will map the on-disk dataset to a region of memory that is paged in on-demand, but somehow I doubt that’s what OP was referring to either. If you just read() the file into memory and work on it, you’re going to be using a ton of RAM. The OS will only put “the rest on disk” if it swaps, which is a degenerate performance case, and it may not even be the dataset itself that gets swapped (the kernel may opt to swap everything else on the system to fit your dataset into RAM. All pages are equal in the eyes of the virtual memory layer, and the ranking algorithm is basically an LRU cache.)
- geocar 3y agoread() doesn't read from the disk if the blocks are already in memory.
- ninkendo 3y agoThat’s a really misleading thing to say. If the kernel already has the thing you’re read()’ing cached, then yes the kernel can skip the disk read as an optimization. But by reading, you’re taking those bytes and putting a copy of them in the process’s heap space, which makes it no longer just a “cache”. You’re now “using memory”. read() is not mmap(). You can’t just say “oh I’ll read the file in and the OS will take care of it”. It doesn’t work that way.
- otteromkram 3y agoDid you try dask? https://www.dask.org/ https://www.dask.org/
- deleted 3y ago[deleted]
- culebron21 3y agoI've looked into the samples and recall what the problem was: geopandas was in an experimental branch, and you had to lock yourself into dask -- plus, the geopandas code had to be rewritten completely for dask. So i wrote my own processor that applies the same function in map&reduce fashion, and keeps code compatible with jupyter notebooks -- you decorate functions to be parallelizeable, but still import them and call normally. https://github.com/culebron/erde https://github.com/culebron/erde
- goeiedaggoeie 3y agoSame in video parsers and tooling frequently, expects a whole mp4 to be there, or a whole video to parse it, yet gstreamer/ffmpegapi delivers the content as a stream of buffers that you have to process one buffer at a time.
- prox 3y agoIs it me or aren’t there a whole lot video specialists in general? It’s just something I noticed here and there on github.
- londons_explore 3y agoIn a way, that's good. The few hundred video encoding specialists who exist in the world have, per person, had a huge impact on the world. Compare that to web developers, who in total have had probably a larger impact on the world, but per head it is far lower. Part of engineering is to use the fewest people possible to have the biggest benefit for the most people. Video did that well - I suspect partly by being 'hard'.
- nullpilot 3y agoMy experience that played out over the last few weeks lead me to a similar belief, somewhat. For rather uninteresting reasons I decided I wanted to create mp4 videos of an animation programmatically. The first solution suggested when googling around is to just create all the frames, save them to disk, and then let ffmpeg do its thing from there. I would have just gone with that for a one-off task, but it's a pretty bad solution if the video is long, or high res, or both. Plus, what I really wanted was to build something more "scalable/flexible". Maybe I didn't know the right keywords to search for, but there really didn't seem to be many options for creating frames, piping them straight to an encoder, and writing just the final video file to disk. The only one I found that seemed like it could maybe do it the way I had in mind was VidGear[1] (Python). I had figured that with the popularity of streaming, and video in general on the web, there would be so much more tooling for these sorts of things. I ended up digging way deeper into this than I had intended, and built myself something on top of Membrane[2] (Elixir) [1] https://abhitronix.github.io/vidgear/ https://abhitronix.github.io/vidgear/ [2] https://membrane.stream/ https://membrane.stream/
- deskamess 3y agoWhat is the best approach to handling a continuous stream of data? Is it just 'buffer till you have what you need and pass it off to be processed' approach? And then keep reading until end of stream/forever.
- allan_s 3y agoI think what they mean is that most people think that only the following is possible on 1 connection 1. Send Request 1 2. Wait for Response 1 3. Send Request 2 4. Wait for Request 2 while you can do 1. Send Request 1, move on 2. Send Request 2, move on and have an other process/routine handling response and potentially you even have Request that can be sent without needing a reponse "user is typing" in XMPP for example. and even wilder for people using only http, that you can receive Response without a Request ! (i.e that you don't need to implement a GET /messages request, you can directly have your server sending messages)
- bmicraft 3y agoSounds like a worse way of writing async requests, while the last part is basically what websockets seem to be intended for
- allan_s 3y agoI think you missed my point > Sounds like a worse way of writing async requests, It's just how it works under the hood, this complexity is quickly abstracted and actually it's how a lot of async requests are implemented, it's just here it's on 1 tcp connection. > , while the last part is basically what websockets seem to be intended for yes I was specifically answering that : > I have seen teams of experienced seniors using websockets and then just sending requests/responses over them as every architecture choice and design pattern they were familiar with required this. i.e people using websocket like normal http request.
- dgb23 3y agoIn the case of websockets that is already handled for you. I think GP talks about how to think about communication (client server). Stateless request response cycles are much simpler to reason about because it synchronizes messages by default. The state is reflected via this back and forth communication. Even when you do it via JS: the request data is literally in the scope of the response callback. If you have bi-directional, asynchronous communication, then reading and writing messages is separate. You have to maintain state and go out of your way to connect incoming and outgoing messages semantically. That's not necessarily what you should be doing though.
- grogenaut 3y agoI know right. The kids these days. Most of them never learned to solder either so how can they assemble their own computers from ics? I caught one of my tech leads using a jet burner lighter and just scorching the whole board. And forget reading core dumps in hex!!! An intern was just putting the hex dump in the chat chibi and asking it what went wrong. Get off my lawn already.
- ascar 3y agoIf I recall correctly in TCP a packet loss will cause a signifcant slowdown in the whole data stream since that packet needs to be retransmitted and you generally end up with a broken data stream until that happens (even tho TCP can continue to send more data in the meantime meaning it's more of a temporary hang than a block). Thus if you are sending multiple different data streams over the same TCP connection a packet loss will temporarily hang the processing of all data streams. A constrain that QUIC doesn't have.
- culebron21 3y agoYes, I just read about this, and it makes sense.
- pjc50 3y agoNot broken, but you end up with a hole in the TCP receive window while the packet is retransmitted. How does QUIC manage its stream reassembly window sizes? I suppose it's easier since it's all in userland.
- tsimionescu 3y ago> I suppose it's easier since it's all in userland. I doubt applications would provide more reliable information to the QUIC library than they would to the kernel. The main difference as I understand it is that QUIC allows multiple separate TCP-like streams to exist on the same negotiated and encrypted connection. It's not fundamentally different from simply establishing multiple TLS over TCP connections with separate windows, it just allows you to establish the equivalent of multiple TLS + TCP connections with a single handshake.
- adgjlsfhk1 3y agoThe key point is that if I want to load a webpage that needs to download 100 different files, I don't care about the order of those 100 files, I just want them all to be downloaded in order. TCP makes you specify an order which means that if one packet gets lost, you have to wait for it. QUIC lets you say "here are the 100 things I want" which means that if you lose a packet, that only stops 1 of the things so the other 99 can continue asking for more packets.
- oefrha 3y agoTCP is a streaming protocol. You can build whatever multiplexing scheme on top like h2 does, but you simply can’t escape TCP head of the line blocking, as it’s just a single undelimited stream underneath. As an aside, I only truly grasped the stream nature of TCP when I started dissecting and reassembling packets. The first ever reassembly program I wrote was hopelessly wrong because I was treating TCP packet boundary as data packet boundary, but in fact higher level protocol (HTTP/RTMP/etc.) data packet boundaries have nothing to do with TCP packet boundaries at all, it’s a single continuous stream that your higher level protocol has to delimit on its own.
- pjc50 3y agoThere's an additional layer of network administrators at fault which block other protocols. Saw this question the other day: https://softwareengineering.stackexchange.com/questions/447903/are-there-downsides-of-two-tcp-connections-for-bidirectional-communication https://softwareengineering.stackexchange.com/questions/4479... Administrator blocks everything except TCP. Sometimes you even get blocks on everything except 80 and 443.
- lazide 3y agoThat must really suck for DNS!
- LinuxBender 3y agoIt's common in restricted environments. Egress for 80/443 allowed and DNS must use local recursive DNS servers. Those internal DNS servers probably pass through a few SIEM and other security devices and are permitted out, usually to minimize data exfiltration. Though in those cases 80 and 443 are often using a MITM proxy as well for deep packet inspection. There are both commercial and open source MITM proxies. Fans of HTTP/3 and QUIC would not like most of the MITM proxies as they would negotiate a specific protocol with the destination server and it may not involve QUIC.
- zoogeny 3y agoI worked in an environment with similar setup. First step for all devices allowed to connect to the network was to install the companies custom CA root certificate. There are a lot of sharp edges in such a setup (like trying to get Charles or other debugging proxies to work reliably). But in highly sensitive environments it would seem the policy is to MiTM every packet that passes through the network. I wasn't involved but another team did some experimenting with HTTP/2 (which at the time was still very early in its rollout) and they were struggling with the network team to get it all working. Once they did get it to work it actually resulted in slightly less performant load times for our site and the work was de-prioritized. I recall (maybe incorrectly) that it was due to the inefficiency of forcing all site resources through a single connection. We got better results when the resources were served from multiple domains and the browser could keep open multiple connections. But I wasn't directly involved so I only overheard things and my memory might be fuzzy on the details of what I overheard. Funnily enough, we did have to keep a backup network without the full snooping proxy for things like IoT test devices (including some smart speakers and TVs) since installing certs on those devices was sometimes impossible. I assume they were still proxying as much as they could reasonably manage.
- ericpauley 3y agoThe author obviously knows this. As others have noted, even though HTTP over TCP supports multiple requests they must be accomplished consecutively unless you use multiple TCP connections.
- loup-vaillant 3y agoThere is though a fundamental mismatch between TCP, and the problem HTTP (any version) needs to solve: TCP is for sending stream of bytes, reliably and in the same order they were sent. HTTP needs to transmit some amount of data, reliably. The only aspect of TCP HTTP really wants here is reliability. The order we don’t really care about, we just want to load the whole web page and all associated data (images, scripts, style sheet, fonts…), in a way that can be reassembled at he other end. This makes it okay to send packets out of order, and doing so automatically solves head-of-line blocking. This is a little different when we start streaming audio or video assets: for those, it is often okay for reliability to take a hit (though any gap must be detected). Losing a couple packets may introduce glitches and artefacts, but doesn’t necessarily renders the media unplayable. (This applies more to live streams & chats though. For static content most would prefer to send a buffer in advance, and go back to sacrifice ordering in order to get a perfect (though delayed) playback.) In both use cases, TCP is not a perfect match. The only reason it’s so ubiquitous anyway is because it is so damn convenient.
- masklinn 3y agoThat’s a different issue than what parent is talking about: HTTP definitely needs each individual resource to be ordered, what it does not need is for different resources to be ordered relative to one another, which becomes an issue when you mux multiple requests concurrently over a single connection.
- crims0n 3y ago> This is a little different when we start streaming audio or video assets: for those, it is often okay for reliability to take a hit (though any gap must be detected). Losing a couple packets may introduce glitches and artifacts, but doesn’t necessarily renders the media unplayable. This is exactly what UDP is for. There is nothing wrong with TCP and UDP at the transport layer, both do their job and do it well.
- bjourne 3y agoI could not find that claim in the article, but perhaps you are referring to an earlier version of the article that the author then updated? The performance problem with TCP is that it imposes a strict ordering of the data. The order in which clients receive data is the same as the order in which servers send data. So if some packet fail to reach the client, the packet has to be retransmitted before subsequent packets can be sent (notwithstanding the relatively few non-ACKed packets that are allowed to be in flight). I think this problem is what the author is referring to. And that it would be nigh impossible to get all network equipment that sits between a client and a server to a more latency-friendly version of TCP.
- taneq 3y ago> It was HTTP/1 that was decidedly stateless. And this was a principled stance. HTTP/1 was for serving web pages, and web pages are documents. Then we started generating web pages from databases, which was pretty useful, but also started the slippery slope to us hijacking the web and turning it into a network of applications running on a nested operating system.
- ignoramous 3y ago> ...the slippery slope to us hijacking the web and turning it into a network of applications running on a nested operating system. Well if folks drop anything that's not 53, 443, or 80, then what other choices are left?
- taneq 3y agoThat's a slightly different question (ie. how do we pragmatically tunnel our data between applications) but yes, that evolutionary race to the bottom (or port 80/443 as you say) also sucks.
- ignoramous 3y ago> Actually, TCP allows continuous connection and sending as much stuff as you want This is also what QUIC is, but implemented in userspace and with some key properties to prevent ossification and analysis.
- paulddraper 3y agoThere is a mismatch. What is ideal for (web browser) HTTPS is a single encryption handshake used by multiple parallel, independent transfers. So if a chunk of your PNG is delayed, that doesn't stop your stylesheet from loading, or vice versa. I.e. multiplexed encrypted connections.