24 August 2015

Subscribing to your VK friends Instagram

Story

So I decided to create an Instagram account. There you can do 2 things: post photos and watch photos of others. While I do not have an answer for you what to post (you may photograph your food or big abs in a mirror), I do have one on whom to follow. Probably if you are Russian like me you have a VK account and chances are your friends have linked Instagram on their pages. I have 300+ friends so you can see why programmer in me decided to automate this process.

Technical

There isn't much to it, we need a headless browser and a pretty straightforward Ruby script. Code can be found on Github, just open my vk_to_instagram repository.

21 June 2015

High Performance Browser Networking - Book Review

I will try to make it concise and give my personal opinion.

  • Author: Ilya Grigorik, a Web performance engineer at Google
  • Pages: 408
  • Published: September 2013
  • Amazon rating: 4.6/5
  • My rating: 4.1/5

This piece of writing has many levels to it. Ilya goes over all the building blocks which play part in Web performance. He briefly describes work mechanisms for each block and then based on acquired knowledge shows how to squeeze as much as possible out of it.

The fact that Ilya goes all the way from TCP / Mobile network work principles to Javascript API is both an upside and a downside. Many Web developers don't care about such level of detail and are only worried about steps they can do at the top of the stack, not server side TCP tweaks and peculiarities of different Mobile networks.

Nevertheless, if you are like me and you prefer deeper knowledge I advise you to read the whole book. If what interests you is only the top of the stack and you have few coins to spare then go ahead and read just the latter part of the book. I guarantee that you can find of lot of juicy revelations in there.

Brief summary of book contents:

1. Effects of latency and bandwidth
While bandwidth keeps increasing and all ISPs advertise it latency for the most part remains unchanged and it is latency that is often a speed bottleneck.

2. TCP
Describes basics of TCP and how we can tweak our servers to provide best performance

3. UDP
Tells about UDP and when we should use it over TCP.
Also covers STUN, TURN and ICE, techniques allowing to establish a connection between 2 peers even if they are behind NAT.

4. TLS
History, basic principals and performance implications of using a secure connection.

5. Wireless networks
Intro to wireless networks

6. WiFi
Performance characteristics of WiFi connections

7. Mobile Networks
History, all the different types of mobile connections and their performance.

8. Optimizing for Mobile Networks
Being energy efficient for mobile networks is perhaps as important as being fast.
Keep update checks and uploads to a minimum. Batch your uploads. Make your application work well both with good and bad networks.

9. HTTP history
Well... HTTP history

10. Primer on Web Performance
Human perception of speed. How browsers render pages. Different optimizations browser does to make loading process faster. The way we can give tips to a browser on what resources to load.

11. HTTP 1.x
Principles of HTTP 1.x. Protocol imperfections and the way Web developers overcome them (optimizations).

12. HTTP 2.0
Principles of HTTP 2.0. HTTP 2.0 usages in the wild (or more precisely usage of SPDY).

13. Optimizing Application Delivery
Universal optimization tips (apply to all protocols)
Optimizing for HTTP 2.0. Making applications work with both HTTP 2.0 and HTTP 1.x clients.

14. Primer on Browser Networking
Building blocks of a browser

15. XMLHttpRequest
History, use cases, performance, limitations

16. Server Sent Events
SSE API, use cases and performance

17. WebSocket
WebSocket API, use cases and performance.
What makes WebSocket different from other transports and it's flexibility

18. WebRTC
Use cases, work principles, API, possible complications. Delivery audio/video + custom data over WebRTC.

Not sure how useful it is, quickly wrote it at 4 AM :-)

01 March 2015

Seamless ActiveRecord Model extension

The Problem

What if you have one very bloated model, like User, that has a ton of fields you use only once or twice in your whole application and yet paying price for it every time you fetch / create a new one.

In this case what you want is to move some of these fields to another model (e.g. profile or user details).

The Solution

First step is to generate another model, let's name it UserProfile and link it to User model.

You would also have to run a migration that adds UserProfile to all existing users. Now what you can do is to write something like:

Now, of course, we could stop there, but why miss all the fun? What we want to do instead is:

So how do we do that?

Performance

When I measured how speed and memory footprint correspond to number of columns I found that both increase roughly linear as number of columns grows.

Precautions

When mass-assigning attributes from controller while using CanCan gem (tested in Rails 3.2), e.g. (User.new(params[:user])), CanCan tries to be smart and in "load_and_authorize_resource" tries to clean up all the unknown attributes from params[:user]. Solution is to set @user instance variable before "load_and_authorize_resource" is called.

p.s. in retrospective that blog post has a very ambiguous title, but that's the best I could come up with.

p.p.s. Happy Spring everyone!

19 January 2015

Parsing HTML generated outside of Angular

It often happens that you have to work on some old project using jQuery. But in modern Web Development jQuery just doesn't cut it. So you write new features in Angular. But sometimes you have to modify existing code.

It's not a problem as long as HTML is static, but if it's generated on server side Rails+jQuery style, then Angular won't know anything about it when it arrives to a browser.

So we have make Angular parse this HTML. I remember a long time ago when I first encountered that problem I googled quite a lot but came up empty handed. So I had to find a way myself. Recently my colleagues stumbled on the same problem so I decided to share this little piece of code on the internets.

Well... That's pretty much it. You shouldn't try running your angular app again. It's going to create a separate application.

Also I want to share an interesting gotcha. If you inline your angular templates with


<script type="text/ng-template" id="the-template" >

and they are in dynamically generated HTML you have parse this HTML. Strangely enough Angular doesn't use selectors to get this template. Rather it puts this template into template cache when encounters it during parsing.