Notes from Daily Encounters with Technology RSS 2.0
 
# Saturday, July 4, 2015

Add New Debug ConfigurationAs soon as I started developing my first Grunt multi task, it became obvious that being able to debug it, will shorten my development time a lot. Since I've been recently using WebStorm as my JavaScript IDE of choice, I also wanted to be able to debug my task directly inside it. To no surprise, WebStorm has built-in support for debugging all kinds of Node.js scripts, including Gruntfiles. It's only a matter of getting used to WebStorm's debugging workflow.

Although there's support for temporary debug configurations which can be created ad hoc, this approach can't be used for debugging Grunt scripts. A proper debug configuration needs to be created for that, using Run/Debug Configurations dialog (accessible via Run > Edit Configurations... menu). The little "plus" icon in its top left corner opens a menu with a selection of preconfigured templates for debugging different types of Node.js scripts. Among them is also Grunt.js - the one that we need to use.

If you have your Node.js environment correctly setup and grunt-cli package installed globally, two important fields should already be prefilled for you:

  • Node interpreter should point to your Node executable (C:\Program Files\nodejs\node.exe in my case)
  • Grunt-cli package should point to where you have the package globally installed (C:\Users\damir\AppData\Roaming\npm\node_modules\grunt-cli in my case)

The only things left for you to fill in are the configuration Name (up to you) and the path to the Gruntfile you want to the debug. Optionally you can also set the Tasks to run if you want to debug anything else than default.

Grunt Debug Configuration

If you have written your Grunt script in JavaScript, then that's all you need to do. You can now set a couple of breakpoints and start debugging using the Run menu or the Debug tool window (the latter will open automatically once you start debugging, if you have it closed). If your Gruntfile is written in CoffeeScript, you're not done yet. Even though Grunt can run CoffeeScript scripts directly, WebStorm will report errors if you set a CoffeeScript Gruntfile in your debug configuration.

My next attempt was starting the Node interpreter directly and attaching to it from WebStorm. Not only was that much less convenient (having to manually start Node from command line every time), the mapping to CoffeeScript source was also mismatched, which made the approach almost useless.

It turned out that WebStorm's file watchers were the right way to go. You will first need to configure a CoffeeScript file watcher in the Settings dialog. Select Tools > File Watchers node in the tree view on the left (you can search for file watchers, to find it quicker) and click on the "plus" icon in the top right corner to add a new file watcher, based on CoffeeScript template. Again, almost everything is preconfigured for you; only the Program must be chosen manually. I suggest you install the coffee-script NPM package globally and point to coffee.cmd file it installs in the root of your global package installation directory (C:\Users\damir\AppData\Roaming\npm in my case).

Now your CoffeeScript Gruntfile will automatically be converted to a JavaScript one, whenever WebStorm detects changes. A JavaScript source map will be generated alongside it, allowing you to debug the original CoffeeScript file instead of the converted JavaScript one. You will still need to point to the JavaScript Gruntfile in the WebStorm debug configuration, though. Also, to make sure the converted file is always up-to-date, you should require the debug configuration to Run File Watchers before launching the script.

Run File Watchers Before Launch

Now, you will be able to debug your CoffeeScript Gruntfile just as if it was written in JavaScript.

Saturday, July 4, 2015 2:24:12 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | CoffeeScript | Grunt | JavaScript | Software | WebStorm
# Friday, June 26, 2015

Roberto Vespa: SignalR Real-time Application CookbookI was quite surprised to receive a review request for a book that was released more than a year ago: SignalR Real-time Application Cookbook by Roberto Vespa. Although I already bought this book some time ago, I somehow never got around to actually reading it. This review request was just the push I needed, to finally do it.

If you have read any of my previous reviews, you might already know, that I'm not really a fan of the cookbook format of books. This one suffers from the exact symptoms which make me dislike most of such books: a significant part of the book is dealing with non-related technicalities, needed to make the recipes work, and too much of the on-topic content gets repeated over and over again, even though the author is trying to minimize that.

In spite of that, this is still a great first book on SignalR to read. It manages to cover all of key SignalR topics, and doesn't stop at the most common scenarios, although most of the time is spent on them, as it should be. You won't learn only about web clients and hosting the server in IIS, but also about .NET based clients and self-hosting. It doesn't stop at the high-level hub API, but explains low-level connections as well. It doesn't ignore the more advanced topics either: authorization, dependency injection, backplanes and extensibility.

