wamp.rt
wamp.rt copied to clipboard
Cleanup callrpc on socket disconnect.
We run the router on a relative low embedded device ( < 300mhz ), and it also host a little nodejs webserver for an webapplication with need to support concurrent users. We trigger nodejs functions from an webapplication, that are relative slow (inherit of the device's cpu).
We call the remote procedures from the webapplication, and than it will hit the nodejs functions, that it turn will trigger a c++ application. We log the calls in the c++ application, so we can see what calls are made.
However, I've noticed that we can, for example, 'attack' the router with 1000 calls from one client/socket, and than disconnect, the router still takes a long time processing the call list, even thought there is no socket to respond on. For quite some times the c++ application keeps logging it is working on collecting data for a callback that is insoluble.
As far as I can see, that means the function from router.js:
will be hit 1000 times, and so the list _pending contains a 1000 callbacks,
So imagine client A creates 1000 calls, and than disconnect, it can't respond quick on client B because it still processes events from client A. I can't see the relationship of the cleanup function done with _session[id].cleanup() and the _pending[invId] = callbacks, or in other words the router is still working on stuff that will never be resolved.
Is this how it works ? If not, how can I instantly drop the 1000 callback associated with that session ? (and thus will never call the slow c++ functions to begin with)
The problem really is with (slow) async funtions, we for example request some data on page A, and try to display a graph when we are supplied with that data (~1/2 sec), but the user already goes to page B. As far as I know the router will still contains the pending callback and still processes it, even thought there is no use to this data anymore.
Note, everything in the UX is cached, so that at least looks fast at the moment, but we still need to hit the 'expensive' (1-2 sec) call to ensure the data is up to data, and update according, so the need to request it every page-hit still exist because of the concurrent users we would like to support.
Is there something that could be of help ?
(please note, I'm aware the device itself is stretching the requirements of nodejs already, however that isn't really that can be changed at this point )
Yes, when closing session, the list of pending calls is not cleaned. Pending calls are not associated with a session, what is needed to clear pending on session closing. I'll try to fix that.
Also, what I see is that client A can create 1000 pending calls, and if client B wants to join...to bad, it will work first on the 1000 calls first before client B get even a change. Perhaps it is an idea to priorities them based on client, so instead of adding them to the pending list, perhaps we can inject them based on the calling's client socket, (client-socket is 1-1 in my assumption),
This animation explains it a lot quicker, just see every stack element as a call-promise, and the circle as the cursor. The names right from that are the origin of that call-promise. 