Suppose you're new to a project that uses a lot of AJAX requests and other asynchronous methods (e.g. Observable subscriptions). If you're seeing an intermittent issue, and you suspect the problem is due to the timing of AJAX responses and resulting observable updates, how would you even begin debugging this?
Here's what I've done. First, I drew sequence diagrams for the relevant code. Then I tried to imagine scenarios that would cause problems, like out-of-order AJAX responses. This takes a lot of time, so instead I often try introducing delays into various REST endpoints in an attempt to expose the problem consistently. Another shotgun-debugging technique I've tried is logging all events and observable updates, but this is way too verbose to be practical.
Is there a better way? It's hard to visualize all of the complexity, and coming up with potential causes just seems like a shot in the dark.
Simply put, you HAVE to document all your async dependencies and then you have to code to make absolutely sure that regardless of timing, all your dependencies are fulfilled. This is the place to start. If this information isn't 100% known, then you can't even begin to ensure the design is correct.
So, this means figuring out exactly which operations are independent and can run on their own and complete whenever and which operations have dependent async operations that must complete first. For the operations which have dependencies, you MUST make sure the code enforces that dependency. This isn't the step where you imagine out of sequence operations or weird timing. This is the step where you fully understand and document for every async operation what has to complete before this operation can either be started or before the result can be processed.
Promises are often a nice architecture for both stating dependencies in the code and then enforcing that dependency.
So, if a and b must complete before c runs, then you have to code such that your code enforces that dependency.
I would NOT suggest that you just try to test the heck out of it to "find" all the problems. Not only is that hard to do, but it isn't really the structured way to make sure you understand the design requirements and that you have code designed to implement those design requirements.
Once you think you fully understand what is required and think you have implemented it, then and only then is the time to start figuring out if you can test what you've built to see if it reacts the way you expect and also as a check to see if you've missed any dependencies. This is the step where you start figuring out how to create out of sequence results in order to test your dependencies. But, you're only doing this to test if the dependencies you've already identified and coded for are working and implemented properly, not to find new things to design for.
If you have a project with a lot of async operations, I would strongly suggest that you use some sort of library to help you manage those async operations and dependencies between them. Depending upon what else you're using in your project and whether it's client or server, you have many different choices. The whole promise architecture looks like it's one of the main design directions this type of thing is headed in the future - ES6 will have promises built-in, many libraries like jQuery have some sort of promises implementation built in, etc... Promises allow you to either sequence async operations or declare that multiple async operations must complete before starting the next one and so on.
One more thing. Once you've identified a problem and need help debugging it, you often cannot use breakpoints in the code because they tend to just mess up the timing of everything that comes afterwards which totally changes the very situation you're trying to look at (kind of like a Heisenberg uncertainty principle for async debugging). As such, I tend to resort to detailed logging so once you see a problem, you can go back and study the logs and see what actually happened. With a more detailed understanding of what might have happened, you can then often either add more targeted logging or perhaps then set a breakpoint to examine the issue or maybe by then, you'll see what dependency in the code you don't have working right or missed that you had to code for.
"Welcome friend, to the asynchronous world of AJAX", that's my opening statement to you...
In short, you need a debugger and a truck load of breakpoints. Get firebug for Firefox my friend or try the google chrome developer console (hit F12 when using Chrome!). Both of these debugger are great for examining responses from the server, the timing and breaking during code execution. They also allow you to examine the object structure if you're working with JSON which saves hours of mentally picturing problems, literally.
My honest advice is:
Get Firebug or Use Chrome's Developer console
Set breakpoints in the script and watch the logical flow and paths of execution of your code.
Fix/Adjust/Re-order code blocks, then repeat step 1 and 2.
This may take time, cause you to restructure your scripts a lot, but it is definitely better than setTimeouts, setIntervals or other shotgun techniques, which will break down if the server responses take longer than usual.
Related
It looks like I'm asking about a tricky problem that's been explored a lot over the past decades without a clear solution. I've seen Is It Possible to Sandbox JavaScript Running In the Browser? along with a few smaller questions, but all of them seem to be mislabeled - they all focus on sandboxing cookies and DOM access, and not JavaScript itself, which is what I'm trying to do; iframes or web workers don't sound exactly like what I'm looking for.
Architecturally, I'm exploring the pathological extreme: not only do I want full control of what functions get executed, so I can disallow access to arbitrary functions, DOM elements, the network, and so forth, I also really want to have control over execution scheduling so I can prevent evil or poorly-written scripts from consuming 100% CPU.
Here are two approaches I've come up with as I've thought about this. I realize I'm only going to perfectly nail two out of fast, introspected and safe, but I want to get as close to all three as I can.
Idea 1: Put everything inside a VM
While it wouldn't present a JS "front", perhaps the simplest and most architecturally elegant solution to my problem could be a tiny, lightweight virtual machine. Actual performance wouldn't be great, but I'd have full introspection into what's being executed, and I'd be able to run eval inside the VM and not at the JS level, preventing potentially malicious code from ever encountering the browser.
Idea 2: Transpilation
First of all, I've had a look at Google Caja, but I'm looking for a solution itself written in JS so that the compilation/processing stage can happen in the browser without me needing to download/run anything else.
I'm very curious about the various transpilers (TypeScript, CoffeeScript, this gigantic list, etc) - if these languages perform full tokenization->AST->code generation that would make them excellent "code firewalls" that could be used to filter function/DOM/etc accesses at compile time, meaning I get my performance back!
My main concern with transpilation is whether there are any attacks that could be used to generate the kind code I'm trying to block. These languages' parsers weren't written with security in mind, after all. This was my motivation behind using a VM.
This technique would also mean I lose execution introspection. Perhaps I could run the code inside one or more web workers and "ping" the workers every second or so, killing off workers that [have presumably gotten stuck in an infinite loop and] don't respond. That could work.
The Express node.js server application I'm currently developing will sometimes go off into the void and stops returning requests. I very much suspect somewhere in it I am doing something that is ultimately skipping a res.end that I need to be doing.
Does anyone have any tips or tricks on how to best go about looking for where I'm missing the res.end (assuming that's the problem)? Is there anyway to view the currently open requests in real time in the node event loop?
When things hang up, everything is still running in that Express will still accept incoming requests. And, these requests are logged to the console via express.logger just fine. But, the request is never returned to the client and no error is being thrown.
Thank you in advance for your thoughts.
Follow-up:
There doesn't seem to be much documentation on node's debug mode beyond the raw API docs. I did find this article which seems to provide a good overview of several options. But, there doesn't seem to be the kind of thing I was thinking of for watching the event loop, something a la vtop's process list.
More Follow-up:
Yesterday, Daniel Hood published Debugging in Node.js stating that, "The state of debugging node.js apps has always been a bit unfortunate..." So, perhaps my question is not so silly as to merit down votes as it might seem. Anyway, in his next article he promises to cover some tools for debugging asynchronous operations.
I posted the last article you mentioned. If you need to debug async stuff, I'll be going over things like long stack traces (modules such longjohn), the try-catch module, and things like zones/domains. Hopefully those links will be of some help (might be a week before I write part 2).
However, for your particular issue, have you tried setting a breakpoint at some known location and stepping through the process? This way you can just watch how the app is executed, and maybe find where some function is returning nothing when it should be returning the req/res object.
If it isn't very reproducible, maybe some simple logging would be helpful.
Here is the situation: A complex web app is not working, and it is possible to produce undesired behavior consistently. The cause of the problem is not known.
Proposal: Trace the execution paths of all javascript code. Essentially, produce two monstrous logs which can then be fed into a diff algorithm to determine where the behavior related to the bug begins to diverge (as the cause is not apparent from application behavior, and both comprehending and obtaining a copy of the actual JS code being run is difficult, due to the many pages that must be switched to and copied out from the web inspector. Making it difficult is the fact that all pages are dynamically spliced together with Perl code, where significant portions of JS code exist only as (dynamic...) Perl strings).
The Web Inspector in Chrome does not have an option that I know about for logging an execution trace. Basically what I would like is a log of every line of JS that is executed, in the order that they are executed. I don't see this as being a difficult thing to obtain given that the JS VM is single-threaded. The problem is simply that the existing user-facing tools are not designed for quite this much hardcore debugging. If we look at the Profiler in the Dev Tools, it's clearly capable of the kind of instrumentation that I need, but it is fundamentally designed to do profiling instead of tracing.
How can I get started with this? Is there some way I can build Chrome from source, where I can
switch off JIT in V8?
log every single javascript expression evaluated by V8 to a file
I have zero experience with the development side of Chrome. So e.g. links to dev-builds/branches/versions/distros of Chrome/Chromium/Canary (what's the difference?) are welcome.
At this point it appears that instrumenting the browser with powerful js tracing is still likely to be easier than redesigning the buggy app. The architecture of the page is a disaster, but the functionality is complex, and it almost fully works. I just have to find the one missing piece.
Alternatively, if tools of this sort already exist, what are some other keywords I can search for them with? "Code Tracing" is pretty much the only thing I can come up with.
I tested dynaTrace, which was a happy coincidence as our app supports IE (indeed Chrome support just came out of beta), but this does not produce a text dump, it basically produces a massive Win32 UI expando-tree, which is impossible to diff. This makes me really sad because I know how much more difficult it was to make the representation of the trace show up that way, and yet it turns out being almost utterly useless. Who's going to scroll up and down that tree view and see anything really useful in it, in anything other than a toy example of a web app?
If you are developing a big web app, it is always good to follow a test driven strategy for the coding part of it. Using just a few tips allows you to make a simple unit testing script (using QUnit) to test pretty much all aspects of your app. Here are some potential errors and some ways of solving them.
Make yourself handlers to register long living Objects and a handler to close them the safe way. If the safe way does not succeed then it is the management of the Object itself failing. One example would be Backbone zombie views. Either the view has bad code in the close section, the parent close is not hooked or an infinite loop happened. Testing all view events is also good, although tedious.
By putting all the code for data fetching inside a certain module (I often use a bunch of Backbone.Model objects for each table/document in my DB) and handlers for each using a reqres pattern, you can test them 1 by 1 to see if they all fetch and save correctly.
If complex computation is needed, abstract it in a function or module so that it can be easily tested with known data.
If your app uses data binding, a good policy is to have a JSON schema for all data to be tested against your views containing your bindings. Check against the schema all the data required. This is applied to your Backbone.Model also.
Using a good IDE also helps. PyCharm (if you use Python for backend) or WebStorm are extremely good for testing and developing JavaScript/CoffeeScript. You can breakpoint and study your code at specific locations, inside your browser! Also it runs your code for auto-completion and you can see some of the errors that way.
I just cannot encourage enough the use of modules in your code. Although there is no JavaScript official way of doing it (next ECMAScript draft has it), you can still use good libraries for it. Good ones are: RequireJS, CommonJS or Marionette.Module (if you use Marionette as your framework). I think Ember/AngularJS also offers this kind of functionality but I did not work with them personally so I am not sure.
This might not give you an immediate solution to your problem and I don't think (IMO) there is an easy one either. My focus was to show you ways to develop so that errors can be easily spotted and countered, and all of it (depending on your Unit Testing) during development phase. Errors will always happen, as much as our programmer ego wants us to believe the contrary. Hope I helped :)
I would suggest a divide and conquer strategy, first via logging, and second via code. Wrap suspect methods of the code with console logging in and out events and when the bug occurs hopefully it is occurring between or after some event. If event logging will not shed light, bring parts of the code into a new page/app. Divide and conquer will find when the error starts occurring.
So it seems you're in the realm of weird already, so I'm thinking of a weird solution. I know nothing about the backend of chrome myself so we're in the same boat, but if you're feeling bold here's an idea. Maybe you could find/replace every newline in your javascript files with a piece of code that logs either to a global string or to the console a) what file you're in, b) the contents of "this" or something useful to you, and maybe even c) the time. This would at least get you started. Make sure it's wrapped in something distinct so you can just as easily remove it.
This is really vague question but I am in the process of inheriting a rough-on-the-edges piece of jQuery for handling requests / responses to an API over JSON. Basically, each 'page' has a separate set of ajax calls and there is tremendous duplication.
I'm looking for a good blog post or maybe a jQuery plugin that separates out different dependancies for doing these requests. I'd like to keep it in jQuery. Like bundle up arguments, post, wait for response, and then delegate to a view. Something like Sammy looks interesting but might be too much.
thx
One way to tackle this is to use Selenium to write a series of tests (essentially documenting how the code currently functions) such that all the tests pass. Then, start refactoring it, and cleaning it up so it's easier to read, but the tests still pass. This way you still know that the code words the same way, but it's much easier to read.
Rewriting it from scratch might work if it's truly a mess, but it's likely that if you take that approach (rather that working to put a test suite around it incrementally, as you're refactoring it) that you'll wind up re-introducing bugs into the code that have already been fixed.
This doesn't sound like it's on the scale of the Netscape mistake, but it's a good story nonetheless.
I was wondering, if there is any generalities (among all the javascript engines out there) in the cost related to execute a given instruction vs another.
For instance, eval() is slower than calling a function that already has been declared.
I would like to get a table with several instructions/function calls vs an absolute cost, maybe a cost per engine.
Does such a document exists?
There's a page here (by one of our illustrious hosts, no less) that gives a breakdown by browser and by general class of instruction:
http://www.codinghorror.com/blog/archives/001023.html
The above page links to a more detailed breakdown here:
http://www.codinghorror.com/blog/files/sunspider-09-benchmark-results.txt
Neither of those pages breaks down performance to the level of individual function calls or arithmetic operations or what have you. Still, there is quite a bit of potentially useful information.
There is also a link to the benchmark itself:
http://www2.webkit.org/perf/sunspider-0.9/sunspider.html
By viewing the benchmark source you can get a better idea of what specific function calls are being tested.
It also seems like it might be a simple matter to create your own custom version of the benchmark that collects the more specific data you are interested in. You could then run the modified benchmark on a variety of browsers, perhaps even taking advantage of a service such as browsershots.org to test a wide spectrum of browsers. Not sure how well that would work, but it might be fun to try....
It is of course possible that the same operation executed in the same browser might take significantly different amounts of time depending on the context in which it's being used, in ways that might not be immediately obvious. For example, I could imagine a Javascript engine spending more time optimizing code that is executed frequently, with the result that the code executed in a tight loop might run faster than identical code executed infrequently. Of course, that might not matter much in practice. Still, I imagine that a good table of the sort you are looking for might also summarize any such effects if they turned out to be important.