Today I Found Out

Server types in Rails

Webrick

Webrick is a single-thread, single-process web server.

Webrick will keep the router's connection open until it has downloaded the entirety of the request from the router. The router then will move on to the next request. Webrick server will then take the request, run the application code and send back the response to the router.

During the all of time, your host is busy, and will not accept connections from other routers. If the router attemps to connect to this host while the request is being processed, the router will wait until the host is ready.

The problem with Webrick are exaggerated with slow requests and uploads. If someone is trying to upload a big file, Webrick is going to sit there and wait while the request downloads, and will not download anything in the meantime, and it also will not accept any requests.

Webrick can't deal well with slow client request or slow application responses.

Thin

Thin is an event-driven, single-process web server.

Thin uses EventMachine under the hood, which gives you some benefits, in theory. Thin opens a connection with the router and
starts accepting parts of the request. But, if suddenly that request slows down or data stops coming in through the socket, Thin will go off and do something else. No matter how a slow client is, Thin can go off and receive other connections from other routers in the meantime.

Only when a request is fully downloaded will Thin pass the request to application. In fact, Thin will write very large request (like uploads) to a temporary file on the disk

Thin is multi-thread, not multi-process. Thin can't accept other request while waiting for I/O in the application code to finish. For example - if your application code POSTs to a payments service for credit card authorization, Thin cannot accept new requests while waiting for that I/O operation to complete by default.

Unicorn

Unicorn is a single-threaded, multi-processes web server.

Unicorn spawns up a number of "worker processes" (app instances) and those processes all sit and listen on a single Unix socket, coordinated by "master process".

So, when a connection request comes in from a a host, it doesn't go to master process, but instead directly to the Unicorn socket where all of the worker processes are waiting and listening.

A worker process (only listening on the socket because it's not processing a request) accept the request from the socket. It waits on the socket until the request is fully downloaded and then stop listening on the socket to go process the request. After it's done processing the request and sending the response, it listens on the socket again.

While downloading the request off the socket, Unicorn workers can't accept any new connection and that worker become unavailable.

Basically, you can only serve many slow requests as you have Unicorn workers. For example, if you have 3 Unicorn workers and 4 slow requests that take 3000 ms to download, the fourth request will have to sit and wait while other requests are processed.

Passenger, Puma (threaded), Puma (clustered) will update soon.

Little's Law - How many application instances you need?

How many instances do you need?

There's a theoretical tool we can use, the number of instances must obey Little's Law. The definition from Wikipedia is so hard to understand. So, basically, we just need to know the formula

Number of application instances = Average number of requests per second (requests/second) * Average response time (second)

Application Instances, its job is process a single request dependently and send it back to client. When using Puma in threaded mode, application instance is the entire Puma process, when using MRI, JRuby,each thread counts as an application instance. When using Unicorn, Puma (clustered) or Passenger, your application instance is each worker process.

For example:

My application haves:

  • Average rps (request per second): 153
  • Average response time: 300ms

So the application instance: 153 * 0.3 =~ 46 instances

Difference between Benchmarking and Profiling

Concepts

Benchmarking. We take two competing pieces of code - could be as simpler as a one liner or as complex as an entire web
framework. Then, we put them up against each other (iterations per second). At the end of the task, we come up with a single metric,
a score. We use the score to compare the two competing options.

In Ruby, the Benchmark module provides methods to measure and report the time used to execute Ruby code.
http://ruby-doc.org/stdlib-2.0.0/libdoc/benchmark/rdoc/Benchmark.html

Profiling. Profiling your program is a way to determining which methods are called and how long each method take to complete.
This way you can detech which methods are possible bottlenecks. Profiling also tell us a lot of valuable things, like what
percentage of CPU time was use where, where memory was allocated and things like that.

In Ruby, Profiling your program will slow down your execution time considerably, so activate it only when you need it.
https://ruby-doc.org/stdlib-2.1.0/libdoc/profiler/rdoc/Profiler__.html

In general

We should not use profiling to determine performance. Profiling is intented to be used in order to identify the parts of your
program which take the most time.

When measuring performance, we only care about the speed of whole program taken together. Profiling in that case only skew
result, instead, performance should be tested by benchmarks.

Refer:

http://programmers.stackexchange.com/questions/74697/can-software-performance-monitoring-profiling-be-automated-to-a-high-degree-as

https://ruby-doc.org/stdlib-2.1.0/libdoc/profiler/rdoc/Profiler__.html

http://ruby-doc.org/stdlib-2.0.0/libdoc/benchmark/rdoc/Benchmark.html

http://programmers.stackexchange.com/questions/74736/does-profiling-without-benchmarking-lead-to-micro-optimization

Explicit binding in JS

Explicit binding in JS

  • call()
  • apply()
  • binding()

call

Every function has call () property

var sayName = function() {
    console.log('Hello '+ this.name);
}

var vinh = {
    name: "Vinh Nguyen",
    age: 26
}

sayName.call(vinh); // Hello Vinh

So, if we want to pass few more arguments to sayName, what we can do?

var sayName = function(lang1, lang2) {
    console.log('Hello '+ this.name + '. Do you know ' + lang1 + ' and ' +  lang2) ;
}

var vinh = {
    name: "Vinh Nguyen",
    age: 26
}

var languages = ['Javascript', 'Ruby']

sayName.call(vinh, languages[0], languages[1]) //  Hello Vinh. Do you know Javascript and Ruby?

So, if we want to pass languages array as a argument to sayName, what can we do?

apply

apply is a property similar to call but instead passing argument one by one, we can pass an array as a argument.

sayName.apply(vinh, languages) // Hello Vinh. Do you know Javascript and Ruby?

So, how about bind?

bind

bind is similar to call but one thing is different. bind is going to return new function and setup invoking later.

var newFn = sayName.bind(vinh, languages[0], languages[1]) ;

newFn() // Hello Vinh. Do you know Javascript and Ruby?

Use current_user inside Serializer

  • Add serialization_scope to your application controller
class ApplicationController < ActionController::Base
  serialization_scope :view_context
end
  • From your serializer, use scope.current_user to get current_user.

Color column in Vim

Use the configure:

set colorcolumn = 81

to highlight column no.81.

This will help us when should break line :D

Stateless Functions in React and Pure function in JS

You may also define your React classes/components as a plain Javascript function.

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}
ReactDOM.render(<HelloMessage name="Vinh Nguyen" />, document.getElementByid('app'));
 var ProfilePic = function (props) {
   return <img src={'https://photo.fb.com/' + props.username} />
 }
 var ProfileLink = function (props) {
   return (
     <a href={'https://www.fb.com/' + props.username}>
       {props.username}
     </a>
   )
 }
 var Avatar = function (props) {
   return (
     <div>
       <ProfilePic username={props.username} />
       <ProfileLink username={props.username} />
     </div>
   )
 }
 <Avatar username="vinhnglx" />