The last couple of recipes were the ones I liked the most; every one of them applying SignalR to a different real-world scenario. It was great to see examples going beyond the usual real-time chat. Their real value should be in giving the reader additional ideas, how to take advantage of the framework in less obvious cases. Still, don't expect the book to give you a really in-depth look at SignalR. It mostly focuses on using it, not understanding its internals. Different transport strategies are only briefly touched, and the author doesn't even attempt to go into explaining the "magic" that's happening behind the curtains.

If you're looking for a book to learn SignalR from, you can't go wrong with this one. On the other hand, if you're already fluent in SignalR and just want to learn more, it probably isn't your best choice, unless you're interested in one of the above mentioned topics.

The book is available on Amazon and sold directly by the publisher.

Friday, June 26, 2015 12:03:31 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | ASP.NET | JavaScript | Personal | Reviews
# Monday, June 15, 2015

Nathan Rozentals: Mastering TypeScriptOnce again I received a review copy of a book from Packt Publishing. This time it was Mastering TypeScript by Nathan Rozentals. Its subject happened to relate to some new responsibilities I have at work recently, therefore I am now much more interested in it than I would have been in the past.

The book starts out pretty slow with the necessary introduction to the language and the tooling available for it. Complete beginners in TypeScript will probably appreciate this part the most, but it is really exhaustive, therefore even existing developers might learn something new. The same goes for type definitions; not only will the reader know how to use them, he will also learn to write his own, for JavaScript libraries that don't have them yet.

Still, in my opinion the real value is delivered in the later chapters of the book, where the focus shifts from the language specification to real-world scenarios. The author is reinforcing best practices all the time: explaining the SOLID principles, promoting testing and test driven development, implementing design patterns, such as factory, service locator, mediator and others. Seeing real software engineering approaches applied to TypeScript and JavaScript code is really valuable.

Unfortunately, JavaScript development today is strongly dependent on 3rd party libraries. This is a quickly evolving field with many alternatives available for every task. Because of this, the author couldn't completely avoid being subjective in his choice of frameworks, which he used in his samples. I like, how he compared them through the lens of a TypeScript developer, although you still shouldn't regard it as a guide to choosing the right one. It's just an incomplete overview that can get you started, when picking your own set of MV*, testing or modularization libraries.

I have mixed feelings about the custom frameworks developed throughout the book, implementing reflection, service locator and message bus functionalities. Although they have pedagogical value, they might be too tempting to use in own projects. In my opinion using these instead of maintained alternative open source libraries is not a good idea; and this isn't clearly communicated in the book.

In spite of that I have no reservations about recommending the book to any existing or future TypeScript developer. It can serve as the first book to start learning the language, but can teach you a lot even if you have already been programming in it for a while. Some of the samples towards the end of the book can become quite complex, but if you read the whole book and occasionally look at the code downloads, you should still be able to follow them.

The book is available on Amazon and sold directly by the publisher.

Monday, June 15, 2015 3:19:23 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | JavaScript | TypeScript | Personal | Reviews
# Thursday, June 4, 2015

Packt Publishing has started a new initiative; offering a different ebook for free every day. To get it, you need to have a free account on their web site, so that it can be added to your collection. You also only have a 24 hour window during which the daily book is available, before it is replaced with the next one. Though, once it is added to your collection, you can always download it again in the future.

Develop new skills and unlock valuable knowledge with a FREE eBook every day

As you can see from the initiative web page, the books they are offering for free cover a really wide spectrum of topics, so everyone should be able to find something for his taste; e.g. yesterday's book s was the first edition of Learning NServiceBus, the successor of which I have recently reviewed.

There have already been similar promotions in the past, but they have all been of shorter period. The current set of 24 books on the page is the second one in a row, and there's still 9 days till the end. It's also quite possible, it will continue with another set afterwards, although this doesn't seem to be communicated anywhere on the page. Even if not, you should check the page every day until then and download any books that might interest you.

Thursday, June 4, 2015 9:27:53 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Personal | Reviews
# Sunday, May 24, 2015

Recently I was involved in troubleshooting a strange performance issue, manifesting itself in the form of long initialization time of each newly created process or AppDomain on one of the servers. Thanks to the application built-in logging functionality we quickly identified slow assembly loading as the root cause of the problem; on average each assembly took approximately 8 seconds to load.

