One of the teams I was on solved the pull behavior by having an "immediately publish last known value on subscription" parameter we could pass in when subscribing.
This solved most of our needs around pulling data.
We weren't doing a full FRP system, no composable streams, just building a system in which the only way to communicate was through subscriptions between components.
This worked really well in practice, for example to configure the rate at which the accelerator ran, a component would subscribe to the proper hz publisher, with different publishers existing for supported frequencies. A fancy bit of code handled doing the math needed to deliver all the different subscribers data at their requested rate.
We were running on an embedded micro with 256KB of RAM, so just making everything async and callback based was already pushing the boundaries of the industry. Vendors we worked with got extremely confused when we said they needed to hand us async code, that they had a few milliseconds to run in before they relinquished control, and that busy loops were verboten.
I really miss working in a code base where every component can be trivially subscribed to.
On the flip side, I've seen subscriptions taken too far, as people make every single value on a form a separate subscription. Seriously, it is A-OK to give the First and Last names together when the user hits submit.
This solved most of our needs around pulling data.
We weren't doing a full FRP system, no composable streams, just building a system in which the only way to communicate was through subscriptions between components.
This worked really well in practice, for example to configure the rate at which the accelerator ran, a component would subscribe to the proper hz publisher, with different publishers existing for supported frequencies. A fancy bit of code handled doing the math needed to deliver all the different subscribers data at their requested rate.