The whole concept of a pure function is consistency and predictability.

  • Pure functions always return the same result given the same arguments.
  • Pure function's execution doesn't depend on the state of application.
  • Pure function doesn't modify the variable outside of their scope.

When you call a function that is "pure", you can predict exactly what's going to happen based on its input.

function add (x,y) {
  return x + y
}

add is a pure function. There are no side effects. Given the same arguments, it will always return the same value.

But in React, these components (Pure functions) must not retain internal state, do not have backing instances, and do not have the component lifecycle methods. They are pure functional transforms of their input, with zero boilerplate

Imperative and Declarative - Simple way

  • Imperative code means you tell your program how do do some thing?
var numbers  = [2, 4, 6, 8, 10]
var total = 0
for (var i = 0; i<numbers.lenght; i++) {
        total += numbers[i];
}
  • Declarative code means you tell your program what you want to do?
var numbers = [2, 4, 6, 8, 10]
numbers.reduce(function (previous, current) {
    return previous + current;
});

And Declarative will help us:

  • Reduce side effects
  • More readable code
  • Minimize mutability
  • Less bugs

Passion

A few days ago, I saw an article on Medium.com about OOP is finally dead, huh, I thought I shouldn't read it, because , in my opinion, that article is not good. We shouldn't make a war about OOP is dead or not. OO is a way for us can solve the problem.

And today, I read the post from Uncle Bob, a super developer, he shared about OOP and FP. So, below are good things that I saw from his post. I'll keep this note as the magnetic needle during my programming life.

Well, consider this OO issue. OO isn't dead. OO was never alive. OO is a technique; and a good one. 
Claiming it's dead is like  claiming that a perfectly good screwdriver is dead. 
Saying goodbye to OO is like saying goodbye to a perfectly good screwdriver. It's waste!
But Functional Programming is better!

I'm sorry, but that's like saying that a hammer is better than a screwdriver. 
Functional programming is not "better" than Object Oriented programming. 
Functional Programming is a technique, and a good one, that can be used alongside Object Oriented programming.
We need to choose a language, or two, or three. A small set of simple frameworks. 
Build up our tools. Solidify our processes. And become a goddam profession.

Thank you Uncle Bob for this post.

Using TabEdit in Vim

Open your ~/.vimrc and add short-keywords for TabEdit

