Skip to main content

Posts

Showing posts from 2015

Nginx secure link with node.js

Serving static files is a natural task for web servers. They, especially ones, having asynchronous architecture (like Nginx), are very good at such tasks. However, usually there is an additional security logic, which should restrict access to files you've published. IIS, for example, offers deep integration with application layer, which allows custom .NET "middleware" logic injection into the request pipeline. Node.js applications are very often published behind Nginx for various reasons and, with the help of Nginx "Secure Link" module, it's possible to offload static file serving tasks from node.js to Nginx, even if the files are not public. This module uses "shared secret" string (known to Nginx and the application) and expects a hash, based on this secret, to be present in the request to decide whether to proceed or return an error. Secure Link module may work in 2 alternative modes ( http://nginx.org/en/docs/http/ngx_http_secure_link_modul...

Profiling JavaScript memory in the browser and on the server

Summary  Recently we were executing a memory usage analysis in my current (node.js) project. This article summarizes some of our findings, which may be useful to other projects. It does not describes the very basics of the mark-and-sweep garbage collection algorithm. Instead, it focuses on the details of the particular tools we used. Chrome developer tools  Chrome developer tools have great heap snapshot section, which can be used to analyze heaps of both browser and server (node.js) applications. It can be used to record JavaScript heap snapshots of a running process or to load existing snapshots, recorded by other tools. It is available already for several years and is extensively described on the Internet. Still, there are parts of this tool, which don’t have proper description and, overall, it may be a bit overwhelming in the beginning. So here is a very simple HTML document example, which may help in understanding Chrome heap snapshot views. A script in this docu...

Returning cached value you haven't cached yet

In my current project, we use JavaScript promises all over the place. We use built-in angular.js $q service on the client and the great bluebird node.js promises library on the server. In fact, we don't even have any callbacks, all the "standard" node.js APIs are always "promisified". The virtues of promises have been extolled by many people. I personally like this article a lot:  https://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity /. I especially like the part, which tells about how promises allow "programming with values" in asynchronous contexts. Recently I've found a very interesting use case of this "programming with values" concept. Imagine, you have a service, which returns a value (a promise of value, to be more precise), by making an HTTP request. Then you decide you want to cache this value and make sure that many requests to this method don't make ext...

Merging sorted collections

Recently I had a chance to implement an interesting optimization for combining two sorted sets into another sorted set in JavaScript (by "sets" I mean arrays with unique elements). Additional requirement for the algorithm was that when matches are found in two sets, element from the first set should always appear in the result. The general approach of the implementation is the one used by SQL Server in its Merge physical join operator - since arrays are already sorted, both of them need to be iterated only once and there is no need for hashes to avoid duplicates. This approach would work even better with linked lists, since source items could be added directly into target efficiently without the need to create a separate array object. This is one of those algorithms, which is so simple but so efficient at the same time, so it is a great pleasure to implement. Resulting gist is presented below:

Redis Lua scripts are not really transactions

Redis support of Lua scripts is a great feature. We use it a lot to build fast reliable queues with some very interesting requirements. You need it every time you want to decide your next Redis command, based on the result of a previous command, while guaranteeing that no one else has done anything with this result or anything else has changed in Redis. That is, the whole Redis script is an "atomic" operation. However, I put it in quotes intentionally. My understanding of phrase "atomic operation" is that not only no one else can see it half complete while it is executing (that works so great in Redis). It should also mean, that it should never be left half complete if an error occurs in the middle (or at least, that is my wishful thinking:) ). Yea, exactly, the second point doesn't work in Redis and there is no warning in the official docs. To be more polite (or precise), there is no rollback in Redis (referring to a comment in this SO question -  http://sta...

Masked input plugin angular.js adapter and JS comma operator

I was recently adapting jQuery masked input plugin ( http://digitalbush.com/projects/masked-input-plugin ) for angular.js. This is the adapter itself: In order to produce the adapter, it was necessary to familiarize myself with source code of the original library. It was a very interesting task indeed! While the library works very well, it's source code is ... a bit too smart. It's uncompressed version looked a bit like it was compressed. But what was really interesting about it was how JavaScript comma operator was a bit abused. This lead me to research the topic a bit and I've found an amazing write-up on the topic, which I really recommend to read:  http://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/ UPDATE:  I should have researched it better. The link at the project site really does point to some semi-minified source code. The source code at github ( https://github.com/digitalBush/jquery.maskedinput ) looks much more readable!

Missing rows after updating SQL Server index key column

I'm reading the amazing "T-SQL Quering book" ( http://www.amazon.com/Inside-Microsoft-Querying-Developer-Reference/dp/0735626030 ). It has an interesting example, where reading all rows from a table, while updating clustered index key column value, one can miss a row or read a row twice. Updating entity key is not a good idea anyway, so this behavior seemed to be acceptable. I've tried to update this example, so that the same happens with a non-clustered index. This seems not to be acceptable with non-clustered indexes, since keys of these indexes are not domain keys and related values may very well be changing. In order to simulate such situation, we need to create a covering non-clustered index, which takes at least 2 pages. Then we need to update it's key column in such a way that first row (in index order) becomes last (jumps to second page in the index) and then - back again. While this jumping happens in the endless loop, we need to select all rows in t...