As usually, we first checked for similar issues others might had in the past. The only one we came across was slow Authenticode signature verification due to inaccessible certificate revocation list. For several reasons this obviously wasn't happening in our case: the assemblies were not Authenticode signed and the issue does not happen in .NET 4, only in older versions.

This meant we had to gather more information about the problem. Since we couldn't directly debug a process on the production server, where the issue was happening, we had to resort to creating a memory dump during the assembly loading and analyze it with WinDbg to hopefully determine what was taking such a long time. We repeated the process several times to avoid a single random sample sending us into the wrong direction. It turned out in all of them the working thread had the same top of the stack trace:

1207ca00 73c8e47f (MethodDesc 739938f0 +0x5f DomainNeutralILStubClass.IL_STUB_PInvoke
    (Char*, Int32, Char*, IntPtr))
1207ca38 73bd7aca (MethodDesc 73a2c4b0 +0xba System.IO.PathHelper.GetFullPathName
    ())
1207cc24 73bd23a5 (MethodDesc 73979e38 +0x65 System.String.CtorCharPtrStartLength
    (Char*, Int32, Int32))
1207cc54 73c53621 (MethodDesc 73979bc4 +0x51 System.String.Equals
    (System.String, System.String, System.StringComparison))
1207cc64 73bd77ce (MethodDesc 73984c5c +0x64e System.IO.Path.NormalizePath
    (System.String, Boolean, Int32, Boolean))
1207cf04 73c4fd52 (MethodDesc 7397f394 +0x42 System.Array.CopyTo
    (System.Array, Int32))
1207cf28 73c4fcf4 (MethodDesc 739753c8 +0x74 System.Collections.ArrayList.InsertRange
    (Int32, System.Collections.ICollection))
1207cf84 73c5b4d3 (MethodDesc 7397f93c +0x23 System.Reflection.RuntimeAssembly.nLoad
    (System.Reflection.AssemblyName, System.String, System.Security.Policy.Evidence, 
     System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, 
     Boolean, Boolean))
1207cfa8 73c4cf09 (MethodDesc 7397f75c +0x99 System.Reflection.RuntimeAssembly.InternalLoadAssemblyName
    (System.Reflection.AssemblyName, System.Security.Policy.Evidence, 
     System.Reflection.RuntimeAssembly, System.Threading.StackCrawlMark ByRef, IntPtr, Boolean, 
     Boolean, Boolean))
1207cfe4 73bcdda3 (MethodDesc 73a28224 +0x67 System.Reflection.RuntimeAssembly.InternalLoadFrom
    (System.String, System.Security.Policy.Evidence, Byte[], 
     System.Configuration.Assemblies.AssemblyHashAlgorithm, Boolean, Boolean, 
     System.Threading.StackCrawlMark ByRef))
1207d00c 742d098f (MethodDesc 73977d0c +0x23 System.Reflection.Assembly.ReflectionOnlyLoadFrom
    (System.String))

The thread was indeed in the middle of loading an assembly (Assembly.ReflectionOnlyLoadFrom()). But it was busy getting a file path. That couldn't take that long, or could it?

We were stuck for a while, until we got another bit of information about the server: there was a huge number of .htm files in the Internet Explorer cache folder of the system account (%windir% \SysWOW64\config\systemprofile\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5). Then it struck me: could it be assembly binding log causing the performance issues? After all, the log is stored as a bunch of .htm files, placed by default in the user's IE cache folder.

Although Fusion Log Viewer was not installed on the machine, it turned out logging was indeed enabled; the settings are stored in the registry (HKLM\SOFTWARE\Microsoft\Fusion) and can of course be modified even without the tool. Obviously, having the logging enabled affects performance, but usually not in such an extreme manner. Due to how the logging is implemented, the performance can deteriorate significantly if it is enabled for a longer period of time without cleaning the selected log folder: because of too many files in the folder and the resulting log file name clashes it takes longer and longer to find a suitable file name for new log files. In our case it already took 8 seconds. As soon as we disabled the logging, the performance was back to normal. Deleting the log files freed up a significant amount of disk space, as well. We still don't know when the logging was enabled in the first place and why.

Lesson of the day? Don't log assembly binding on production machines, unless you really have to. As soon as you don't need it any more, turn it off immediately and delete the logs. It can save you a lot of headaches in the future.

Sunday, May 24, 2015 9:59:28 AM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET
My Book

NuGet 2 Essentials

About Me
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2015, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.