nnoremap th  :tabfirst<CR>
nnoremap tj  :tabnext<CR>
nnoremap tk  :tabprev<CR>
nnoremap tl  :tablast<CR>
nnoremap tt  :tabedit<Space>
nnoremap tn  :tabnext<Space>
nnoremap tm  :tabm<Space>
nnoremap td  :tabclose<CR>
nnoremap th :tabnext<CR>
nnoremap tl :tabprev<CR>
nnoremap tn :tabnew<CR>

Open your vim, enter tn to create new tab, tj to go to next tab. Pretty neat.

Debugging when using Pow

When running the Rails server, normally we will use puts to print something to screen log. But, if we use Pow to run the Rails server, the puts command won't work, and we have to use Rails.logger.debug or Rails.logger.info to show something on screen log.

Difference between Props and State in ReactJS

The props are passed from parent component to child components and they can be changed inside child components. Props owned by parent component.

So far the component that we have created are stateless, the data doesn't change. In the other hand, State is reserved for interactivity, when the data changes overtime.

JSX - ReactJS

JSX allows us to write HTML-lish syntax in our Javascript code, it is not a template system, one of React’s core philosophies is that components are the right way to separate concerns rather than “templates” and “display logic”.

Check IP of instances from website

Use nslookup <website-address> to check.

For example:

nslookup artstand.jp

Server:         192.168.1.1
Address:        192.168.1.1#53

Non-authoritative answer:
Name:   artstand.jp
Address: 54.249.118.67
Name:   artstand.jp
Address: 54.65.177.184

View log from production

Normally, I use the command: tail -f log/staging.log to track the log.

Today, I know one more command to check: tail -n 100 log/staging.log to view 100 lines from the log.

DRY - Documentation in code

Programmer are taught to comment their code: Good code has lots of comments. But, they don't know, they are never taught why code needs comments: bad code require lots of comments.

The DRY principle tells us to keep the low-level knowledge in the code, where it belongs, and reserve the comments for other, high-level expla- nations. Otherwise, we’re duplicating knowledge, and every change means changing both the code and the comments. The comments will inevitably become out of date, and untrustworthy comments are worse than no comments at all.

In general, comments should discuss why something is done, its pur- pose and its goal. The code already shows how it is done, so comment- ing on this is redundant—and is a violation of the DRY principle.

Dump the AWS RDS Postgres

  • Need to know host, database_name, user and password of RDS first. For example, here is the configure that we need
production:
  adapter: postgresql
  encoding: unicode
  database: example
  pool: 20
  host: examplec8dco5xli.ap-southeast-1.rds.amazonaws.com
  username:  ubuntu
  password: hello
  • So, the command should be
pg_dump -h  <host> -U <username> <database> -f <file_name>.dump

How to install postgresql 9.4 on Ubuntu 14.04?

Create the file:

  • sudo touch /etc/apt/sources.list.d/pgdg.list
  • sudo vim /etc/apt/sources.list.d/pgdg.list
  • Add this line to pgdg.list: deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main

Next, run the command on terminal

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
  sudo apt-key add -
sudo apt-get update

Finally, install postgresql 9.4 by command

sudo apt-get install postgresql-9.4

Define function javascript to avoid error when run precompile

If you have function like this:

function aB(messenger = messenger) {
}

then you will get an error about syntax when deploy to production.

This function above should be changed to pass precompile before deploy to production

function aB(messenger) {
  var messenger = messenger;
}

Add a field have array type to model

class AddWrongQuestionIdsToContentProgress < ActiveRecord::Migration
  def change
    add_column :content_progresses, :wrong_question_ids, :string, array: true, default: '{}'
  end
end

First company for developer: Outsource or Product.

After 4 years working on programming, I knew one thing: The first company for a developer is really important.

In my country, actually, my city, almost companies are out-source companies. Newbie developers will be learned a lot of technologies because they need to do many tasks from back-end to front-end to finish many projects. But the developers needs to know one thing: They have to take a time to understand deeply when to learn any technology. But you know, in an out-source company, you have to follow a training plan from supporters, and this plan just introduces for you guys simple features of a technology. Next, you will join the project and start working, apply technology into the project. When you finish the project, you have to learn more new technology for other projects.

My friend, he has more luck than me, he started work for a product software company. He doesn't know more about new technologies, but he can understand deeply about one technology, he knows about how to apply the algorithm, apply design patterns, design Object-Oriented objects...and so on. I can recap for you guys, he knows all kinds of stuff for developing a software product.

So, I have many things need to share with you guys, but I can say in one sentence:

With newbie developer, you SHOULD NOT work for out-source company, let's find and apply for junior-developer position of a startup/product company. Knows more that don't know about basic things then I'm pretty sure, you will get a lot of troubles when working.

Feel free to ping me via email vinh.nglx@gmail.com to share your opinion.