[HN Gopher] Next Generation Out of Band Garbage Collection
___________________________________________________________________
Next Generation Out of Band Garbage Collection
Author : ksec
Score : 159 points
Date : 2024-11-02 19:57 UTC (1 days ago)
(HTM) web link (railsatscale.com)
(TXT) w3m dump (railsatscale.com)
| jeeyoungk wrote:
| This is from several years ago (2017), but this has very similar
| vibe as Instagram disabling Python GC - https://instagram-
| engineering.com/dismissing-python-garbage-...
| IshKebab wrote:
| A 10% performance improvement on Python code is laughable. You
| can get a 5000% performance improvement if you switch to a
| better language.
| ziddoap wrote:
| I bet the engineers at Instagram were unaware of pythons
| performance profile when they chose it, you should let them
| know that they should just switch to a different language.
| byroot wrote:
| Meta is just a small startup though, they probably don't
| have enough resources nor the skills to switch to a better
| language even after they've heard the gospel.
| immibis wrote:
| The joke is that Facebook literally did, right?
| byroot wrote:
| Did what? Rewrite Instagram into another language? Do you
| have any source on this?
|
| Last time I checked they're working on improving Python
| performance instead (yes I know they forked it into
| Cinder, but they're trying to upstream their
| optimizations [0]). Which is very similar to what we're
| doing at Shopify.
|
| Of course 100% of Instagram isn't in Python, I'm certain
| there's lots of supporting services in C++ etc, but AFAIK
| the Instagram "frontend" is still largely a Python/Django
| app.
|
| The joke is that if Meta thought that replacing all the
| Python code they have with something else was worth it,
| they'd have done it already.
|
| [0] https://github.com/facebookincubator/cinder
| lucianbr wrote:
| > The joke is that if Meta thought that replacing all the
| Python code they have with something else was worth it,
| they'd have done it already.
|
| "Worth it" depends on both how much performance
| improvement you get, and how hard it is to replace. Did
| you consider maybe the rewriting effort is so humongous
| that it is not worth doing despite large performance
| improvements? Thus making the joke not funny at all...
| byroot wrote:
| That's exactly the joke though. Every time Ruby (or
| Python) is discussed on HN we get the same old tired
| question of "why don't they just rewrite in Rust".
|
| But that's some silly engineer tunnel vision, squeezing
| the very last bit of performance out of a system isn't a
| goal in itself. You just need it to be efficient enough
| that it cost you significantly less to run that the
| amount of revenue it brings you.
|
| I can bet you that moving off Python must have been
| pitched dozens and dozens of time by Meta engineers, but
| deemed not worth it, because execution speed isn't the
| only important characteristic.
|
| So yes, I find it hilarious when HN commenters suggests
| companies should rewrite all their software into whatever
| is seen as the most performant one.
| IshKebab wrote:
| It's usually dismissed because companies think short
| term, and switching languages is a project with huge
| short term disadvantages and huge long term advantages.
| HumanOstrich wrote:
| It's usually dismissed because it's almost always a huge
| strategic blunder.
| debugnik wrote:
| I think they meant Facebook switched their PHP code to
| Hack and HHVM, their own PHP-like language and
| implementation.
| IshKebab wrote:
| I don't know if you're joking or not but that is exactly
| true. Meta went as far as creating their own PHP engine
| and then a new PHO compatible language because they
| didn't have the resources to switch from PHP.
|
| Instagram is presumably in the same position. Switching
| language is basically impossible once you have a certain
| amount of code. I'm sure they were aware of the
| performance issues with Python but they probably said
| "we'll worry about it later" when they were a small
| startup and now it's too late.
| eru wrote:
| Well, Facebook also created their own hacked up version
| of PHP (called Hack) that's presumably easier to migrate
| PHP to.
|
| Hack is actually surprisingly pleasant, basically about
| the best language they could have made starting from PHP.
| (I know, that's damning with faint praise. But I actually
| mean this unironically. It has TypeScript vibes.)
| krapp wrote:
| I was excited about Hack when it came out. Unfortunately
| PHP took just enough from it to kill it. I gave up on it
| once Composer stopped supporting it, after backwards
| compatibility with PHP no longer became a goal.
|
| IMHO Hack's best feature was native support for XHP...
| which (also unfortunately) isn't something PHP decided to
| take.
| eru wrote:
| I only used Hack when I was very briefly working for
| Facebook. (And I used PHP once before nearly 20 years ago
| by now for some web site I had 'inherited', back when PHP
| was truly an awful language)
| Twirrim wrote:
| Hack really gave PHP/Zend the kick up the arse that it
| seemed to need.
| IshKebab wrote:
| Yes I mentioned that.
| electricwire wrote:
| They may well have been initially, its a pretty puzzling
| choice
| worik wrote:
| > I bet the engineers at Instagram were unaware of pythons
| performance profile when they chose it,
|
| Is the Instagram stack Python? I doubt it, but stranger
| things have happened
|
| I suspect it is actually some derivative of Apache, or
| Nginx. Something sensible
| httgp wrote:
| Instagram is built with Django.
| rty32 wrote:
| Very naive take.
|
| 1. 10% performance improvement at Instagram could lead to
| many millions of revenue "instantly". It is not laughable at
| any company. 2. It won't be a 5000% performance improvement.
| Facebook uses its own fork of Python that is heavily
| optimized. Probably still far from C++, but you should be
| thinking about languages like Java when talking about
| performance.
|
| "Better" is a very subjective term when discussing languages,
| and I hope such discussions can be more productive and
| meaningful.
| foobazgt wrote:
| Cinder's benchmarks don't seem "like Java" performance,
| given they aren't that far off cython.
|
| https://github.com/facebookincubator/cinder/blob/cinder/3.8
| /...
| eru wrote:
| CPython itself has seen lots of performance improvements
| recently. Benchmarks on CPython 3.12 take about half the
| time they took on CPython 3.9.
| IshKebab wrote:
| Yeah it's definitely welcome, but even if it is double
| the performance (doesn't seem to be quite there in my
| experience) fast languages are still 25-50x faster. It's
| like walking twice as fast when the alternative is
| driving.
| lucianbr wrote:
| > Facebook uses its own fork of Python that is heavily
| optimized.
|
| So likely the 5000% improvement is no longer possible
| because they already did multiple 10% improvements? I don't
| know how this counters the original point.
|
| All clues point to FB going this route because they had too
| much code already in PHP, and not because the performance
| improvement would be small.
|
| In any case, "facebook does it" is not a good argument that
| something is the right thing to do. Might be, might not be.
| FB isn't above wrong decisions. Else we should buy "real
| estate" in the metaverse.
| hinkley wrote:
| > Ideally in a web application, aside from some in-memory caches,
| no object allocated as part of a request should survive longer
| than the request itself.
|
| This is one of those areas where out of process caching wins. In
| process caching has a nasty habit of putting freshly created
| objects into collections that have survived for days or hours,
| creating writes in the old generation and back references from
| old to new.
|
| Going out of process makes it someone else's problem. And if it's
| a compiled language with no or a better GC, all the better.
| byroot wrote:
| Author here.
|
| Agreed. We have some facility for out of process caching (node
| local memcached), and I frequently have to argue with
| colleagues that it's generally preferable to in-process
| caching.
| hinkley wrote:
| I accept that it is true but I bristle at the fact of it. It
| shouldn't be true.
| byroot wrote:
| Depends, it's not just about access time and GC pressure,
| it's also about sharing that cache with other processes on
| the node.
| foobazgt wrote:
| A similar strategy is to serialize the object and store it
| in-process but off heap. This is useful when the values are
| private to the process, and/or they don't need to survive a
| crash, and/or you need to avoid the network overhead. Access
| times are often 100x-1000x faster.
| kgeist wrote:
| This is something I've been thinking about for a while.
| What if we create a language where all object references
| are explicitly specified to be either request-scoped or
| application-scoped. Don't allow application-scoped objects
| reference request-scoped objects. Allow to manually upgrade
| a reference from request-scoped to application-scoped if
| needed.
|
| That would allow us to have ephemeral per-request heaps
| which are torn down after every request at once. In-request
| garbage collections are super-fast. Application-scoped
| objects are never collected (i.e. no major collections).
|
| Wouldn't this simple model solve most problems? Basically,
| a very simple equivalent to Rust's lifetimes tailored to
| web services without all the complexity, and much less GC
| overhead than in traditional GC systems.
| JonChesterfield wrote:
| You could call them "arenas" to be consistent with the
| prior art. Yes, if you can partition the heaps into ones
| with distinct lifetimes, good plan.
| ryukoposting wrote:
| Given that Rust seems to be the generalized solution to
| this problem, would a viable prototype just be a Rust
| HTTP server with a Ruby interpreter embedded in it? Write
| the code in some kind of Ruby DSL which then feeds back
| into Rust?
|
| I ask because I have embedded Ruby in applications
| before, and I'm looking for an excuse to do it in Rust.
| jnwatson wrote:
| "What if we create a language where all object references
| are explicitly specified to be either request-scoped or
| application-scoped."
|
| I've done this in both C and C++.
|
| The downside of automatic memory management is you have
| to accept the decisions the memory manager makes.
|
| Still, generational GC like in Ruby and Python
| essentially attempts to discern the lifetime of
| allocations, and it gets it right most of the time.
| echelon wrote:
| Rust is emerging as a major contender for HTTP/gRPC backend
| services.
|
| Actix, Axum, sqlx, diesel, and a whole host of other utilities
| and frameworks make writing Rust for HTTP just as easy and
| developer efficient as Golang or Java, but the code will never
| have to deal with GC.
|
| It's easy to pull request scoped objects into durable caches.
| tsimionescu wrote:
| This could also be a case for non-managed objects in the same
| process. APIs aren't typically very friendly, but I would
| expect they could be made so, especially if it was for a
| dedicated use-case like caching.
| the_mitsuhiko wrote:
| One of the challenges I see in general is that languages don't
| have enough capabilities to express intent of lifetimes /
| control flow. What I mean by that is that there is a
| significant difference between spawning a thread with the
| intention of joining, allocating memory with the intention of
| only lasting to the end of the request etc. vs spawning a
| permanent background thread or stashing away an object into a
| global cache.
|
| This is starting to really become a problem in the
| observability space and async locals. Node.js for instance
| currently will keep async locals around for too long of a time
| because they are propagated everywhere. For instance if you
| call `console.log` in a promise you will leak an async local
| forever.
|
| Next.js famously keeps around way too many async locals past
| the request boundary for caching related reasons.
|
| A solution would be to have a trampoline to call things through
| that make it explicit that everything happening past that point
| is supposed to "detach" from the current flow. An allocator or
| a context local system can then use that information to change
| behavior.
| dinosaurdynasty wrote:
| You could do something like that in Rust with a request-
| scooped arena. But then you'd have to do Rust.
|
| In node you could use worker threads (which create a new V8
| instance in a separate OS thread) but that's probably too
| heavy handed.
| henning wrote:
| They built a large codebase on a language that doesn't let you
| control memory, because that makes you "more productive". So just
| having Rails allocate a per-request arena that is asynchronously
| freed which would force the programmer not to have any objects
| that outlive the request, or just pre-allocating memory for a
| fixed amount of request handling per server instance, or whatever
| allocation behavior you want to do that is generally possible in
| C/C++/Zig/Rust/Odin/etc, requires hacking on the language itself.
| Which means your changes have to go through the Ruby team first.
| Any additional changes would also need to go through them, which
| increases the cost of change. Then there is a permanent layer of
| indirection between your GC callbacks and the semantics of what
| those callbacks do. Instead of just writing out the custom
| allocators you want, because that's impossible. How depressing.
| jrockway wrote:
| I'm guessing that Zig, Rust, Oden, and "etc." didn't exist when
| they started the codebase. Now they need to keep moving in
| their imperfect state. I don't think anyone would start a large
| company on Ruby today. (They would on Python, though, which is
| equally unfortunate.)
| bhaak wrote:
| Startups are not large companies in the beginning.
|
| Although I'm not sure what the preferred language for quickly
| getting a startup up and running would be these days.
| floating-io wrote:
| Whatever works and you can find enough developers for.
|
| The language (or the rest of the stack even) is rarely a
| barrier to success. What matters are a good idea, good
| motivation, and decent availability of competence.
|
| JMHO.
| byroot wrote:
| I don't see how it is imperfect.
|
| Per request arenas sound super cool on paper, and work very
| well on system with clear constraints. But if suddenly a
| request start allocating more than the arena can accommodate
| you're in a bit of a pickle. They're absolutely not a
| panacea.
|
| Setting aside the challenge of refactoring the Ruby VM to
| allow this sort of arenas, they'd be a terrible fit for
| Shopify's monolith.
|
| Ultimately, while it's a bit counter intuitive, GCs can
| perform extremely well in term of throughput. Ruby's GC isn't
| quite there yet, but still perform quite well and is
| improving every versions.
| samatman wrote:
| > _allocating more than the arena can accommodate_
|
| In Zig, at least, this isn't how arenas work. They're a
| wrapper around a backing allocator, so if the arena runs
| out of memory, then that means the process is out of
| memory, something no allocation strategy can fix (ignoring
| the fact that Zig returns a specific error when that
| happens, and maybe you can trigger some cache eviction or
| something like that).
|
| It's easy to set them to retain a 'reasonable' allocated
| capacity when they get reset, for whatever value of
| reasonable, so big allocation spikes get actually freed,
| but normal use just moves a pointer back and reuses that
| memory.
|
| I don't see Shopify harvesting a lot of value from a
| complete Zig rewrite, no. But arenas are basically ideal
| for the sort of memory use which web servers typically
| exhibit.
| simonask wrote:
| And when the default arena size is often outgrown, you'll
| known from whatever diagnostics/logging/dashboard
| solution you are using. Which is incidentally also a
| great tool when optimizing per-request memory usage.
|
| Being explicit about memory has many advantages, and is a
| strict requirement when scaling.
| byroot wrote:
| > something no allocation strategy can fix
|
| Well, yes, with a GC when your heap is full, you make
| space by getting rid of the garbage.
|
| Also, with a good GC, allocating is most of the time just
| bumping a pointer, exactly like an arena, and the
| collection time is proportional to the number of live
| objects, which when triggered out of band is basically 0.
|
| Hence why I think a well tuned GC really isn't that far
| off.
| ngrilly wrote:
| I really like Zig, and I've been thinking about using it
| for developing servers offering APIs over HTTP, using
| arenas bound to request lifetime. I think I would be
| comfortable developing like this myself. But all the devs
| in my org have only ever used managed-memory languages
| such as Java, C#, Python or JavaScript, which makes me
| hesitant, as I'm wondering about the learning curve, and
| of course the risk of use-after-free. Not something I
| would do anyway before Zig reaches 1.0.
| samatman wrote:
| I wrote substantial amounts of C, and Pascal/Delphi
| before that, before learning Zig, so you and I wouldn't
| see the same learning curve. That said, I found it
| straightforward to take up. Andrew Kelly places a great
| emphasis on simplicity in the sense Rich Hickey uses the
| term, so Zig has a small collection of complete solutions
| which compose well.
|
| Now is a great time to pick up the language, but I would
| say that production is not the right place to do that for
| a programmer learning memory management for the first
| time. Right now we're late in the release cycle, so I'd
| download a nightly rather than use 0.13, if you wanted to
| try it out. Advent of Code is coming up, so that's an
| option.
|
| Using a memory-managed language means you need to design
| a memory policy for the code. Zig's
| GeneralPurposeAllocator will catch use after free and
| double free in debug mode, but that can only create
| confidence in memory handling code if and when you can be
| sure that there aren't latent bugs waiting to trigger in
| production.
|
| Arenas help with that a lot, because they reduce N
| allocations and frees to 1, for any given set of
| allocations. But one still has to make sure that the
| lifetime of allocations within the arena doesn't outlast
| the round, and you can only get that by design in Zig,
| lifetimes and ownership aren't part of the type system
| like they are in Rust. In practice, or I should say
| _with_ practice, this is readily achievable.
|
| At current levels of language maturity, small teams of
| experienced Zig developers can and do put servers into
| production with good results. But it's probably not time
| for larger teams to learn as they go and try the same
| thing.
| ngrilly wrote:
| I started programming in Pascal, C and C++, so personally
| I'm fine with manual memory management, especially with a
| language like Zig. I actually find it quite refreshing.
| I'm just wondering if it's possible to "scale" this
| approach to a team of developers who may not have that
| past experience (having only worked with GCed languages)
| without ending in a code base littered with use-after-
| free errors.
| danmur wrote:
| I don't think using Zig over Python is gonna have the biggest
| impact in making your next big company successful. It's a
| drop in the ocean compared to the quality of people you have
| to actually design and build it.
| simonask wrote:
| It doesn't matter for a startup trying to get acquired.
|
| It does matter for a company trying to scale its user base
| while keeping costs down.
| indulona wrote:
| That is nonsense. If you can run your code on 10 servers
| instead of 1k servers, that is an insane time and money
| saver that could make or break a company.
| WJW wrote:
| For most startups the difference between Rust and Ruby is
| not 10 servers vs 1000 but rather between using 0.1% of a
| CPU or 1% of a CPU. A single server running Rails will
| easily scale to hundreds of thousands of daily users.
| Most companies never get that many users in the first
| place, and those that do will have the funds to afford
| rewriting the hottest paths in a more performant
| language.
| xerxes901 wrote:
| > Which means your changes have to go through the Ruby team
| first. Any additional changes would also need to go through
| them ...
|
| I do want to pick on this specifically - people can and should
| be patching open source projects they depend on and deploying
| them to production (exactly as described in the article).
| Something being in the language vs in "user" code should be no
| barrier to improving it.
| simonask wrote:
| There's a pretty huge difference between implementing a
| performance optimization that works in your use case, and
| upstreaming that optimization to be generally usable.
|
| The latter is often orders of magnitude more work, and the
| existing solution is probably chosen to be well suited in
| general.
| gmueckl wrote:
| Patching a dependency comes with significant downstream
| costs. You need to carry the patch forward to new upstream
| versions . This implies remembering that the dependency was
| patched, extracting a patch from the existing changed code,
| and reapplying the patch, fixing comflicts, recompiling the
| now special version of that dependency and running tests,
| checking/updating required license notices accordingly.
|
| This is in essence another form of technical dept.
| sys64739 wrote:
| What dashboard software is that?
| mhh__ wrote:
| Looks like grafana
| spullara wrote:
| All the other virtual machines that support GC need to look at
| the JVM's ZGC and Shenandoah. Sub-millisecond pause times with
| terabyte heaps.
| oorza wrote:
| C4 still smokes them both, doesn't it?
| spullara wrote:
| hard to smoke sub-millisecond pauses but there may be other
| axes where it is better. it used to be that people thought
| azul was better because it was generational but now zgc is as
| well. my guess is that c4 doesn't have enough of an edge at
| this point but happy to see benchmarks that prove otherwise.
| algorithmsRcool wrote:
| How much of a throughput penalty do those options incur on the
| application?
| spullara wrote:
| I think it only affects throughput at the limit at the 5%
| level. All the portfolio companies that implemented it got a
| net increase in performance as they avoid redlining their
| servers.
| bob1029 wrote:
| I think we should be careful when correlating heap size with
| how long the collection should take.
|
| Also, I really want ZGC in .NET runtime, but I don't think I'll
| ever get support for it first party. There's some kind of
| principled ideologue holdout situation going on over at
| Microsoft. Every time I get into it with one of their engineers
| I'm sent to some impotent "please may I have a temporary GC
| exemption" API. All I want is it to do _nothing_. How hard is
| it to just not clean up the goddamn garbage? Give me a registry
| flag + env variable + cli arg all required at the same time if
| you 're so worried someone might trip over it.
| reubenbond wrote:
| Would GC.TryStartNoGCRegion work for you?
| https://learn.microsoft.com/en-
| us/dotnet/api/system.gc.tryst...
| neonsunset wrote:
| ZGC does not stand for zero. It stands for Z Garbage
| Collector. It's a next-generation GC implementation for
| OpenJDK that focuses on low pause time while supporting very
| large heap sizes. It does not "not collect garbage".
|
| You could try using https://github.com/kkokosa/UpsilonGC and
| seeing if it still works.
|
| At the end of the day for anything performance-related you
| can just write code with manual memory management with RAII
| patterns via IDisposable on structs and get code that
| performs closely to C++ or Rust. It's also necessary to
| understand if this is a good idea at all - most of the time
| you _do_ want to just rely on GC.
| bob1029 wrote:
| > ZGC does not stand for zero. It stands for Z Garbage
| Collector.
|
| Apologies - I was attempting to referring to "absolutely
| no" garbage collection path. I was thinking of Epsilon [0].
|
| > It's also necessary to understand if this is a good idea
| at all - most of the time you do want to just rely on GC.
|
| Assume we are building a cruise missile flight computer. I
| have enough ram for ~100 hours of flight if we never clean
| up any allocations. I only have enough fuel for 8 hours of
| flight on a good day. Why do I still need a garbage
| _collector_? All I need is a garbage _generator_. The
| terminal ballistics and warhead are the "out of band"
| aspects in this arrangement.
|
| > You could try using https://github.com/kkokosa/UpsilonGC
| and seeing if it still works.
|
| I've spent weeks on this exact thing. I cannot get it to
| work. This gets me back to the first party support aspect.
|
| [0] https://openjdk.org/jeps/318
| byroot wrote:
| We're actually hoping to get mmtK included in Ruby to be able
| to use more advanced GCs. Medium term we hope to use Immix:
| https://bugs.ruby-lang.org/issues/20860
|
| And yes, we're aware of ZGC &co
| https://www.eightbitraptor.com/presentations/RubyKaigi2023-m...
| bitbckt wrote:
| Amazing to see this happening. I wrote the non-moving Immix
| collector at Twitter for our Ruby runtime, Kiji.
|
| Good luck!
| voiper1 wrote:
| > Ideally in a web application, aside from some in-memory caches,
| no object allocated as part of a request should survive longer
| than the request itself. Any object that does is probably
| something that should be eagerly loaded during boot, or some
| state that is leaking between requests. As such, any object
| promoted to the old generation during a request cycle is very
| unlikely to be immortal, so promoting it is wasteful.
|
| So could each request clean up it's own garbage when it finishes,
| so then they should never need any global garbage collection?
| byroot wrote:
| That's pretty much what I'm hinting at at the end when I
| mention minor GC.
|
| I don't think doing it after each request would be sensible,
| but counter intuitively, the time it takes to run GC isn't
| proportional to amount of garbage to collect, but to the number
| of live objects left (ignoring some minor things like
| finalizers).
|
| So on paper at least we could run a minor GC for very cheap
| after each request, but there's likely some better heuristics
| given currently the median request already spent less than 1ms
| in GC, so after every requests might be overdoing it.
|
| Also even if we were doing that, many requests would still have
| to run GC because they allocate more than there is memory
| available, so they need to clean their own garbage to continue,
| you can't delay GC indefinitely.
|
| But at least now, endpoints that spend too much time in GC are
| responsible for their own demise, so engineers responsible for
| a given endpoint performance have a clear signal that they
| should allocate less, whereas before it could easily discounted
| as being caused by lots of garbage left over by another
| collocated endpoint.
| hgo wrote:
| Would it be possible for the allocator/GC to know what
| allocations are made within a request and make a generation
| for specifically for it? Allocations too big to fit would be
| made like usual
| byroot wrote:
| That's already what we effectively have.
|
| Since objects cannot be promoted to the old generation
| inside the request cycle, objects in the new gen are
| request allocated objects.
|
| So if we were to eagerly trigger a minor GC after a
| request, we'd have very little objects to scan, and only
| need to sweep garbage, which is only a small fraction of
| time spent in GC.
| cletus wrote:
| > no object allocated as part of a request should survive longer
| than the request itself
|
| So I've spent a lot of time doing Hack (and PHP) as well as Java,
| Python and other languages. For me, as far as serving HTTP
| requests goes, Hack/PHP are almost the perfect language. Why?
|
| 1. A stateless functional core. There's no loading of large
| libraries, which is an issue with Python and Java in certain
| paradigms. The core API us just functions that mean startup costs
| for a non-stateful service are near zero;
|
| 2. The model, as alluded to the above quote, basically creates
| temporary objects and then tears everything down at the end of
| the request. It's so much more difficult to leak resources this
| way as opposed to, say, a stateful Java or C++ server. PHP got a
| lot of hate unjustly for its "global" scope when in fact it's not
| global at all. "Global" in PHP/Hack is simply request-scoped and
| pretty much every language offers request-scoping;
|
| 3. There's no threading. Hack, in particular, uses a cooperative
| async/await model. Where you'd normally create threads (eg making
| a network request), that's handled by the runtime to make an
| async/await call out of non-blocking I/O. You never have to deal
| with mutexes, thread starvation, thread pools, lock ups, etc. You
| never want to deal with that in "application" or "product" code.
| Never.
|
| So this article is specific to Ruby-on-Rails, which obviously
| still has persistent objects, hence the need for GC still.
|
| How Facebook deals with this is kinda interesting. Most FB
| product code uses an in-memory write-through graph database
| (called TAO, backed to MySQL). There is an entity model in Hack
| on top of this that does a whole bunch of stuff like enforcing
| privacy (ie you basically never talk to TAO directly and if you
| do, you're going to have to explain why that's necessary, and you
| absolutely never talk to MySQL directly).
|
| But the point is that persistent entities are request-scoped as
| well (unlike RoR I guess?).
| BoppreH wrote:
| If the core API is just functions, how do stateful applications
| handle connections to this persistent storage? Can you still
| have a connection pool, or does every request pay the extra
| latency to start a new connection and re-authenticate?
| spullara wrote:
| i think they do now but originally one of the reasons people
| use mysql with languages that are connection per request was
| that mysql connections were very cheap.
| derefr wrote:
| And why pgbouncer used to be considered an essential part
| of a Postgres web-app-backend deployment -- if your
| business layer didn't pool and reuse connections, then
| having an external shim component that pools and reuses
| connections would solve a lot of the impedance mismatch.
___________________________________________________________________
(page generated 2024-11-03 23:01 UTC)