davery22
- Shirky Principle: Institutions will try to preserve the problem to which they are the solution
- Chesterton's Fence: Changes should not be made until the reasoning behind the current state of affairs is understood
- Rule of Three: Refactoring given only two instances of similar code risks selecting a poor abstraction that becomes harder to maintain than the initial duplication
- https://github.com/frankmcsherry/blog/blob/master/posts/2025...
If I try to service a snapshot with a push system, I'll have to either buffer an unbounded number of events, discard events, or back-pressure up the source to prevent events from being created. And with push alone, my snapshot would still only be ephemeral; once I open the floodgates and start processing more events, the snapshot is gone.
If I try to service a live view with a pull system, I'll have to either pull infrequently and sacrifice freshness, or pull more frequently and waste time and bandwidth reprocessing unchanged data. And with pull alone, I would still only be chasing freshness; every halving of refresh interval doubles the resource cost, until the system can't keep up.
The complicating real-world factor that this article alludes to is that, historically, push systems lacked the expressiveness to model complex data transformations. (And to be fair, they're up against physical limitations: Many transformations simply require storing the full intermediate dataset in order to compute an incremental update.) So the solution was to either switch wholesale to pull at some point in the pipeline (and try to use caching, change detection, etc to reduce the resource cost and enable more frequent pulling), or, introduce a pulling segment in the pipeline ("windowing" joins, aggregations, etc) and switch back to push after.
It's pretty recent that push systems are attempting to match the expressiveness of pull systems (e.g. Materialize, Readyset), but people are so used to pull-based compromises that they're not looking out for natural live view use cases.
Go forth, use (parallel) streams with confidence, and don't run out of memory.
The Java Streams Parallel
Show HN: Vinyl: Relational Streams for Java
https://github.com/davery22/vinyl
Vinyl extends Java Streams with relational operations. I wanted to try a different approach than what I'd found in the wild, to get at a solution that feels good. Vinyl offers type-safe access without type bloat. It offers an extremely expressive API without scores of opinionated methods to learn. It integrates with the Streams we already have, and plays nice with parallelism. If we can do it...