I'm trying to wrap my head around CF's async featu...
# adobe
r
I'm trying to wrap my head around CF's async feature with Futures and am really struggling. I absolutely grok async in JS, but every example is showing sync/simple examples (like return 5). Does anyone have a real example of this feature that shows the benefit?
s
There's a bit of irony there since JS isn't multi-threaded and async operations are managed by the host engine, but CF's async features are genuinely multi-threaded -- which I think is a lot easier to understand because it actually does what it says on the tin. Can you elaborate where you're struggling? You'd normally reach for multi-threaded stuff on the JVM when you have multiple pieces of work you need done and some of them are slow and they can be done concurrently. For example, complex database queries, or HTTP calls to external services.
r
so concurrency - in all the examples ive seen in the docs, its chained: do async 1, then 2, then 3. there's no examples of, lets say, do a HTTP call to X and Y at the same time, when both are done, do Z
s
If it is chained, it ain't "concurrent" by definition.
r
right! 🙂 and yet every sample in the docs shows that
even the Ortus "modern cf" book showed that
s
Can you point to one of those examples? Sounds like they were written by someone who knows JS but not JVM...
s
Jeez, those are terrible examples 😞
r
thank you 🙂
thought i was missing something
s
You may have more luck searching for java completeablefuture examples and tutorials... which is basically what runAsync() does.
r
cool, but would still like to know if anyone has a CFML example
s
I doubt it. I don't think many CFers are doing heavy concurrent stuff.
I guess my question would be: why are you digging into this in CF?
TBH, CF's facilities for concurrent code has always been pretty crappy.
runAsync()
is kind of a dumb API over Java's
CompleteableFuture
so it's about the best CF has had so far.
An example from work (which is Clojure but would map to CF well), is a reporting function that has three big, complex SQL queries in it. The function kicks off each query in a future (
runAsync()
in CF) and then calls
.get()
on each of those three futures to get the query result back. Each SQL query will run in a separate thread and the main thread will then wait for each thread to finish, so it'll run in the time of the slowest query rather than the sum of the time of the three queries. Or you could run two queries in futures, and run one in the main thread, and then wait on the other two. Uses one less thread but also means the main thread can't do other work while the queries are running (we actually run a couple of simple queries one after the other in the main thread because we know their total time will be less than the slowest of the three big queries. Does that help frame a real world situation @raymondcamden?
r
sure... i mean, i do think i get concurrency- as i said though - im just surprised the samples are so bad. i dont need this for any reason outside of curiosity 🙂
s
I'm not surprised the samples are so bad. I'm a bit surprised that you're surprised 🙂 I mean, you've been around the CF community long enough... you should expect terrible sample code!
r
im trying to be nice 🙂
w
i have one example but it's a bit complex (and it's the only one i have). needed to use futures for a publishAndWait() method in a rabbitmq based app. ultimately, i didn't feel i got the async stuff in cf until i abandoned the vanilla runAsync stuff in favor of using cbFutures, which i added to my non-framework app by way of adding logbox to it and leveraging it from there
j
Hi @seancorfield - any change of collaborating / pointing this out to @bdw429s & co. if the examples are bad in your opinion so it gets improved - after all, afaik, Ortus books are pretty much considered one of the "most modern"* cfml learning resource out there which I try to learn from often (*at least that's my impression (but I consider myself very much a non-expert compared to all of you, lol!) ). 🙂 PS @raymondcamden - it's great to receive your newsletters, thank you for your work & everyone have a great rest of the week!
s
I don't know who actually writes/maintains the Ortus books but I'm happy to provide feedback if they ask for it 🙂
👍 1
b
@lmajano wrote most of the modern CFML book, but I assume those
runasync()
examples may have come from the Adobe docs. The source for the book is here https://github.com/ortus-docs/Modern-ColdFusion-CFML-In-100-Minutes/blob/master/beyond-the-100/asynchronous-programming.md Pull requests welcome 🙂 That said, we've never really used runasync() at Ortus and don't care much for it. We've written our own async framework as a direct wrapper around Java's Completable Futures which we prefer and is documented in part here: https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming which allow for things like this:
Copy code
// Parallel Executions
async().all(
    () => <http://hyper.post|hyper.post>( "/somewhere" ),
    () => <http://hyper.post|hyper.post>( "/somewhereElse" ),
    () => <http://hyper.post|hyper.post>( "/another" )
).then( (results)=> logResults( results ) );
If you scroll down on that last page, we actually cover the main difference between cfthread, runasync, and our AsnyncManager (which comes with ColdBox, WireBox, CacheBox, and LogBox.) We tapped into much of the concurrent package and even have a task scheduling engine in ColdBox built on scheduled executors: https://coldbox.ortusbooks.com/digging-deeper/promises-async-programming/scheduled-tasks Anyway, long story short, we've never been super impressed with any of CFML's built in threading and have basically built our own wrappers around the JDK's to harness what it offers.
s
Makes sense. I wouldn't recommend
runAsync()
to anyone either...
m
@saghosh we might want to see if we could get some better concurrent async examples into our docs to better show the capabilities. Let's connect next week on this.
s
Thanks @Mark Takata (Adobe) I'll set up a 1:1 with you.
❤️ 1