A really handy feature of the arrayEach()
function is the parallel argument. It has been supported in Lucee since 4.5, but ColdFusion 2021 now supports it as well.
What does the arrayEach
function do?
Quite simply it loops over each element of an array and invokes a function for each element of the array, here's a simple example:
fruit = ["Apples", "Oranges"]; arrayEach(fruit, function(item) { writeOutput("I like #item#
"); });
It would output (run on trycf):
I like Apples I like Oranges
Make it parallel
Recently on the cfml slack the question was asked:
Anybody have a good examples of using the parallel features or multi-threading <cfhttp> requests?
Yes, you can do this with the parallel argument of array each quite easily:
requests = [ {"url"="https://httpbin.org/ip"}, {"url"="https://httpbin.org/uuid"}, {"url"="https://httpbin.org/uuid"}, {"url"="https://httpbin.org/uuid"}, {"url"="https://httpbin.org/uuid"} ]; maxThreads = 5; parallel = true; tick = getTickCount(); arrayEach(requests, function(value, index) { var httpResult=""; cfhttp(url=value.url, result="httpResult"); value.result = httpResult.fileContent; }, parallel, maxThreads); writeOutput("Took: #getTickCount()-tick# with parallel: #parallel#, maxThreads: #maxThreads#
"); writeDump(requests);
You can run the example on trycf and see that when parallel = true;
it runs in about 180ms, when you set parallel = false;
it takes 750ms.
Pretty simple way to get a big speed boost for that use case, and much easier than using cfthread
.
Things to look out for
One thing you do need to be careful of when you start multithreading is synchronization issues. In my example I am updating the array element struct, but if I were modifying the array itself, or another shared variable within my closure function, I would need to use cflock.
For the same reasons, if you create any variables within your closure function, make sure they are var
scoped or you will run into some strange issues. Without the var scope, the variable will be in the variables scope and shared among all the iterations.
Comments
I thought arrays in ColdFusion were synchronized by default. In that case, would to still need to use cflock when modifying the array itself?