node js - debugging the event loop - javascript

In my express.js project everything works fine, but having several routing files an other function files, I feel a bit like drowning in all the functions, not knowing which functions run, when, and by which caller.
For example, I have two functions that may run too many times in event loop: the router.use which I see as a constructor to all related routes (from which I want to filter out some), and verify token function that should run only when certain conditions are met, such as API calls, or regular calls that detect admin cookie etc.
I'm trying to generate a log that can help me find which functions are called more than once and by which caller.
Sort of like a map per event.
I use console.log to see order and current call url when firing an event, and I also use node-inspector's breakpoints to see how many times functions like router.use are called, but when manually following the functions in node-inspector, many node core files are involved in the process, which makes the task more tedious because I am interested to debug only my functions... and it doesn't let me see the bigger picture, more readable information on a zoomed out perspective.
What is the preferable method to generate such a log/report?

Related

fs.watch fires three times instead of expected two

I'm aware from this other StackOverflow answer that fs.watch() fires twice on some operating systems (I'm on Windows 11). The weird thing though however, is that while fs.watch() fires twice for me with a new setup and almost empty file, it fires three times for me when I'm running it in a complex/large script. Here is my complex script. I don't believe that it's a loop cycle issue, because 1) it returns console.logs in my fs.watch() function 2) it returns console.logs() directly inside the function that should be run after fs.watch() is triggered. For those interested I put a console.log() between these lines.
To put it into summary, I'd like to know whether three pulses is expected behavior on top of stated two pulses, and if it's not normal behavior, how to fix my code to restrict it only to two pulses, if possible.
This issue is described as expected behavior here.
What you see as "one" modification is really numerous calls to the Win32 API. Since there is no transaction to bucket all of the calls together, the filesystem is forced to send out multiple notifications for various kernel calls.
So when using fs.watch on Windows, expect multiple calls to be made for a single modification.
Chokidar is the only alternative I know of which does watching very well.

Refactoring websocket code that uses global variables into events / async programming

There's a bit of someone else's code I am trying to add functionality to. It's using websockets to communicate with a server which I will most likely not be able to change (the server runs on a 3$ micro-controller...)
The pattern used, for instance when uploading data to the server, consists in using global variables, then sending a series of messages on the socket, as well as having an 'onmessage' which will handle the response. This seems clumsy, given that it assumes that there is only ever one socket call made at a time (I think the server guarantees that in fact). The messages sent by the server can be multiple, and even figuring out when the messages are finished is fiddly.
I am thinking of making things so that I have a better handle on things, mostly w.r.t. being able to know when the response has arrived (and finished), going to patterns like
function save_file(name, data, callback) {
}
And perhaps at some point I can even turn them into async functions.
So couple of ideas:
- is there some kind of identifier that I could find in the websocket object that might allow me to better string together request and response?
- short of that, what is the right pattern? I started using custom events, that allows me to much better tie the whole process, where I can supply a callback by attaching it to the event, but even doing removeEventListener is tricky because I need to keep reference to every single listener to make sure I can remove them later.
Any advice anyone?

Achieving UI/logic separation when the logic requires callback functions

As far as I understand, in good practice, the UI code should invoke the logic whenever needed, but the logic should know nothing about the GUI ("loose coupling", see for example How can I separate the user interface from the business logic while still maintaining efficiency?).
I am currently writing a chrome web app that uses the chrome.serial api. Most functions from this api are non-blocking and instead invoke a callback function when their work is done. For example
chrome.serial.getDevices(callback)
searches for devices and than calls callback with a list of found devices.
Now, after chrome.serial.getDevices is called from the logic part of my code, its results ultimately have to be communicated back to the UI code.
How do I achieve clean UI/logic separation in this case? Does my UI need to register callback funcions with my logic code for every call it makes? That seems to violate the above principle of loose coupling and feels like it becomes very confusing very quickly.
You can use Promises. Initiate them in your controller code and pass them to the view. The view will then call its .then() method and display the result.
For example:
//controller.js
myAsyncTask = new Promise(resolve,reject=>{
chrome.serial.getDevices(resolve)
})
view(myAsyncTask);
//view.js
function view(myAsyncTask){
myAsyncTask.then(render);
}
If you are using build tools, such as Webpack or Browserify, then you can have your "logic object" extend Node's EventEmitter (there are other implementations that work in-browser, such as https://github.com/Olical/EventEmitter, if you don't want to bundle Node APIs in with a build tool).
Your "logic object", which is a specialized EventEmitter, operates the chrome async API, which contacts the serial devices, then processing the results according to your data layer rules, and then emits its own events when it has something useful for the UI.
The UI listens both listens to, and emits, events on your "logic object", depending on what's happening. Bonus: this event emitter can also be used by separate UI objects to communicate to each other, via events.
EventEmitter is the key that will make this kind of separation feel clean, simple, and extendable.

Can Firebase transform data server-side before writing it?

According to this documentation, and this accompanying example, Firebase tends to follow the following flow when transforming newly written data:
Client writes data to Firebase, which is immediately accepted
The supplied Cloud Function is triggered, which transforms the data (in the example above, it removes swear words)
The transformed data is written again, overwriting the original data written in step 1
Maybe I'm missing something here, but this flow seems to present some problems. For example, if there is an error in step 2 above, and step 3 is never fired, the un-transformed data will just linger in the database. It seems like it would be better to transform the data as soon as it hits the server, but before writing. This would be followed by a single write operation, which will leave no loose artifacts behind if it fails. Is there any way in the current Firebase + Google Cloud Functions stack to add these types of pre-write data transforms?
My (tentative and weird) solution so far is to have a "shadow" /_temp/{endpoint} area in my Firebase db, so that when I want to write to /{endpoint}, I write there instead, which then triggers the relevant cloud function to do the transformation before writing to /{endpoint}. This at least prevents potentially incomplete data from leaking into my database, but it seems very inelegant and "hacky."
I'd also be interested to know if there are any server-side methods for transforming data before responding to read requests.
There is no hook in the Firebase Database (neither through Cloud Functions nor elsewhere) that allows you to modify values before they're written to the database. The temporary queue is the idiomatic way to address this use-case. It functions pretty similar to a moderator queue in most forum software.
You could use a HTTP Function to create an endpoint that your code calls and then perform the transformation there. You could use a similar pattern for reading data, although you'd have to rebuild the realtime synchronization capabilities of Firebase yourself.

