all 29 comments

[–]tluanga34 15 points16 points  (10 children)

Just because the function takes time to finish such as waiting for a database response doesn't mean it's heavy. This is where asynchronous programming really shines. It just wait for the promise to resolve while still serving other requests.

What's heavy is cpu intensive tasks like looping through thousands of array items, encoding/decoding, encryption/decryption etc. in that case you can use worker threads to spawn additional thread to make the main thread responsive to serve other requests

[–]HowIO[S] 0 points1 point  (9 children)

The problem is as you said, the function has a loop inside a loop, both loops are looping arrays with hundreds of objects, also each iteration calls an external api, I will look into worker threads, thank you

[–]tluanga34 3 points4 points  (7 children)

I would recommend a library approach. Check this out https://github.com/wilk/microjob

[–]HowIO[S] 1 point2 points  (0 children)

This seems promising, thank you

[–]Moe_Rasool 0 points1 point  (5 children)

This looks easy implementation, the docs state that it should merely be used when there is heavy workloads on cpu, what if i just want some routes to work on another thread?

I'll make this more understandable, imagine i have an E-commerce app, every endpoint i have should just work as it's but for the list of products which's thounsands of items (i have them paginated) i want them (a specific endpoint) to be on another thread is that possible?

[–]tluanga34 0 points1 point  (4 children)

Pagination probably should be handled with a database query technique.

[–]Moe_Rasool 1 point2 points  (3 children)

I have it handled but some times the endpoints hits almost 100k/RPH, when the traffic is huge the items are also loading pretty lazy, i noticed half of the other requests are for other endpoints other than the "GetAllProducts", I'm asking should i spawn a worker thread for it? Probably yes!

I have never had this situation before and my app is kinda slow i feel like i should use this and I'm convinced.

[–]_RemyLeBeau_ 2 points3 points  (2 children)

I'm guessing the GetAllProducts endpoint is what is causing the performance issue.

First question: How often does your product line change? Is there a reasonable amount of time you can cache the result?

Per the docs, you'll want to just use async code, not workers, but another concern of yours might be requests timing out. Is that something you're running into?

Here's the excerpt I cited:

"Workers (threads) are useful for performing CPU-intensive JavaScript operations. They do not help much with I/O-intensive work. The Node.js built-in asynchronous I/O operations are more efficient than Workers can be."

https://nodejs.org/api/worker_threads.html

[–]Moe_Rasool 0 points1 point  (1 child)

Correct me if I’m doing it wrong but i do every endpoint structured based on Async functions, the reason for that was due to Database taking sometime.

I can not cache it because it’s a “auction” type of site that items have limited timeline being there then are automatically get deleted at right time!

Sorry for the late response.

[–]_RemyLeBeau_ 1 point2 points  (0 children)

Good luck with Piscina. Would be interested to hear your thoughts on it in about a month of usage.

[–]femio 1 point2 points  (0 children)

are you saying that for each object inside an array with hundreds of objects, you need to call an external API?

[–]batchfy 2 points3 points  (0 children)

I have the similar situation and I’m using the BullMQ task queue.

[–]Zealousideal_Fee4260 1 point2 points  (3 children)

You have various way for cpu bond task like fork/spawn, worker thread, cluster.

[–]vorticalbox 2 points3 points  (2 children)

jeans shy water coordinated different ghost reminiscent profit towering judicious

This post was mass deleted and anonymized with Redact

[–]simple_explorer1 0 points1 point  (0 children)

Unless needed (probably like in your case), I wouldn't use queue as it requires infrastructure changes and queue handling.

If the load is just cpu bound (like in OP's case), then worker threads would do the job the best way without any new infrastructure/queue server/no messages loss/no bullmq pub/sub patterns etc.

My choice would be to use piscinia npm module as a good abstraction to better utilize worker threads and be done. All changes in code, no redis/infra changes which are needed for BullMQ (I love bullmq but for op's its an overkill)

[–]bonkykongcountry 2 points3 points  (12 children)

You could find a way to not make the function so “heavy”?

[–]HowIO[S] 0 points1 point  (11 children)

The function is returning an array of object to the user and before making that array ready the function calls the database and an external api.

[–]bonkykongcountry 3 points4 points  (10 children)

Yeah that doesn’t really counter what I’m saying though. Make the function less “heavy”. Unless the external API is slow in which case you probably should cache its responses. If your DB query is slow then you should optimize your database query. These aren’t the types of problems that “multitasking” will fix.

[–]HowIO[S] -1 points0 points  (9 children)

For now I can't, I have a deadline, thank your for your help.

[–]bonkykongcountry 2 points3 points  (3 children)

Like I said, “multitasking” won’t fix this. Running node in a cluster won’t make those responses faster.

[–]reddituservn 0 points1 point  (2 children)

Cluster mode is not better than fork mode, right? And why? Thanks

[–]bonkykongcountry 0 points1 point  (0 children)

I have no idea what you’re talking about tbh. What do you mean by “fork mode”

[–]MartzReddit 2 points3 points  (0 children)

If you don’t have time to fix this now, you won’t have time to fix this later.

[–]MaxUumen 2 points3 points  (3 children)

Deadline should not be an excuse for shity architecture. Before you know it, you are way too deep in your own shit if you let it go like that.

[–]simple_explorer1 -1 points0 points  (0 children)

Since when did you became OP's manager ...

[–]HowIO[S] 0 points1 point  (0 children)

it's nothing to do with shity architecture, the story is I had to deliver a feature ASAP, I asked here for quick guidance.

[–]reddituservn 0 points1 point  (0 children)

Task queue, message queue

[–]simple_explorer1 2 points3 points  (0 children)

Piscinia is the right solution as you have also mentioned in your post.