Importing Rhythombox playlist data

I have Rhythombox on all my work and personal work machines(laptops) and I keep my music in ~/Music folder. 25GB of music from here and there, last 10+ years of music. Lots of them rated. And when I have to change laptops I lose all my playlists. Not anymore. Rhythombox saves all its data in ~/.local/share/rhythmbox and I copied rhythmdb.xml to new machine. One would say, why not copy home directory. Well, why would I copy home directory when most of my items are either on Google Drive or browsers have already synced them. I just copy Music and Rhythombox data files and am good to go. Yey!!!

How to setup and run multiple zookeeper instances on one box

In layman terms, Zookeeper is a highly available configuration management system meant for distributed systems. Distributed systems solve a lot of problems but then they present their own challenges. What happens when a node in a cluster is not able to serve due to any reason? And what if that node was leader? Zookeeper helps in such situations. Zookeeper keeps track of all the available nodes and knows what lies where. In case a leader is down it will quickly help in electing another leader. The purpose of this post is to explain how to run multiple Zookeeper instances on a single node/machine. Such a setup is also known as Zookeper ensemble. Running multiple instances on a single node means single point of failure, so this is not advisable at all. You can have 3 nodes running 7 instances, 1 small node with one instance and two bit bigger nodes with 3 instances each. One would do to cut costs.

Let’s get into action.

Get the latest release from https://zookeeper.apache.org/releases.html#download, untar and keep the folder at one location, say /home/luser/zookeeper/.

I will be setting up this on a Debian machine named deb and inside /opt directory.

Now the most tough part(?)…configuring Zookeeper. Look for zoo.cfg file inside configuration folder named conf. Open the file in your favorite text editor and you need to configure bare minimum 3 items

  1. dataDir
  2. clientPort
  3. server.n where n is the server/instance number

There are other items which you may want to tweak based on your usage. In my case following was the pattern for 3 Zookeepers on one node

For Zookeeper 1
dataDir=/var/zookeeper/data-1
clientPort=2181
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

For Zookeeper 2
dataDir=/var/zookeeper/data-2
clientPort=2182
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

For Zookeeper 3
dataDir=/var/zookeeper/data-1
clientPort=2183
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

In case I was setting up these three on different nodes, the pattern would have been copy of each other.

For Zookeeper individual node
dataDir=/var/zookeeper/data
clientPort=2181
server.1=node1:2888:3888
server.2=node2:2888:3888
server.3=node3:2888:3888

The last thing to pay attention to is, the myid file. This file goes inside dataDir. So for my nth Zookeeper on single node it would have been inside /var/zookeeper/data-n/myid. This file holds the server/instance number, so for nth instance the content of the file would have been value of n. So the myid file for 3 instance will contain number 3. In case of multiple nodes, myid file on node-n will have value n.

Now that config part is bit clear, there are two ways to start Zookeeper instances. I changed the zoo.cfg file for first instance and then copied the Zookeeper folder from home to /opt/zookeeper-1/ and followed this for other two instance. Then inside bin dir I just did zkServer.sh start. You can completely avoid this and create three zoo.cfg files using pattern zoo-n.cfg and then just cd inside bin dir and run zkServer.sh start zoo-n.cfg command to start servers. Once you have started servers you can verify the setup by connecting to individual server. For my first server I cd inside bin dir and run zkCli.sh -server 127.0.0.1:2181. For 2nd node this command was zkCli.sh -server 127.0.0.1:2182 and so on for 3rd. In case I had set up one node per instance, the command would have been zkCli.sh -server node-ip-or-node-host-name:2181.

And that’s it. Your Zookeeper ensemble is up and running!

Decorator pattern and baking a pizza

I am a self proclaimed master chef. And I love baking pizza. I was going through a video and the presenter mentioned the process of baking pizza as an example of decorator pattern. I had some example PHP “pizza” code lying around and decided to use namespaces and composer to build upon it. Here is the Just an example of decorator pattern. I might push more code to GitHub.

Update: I have been trying to get hang of Java and I did this same example using Java. Actually it was pretty easy to translate this code to Java. I did find and replace all for most of the stuff. Here is the repo.

Fix “Error mounting: mount exited with exit code 13: $MFTMirr does not match $MFT (record 0).”

I was moving around 200+GB data from one WD external drive to another. Although the drives were connected to USB3 port the process was taking time. And I felt asleep and shutdown the system. Next day I connect hard drive and I see

Error mounting: mount exited with exit code 13: $MFTMirr does not match $MFT (record 0).

“Wut!” The complete text said.

Failed to mount ‘/dev/sdc1?: Input/output error NTFS is either inconsistent, or there is a hardware fault, or it’s a SoftRAID/FakeRAID hardware. In the first case run chkdsk /f on Windows then reboot into Windows twice. The usage of the /f parameter is very important! If the device is a SoftRAID/FakeRAID then first activate it and mount a different device under the /dev/mapper/ directory, (e.g. /dev/mapper/media_eahaabcc1). Please see the ‘dmraid’ documentationfor more details.

OK. But my Windows XP Centrino laptop will take ages to book and I do have “ntfs-3g” installed. May be it can fix this problem. And I could see these

ntfs-3g           ntfs-3g.secaudit  ntfscat           ntfscluster       ntfsdecrypt       ntfsfix           ntfsls            ntfsmove          ntfswipe          
ntfs-3g.probe     ntfs-3g.usermap   ntfsck            ntfscmp           ntfsdump_logfile  ntfsinfo          ntfsmftalloc      ntfstruncate

And we have ntfsfix utility!

sudo ntfsfix /dev/sdc1

Look for the success message and done!

What is reflow, repaint, restyle and relayout?

Web browsers are more or less scriptable rendering engines. These engines usually render text and images but sometimes  videos or similar medias too. The rendering process starts when browser receives HTML or markup. Let us look at them step wise

  1. Browser received HTML.
  2. Parses HTML.
  3. Constructs a DOM tree, root of this tree is html tag. with branches like body and sub branches like div or p or a.
  4. By this time browser has also received CSS(hopefully 🙂 and parses it. Stylesheets have “cascading” effect. All this start as
    1. Browser default styles.
    2. External styles contained in style sheets.
    3. Imported styles in @import style sheets.
    4. Inline styles in <style> tag.
    5. Finally the style defined in style attribute of an element.
  5. Now browser has CSS and markup and constructs a render tree. Render tree has everything that must be rendered on to the page. Now, until and unless there are hidden elements, render tree will have almost all the visible elements. Tags like <head>, <script> and similar other tags are not included. Every other visible element will be in render tree.
  6. Now as browser has a render tree result of the above “flow“, it will “paint” this tree.
  7. But things do not stop here, browser calculates everything again to match up the viewport and a “reflow” occurs. This can be seen demonstrated. Delay the CSS arrival by some time and you can see a page loading without style and then when CSS arrives everything is “repaint-ed“.
  8. All the above are very expensive operations. But any change in page can trigger these. Resizing window, animations, adding or removing elements in the page trigger reflows and repaints.

For better performance avoid reflowing and repainting the page. But that’s not possible in case of dynamic app world of today. But there are some ways to make these repaints and reflows fast. Don’t do Y.one(elem).setStyle(styleattribute, value)/$(elem).css(styleattribute, value). Instead simply change the class. Don’t do following in sequence

  1. Change the font color
  2. Change the font size
  3. Change the font width

Instead create a class with all of the above and replace it. Every step will ask browser to do reflow and repaint. Better, perform the steps in a “batch” in background using JS and then replace the block with new node you created using JS. Reflow and repaints affect the performance of a page in same way slow network or a bad JS code will do.