Are Mutexes needed in javascript?

I have seen this link: Implementing Mutual Exclusion in JavaScript.
On the other hand, I have read that there are no threads in javascript, but what exactly does that mean?
When events occur, where in the code can they interrupt?
And if there are no threads in JS, do I need to use mutexes in JS or not?
Specifically, I am wondering about the effects of using functions called by setTimeout() and XmlHttpRequest's onreadystatechange on globally accessible variables.
Javascript is defined as a reentrant language which means there is no threading exposed to the user, there may be threads in the implementation. Functions like setTimeout() and asynchronous callbacks need to wait for the script engine to sleep before they're able to run.
That means that everything that happens in an event must be finished before the next event will be processed.
That being said, you may need a mutex if your code does something where it expects a value not to change between when the asynchronous event was fired and when the callback was called.
For example if you have a data structure where you click one button and it sends an XmlHttpRequest which calls a callback the changes the data structure in a destructive way, and you have another button that changes the same data structure directly, between when the event was fired and when the call back was executed the user could have clicked and updated the data structure before the callback which could then lose the value.
While you could create a race condition like that it's very easy to prevent that in your code since each function will be atomic. It would be a lot of work and take some odd coding patterns to create the race condition in fact.
The answers to this question are a bit outdated though correct at the time they were given. And still correct if looking at a client-side javascript application that does NOT use webworkers.
Articles on web-workers:
multithreading in javascript using webworkers
Mozilla on webworkers
This clearly shows that javascript via web-workers has multithreading capabilities. As concerning to the question are mutexes needed in javascript? I am unsure of this. But this stackoverflow post seems relevant:
Mutual Exclusion for N Asynchronous Threads
Yes, mutexes can be required in Javascript when accessing resources that are shared between tabs/windows, like localStorage.
For example, if a user has two tabs open, simple code like the following is unsafe:
function appendToList(item) {
var list = localStorage["myKey"];
if (list) {
list += "," + item;
}
else {
list = item;
}
localStorage["myKey"] = list;
}
Between the time that the localStorage item is 'got' and 'set', another tab could have modified the value. It's generally unlikely, but possible - you'd need to judge for yourself the likelihood and risk associated with any contention in your particular circumstances.
See the following articles for a more detail:
Wait, Don't Touch That: Mutual Exclusion Locks & JavaScript - Medium Engineering
JavaScript concurrency and locking the HTML5 localStorage - Benjamin Dumke-von der Eh, Stackoverflow
As #william points out,
you may need a mutex if your code does something where it expects a
value not to change between when the asynchronous event was fired and
when the callback was called.
This can be generalised further - if your code does something where it expects exclusive control of a resource until an asynchronous request resolves, you may need a mutex.
A simple example is where you have a button that fires an ajax call to create a record in the back end. You might need a bit of code to protect you from trigger happy users clicking away and thereby creating multiple records. there are a number of approaches to this problem (e.g. disable the button, enable on ajax success). You could also use a simple lock:
var save_lock = false;
$('#save_button').click(function(){
if(!save_lock){
//lock
save_lock=true;
$.ajax({
success:function()
//unlock
save_lock = false;
}
});
}
}
I'm not sure if that's the best approach and I would be interested to see how others handle mutual exclusion in javascript, but as far as i'm aware that's a simple mutex and it is handy.
JavaScript is single threaded... though Chrome may be a new beast (I think it is also single threaded, but each tab has it's own JavaScript thread... I haven't looked into it in detail, so don't quote me there).
However, one thing you DO need to worry about is how your JavaScript will handle multiple ajax requests coming back in not the same order you send them. So, all you really need to worry about is make sure your ajax calls are handled in a way that they won't step on eachother's feet if the results come back in a different order than you sent them.
This goes for timeouts too...
When JavaScript grows multithreading, then maybe worry about mutexes and the like....
JavaScript, the language, can be as multithreaded as you want, but browser embeddings of the javascript engine only runs one callback (onload, onfocus, <script>, etc...) at a time (per tab, presumably). William's suggestion of using a Mutex for changes between registering and receiving a callback should not be taken too literally because of this, as you wouldn't want to block in the intervening callback since the callback that will unlock it will be blocked behind the current callback! (Wow, English sucks for talking about threading.) In this case, you probably want to do something along the lines of redispatching the current event if a flag is set, either literally or with the likes of setTimeout().
If you are using a different embedding of JS, and that executes multiple threads at once, it can get a bit more dicey, but due to the way JS can use callbacks so easily and locks objects on property access explicit locking is not nearly as necessary. However, I would be surprised if an embedding designed for general code (eg, game scripting) that used multi threading didn't also give some explicit locking primitives as well.
Sorry for the wall of text!
Events are signaled, but JavaScript execution is still single-threaded.
My understanding is that when event is signaled the engine stops what it is executing at the moment to run event handler. After the handler is finished, script execution is resumed. If event handler changed some shared variables then resumed code will see these changes appearing "out of the blue".
If you want to "protect" shared data, simple boolean flag should be sufficient.

Categories