about 2 years ago

The HTTP 1.1 specification states:

A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy.

But many modern browsers supports more than that:

IE 6 and 7:      2
IE 8:            6
IE 9:            6
IE 10:           8
IE 11:           8
Firefox 2:       2
Firefox 3:       6
Firefox 4 to 17: 6
Opera 9.63:      4
Opera 10:        8
Opera 11 and 12: 6
Chrome 1 and 2:  6
Chrome 3:        4
Chrome 4 to 23:  6
Safari 3 and 4:  4

The connection limitation is per hostname not IP address. [1]

Thus, even a.test.com and b.test.com points to the same ip address, you can still double the number of parrallel connections.

source: http://stackoverflow.com/questions/985431/max-parallel-http-connections-in-a-browser

 
about 2 years ago

On Ubuntu 14.04, the conifg file for sshd is located at:

/etc/ssh/sshd_config

Before making any modification, make a copy of the original config and make it read-only:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.factory-defaults
sudo chmod a-w /etc/ssh/sshd_config.factory-defaults

Then, open up sshd_config and modify the following lines:

LogLevel VERBOSE # also logs failed attempts, the log file can be found at /var/log/auth.log

AllowUsers user1 user2@10.0.0.1 # only allow user1 and user2 from 10.0.0.1 for example

PasswordAuthentication no # disable password login, use public key login instead

AllowTcpForwarding no # do not allow forwarding

X11Forwarding no

Restart ssh service to make the new config effective:

sudo service ssh restart

To limit the number of login attempts during a time period, enable the Uncomplicated Firewall by:

sudo ufw enable

Then, limit the number of ssh login attempts within 30 seconds to be 10 tries. More attempts will be dropped by issuing this command:

sudo ufw limit ssh

How to config your client

Once the server config has taken effect, you need to update your client ssh config which is found at ~/.ssh/config on your computer.

Host tinBox
HostName 11.12.13.14
User root
PubKeyAuthentication Yes
IdentityFile ~/.ssh/private_key

Make sure PubKeyAuthentication and a absolute/relative path to the private_key are added.

 
about 2 years ago

I work on a Ubuntu (14.04) machine with Postgres 9.4 installed. The config file directory of Postgres is located at:

/etc/postgresql/9.4/main/postgresql.conf

Inside the config file, uncomment and adjust the following lines:

log_destination = 'stderr, csvlog'  # save logs as .log file and a .csv file

logging_collector = on # required to be on for csvlogs

log_directory = '/var/log/postgresql' # use any directory the postgres user have read and write access to. /var/log/postgresql is a pretty good place to start with

log_filename = 'postgresql-%Y-%m-%d_%H%M.log' # modify the %modifiers to suit your need

log_truncate_on_rotation = on # should logs be saved in separated files instead of one gigantic file

log_rotation_age = 1d # save the logs into a new file everyday. If you'd rather seperate files based on file size, modify log_rotation_size instead of this one

log_line_prefix = '%t [%p-%l] %q%u@%d ' # what information should each line of logs include

log_statement = 'all' # check out here for more info: http://www.postgresql.org/docs/9.4/static/runtime-config-logging.html#GUC-LOG-STATEMENT

log_timezone = 'Asia/Shanghai' # what timezone should be used for timestamp each log

These are the basic options I enabled, and to make this new change effective immediately, restart postgres by:

sudo service postgresql restart

For more config explanation, check the official doc here

 
about 2 years ago

I use eslint to lint ES2015 + React projects. One problem I encounter with eslint is that it does not support the spread operator. I realized that I had to install babel-eslint to make this work. I have to modify .eslintrc to make it work with babel-eslint:

{
  "parser": "babel-eslint",
    ...
}

Then, I run eslint and got this error:

Error: Cannot find module 'estraverse-fb'

It turns out that if you are using eslint 2.0, you have to use babel-eslint 6.x.x. The detail is explained in this thread.

 
about 2 years ago

I was learning eslint's react/jsx options and stumbled upon this rule react/jsx-no-bind:

A bind call or arrow function in a JSX prop will create a brand new function on every single render. This is bad for performance, as it will result in the garbage collector being invoked way more than is necessary.

The following patterns are considered warnings:

<div onClick={this._handleClick.bind(this)}></div>

<div onClick={() => console.log('Hello!'))}></div>

The following patterns are not considered warnings:

<div onClick={this._handleClick}></div>
 
about 2 years ago

When writting React using the ES6 class syntax like this:

class MyClass extends React.Component {
    constructor(){
        super()
    }
}

Two questions may arise:

  1. Is it necessary to call super() inside constructor?
  2. What is the difference between callling super() and super(props)?

Answer #1

Always call super() if you have a constructor and don't worry about it if you don't have a constructor

Calling super() is necessary only if you need to have a constructor. Take a look at this code:

class MyClass extends React.Component {
    render(){
        return <div>Hello { this.props.world }</div>;
    }
}

The code above is perfectly valid. You don't have to call super() for every react component you create. However, if there is a constructor in your code, then you MUST call super:

class MyClass extends React.Component {
    constructor(){
        console.log(this) //Error: 'this' is not allowed before super()

    }
}

The reason why this cannot be allowed before super() is because this is uninitialized if super() is not called [1]

You may think you can get away with an empty constructor without callling super():

class MyClass extends React.Component {
    constructor(){} // Error: missing super() call in constructor

}

ES6 class constructors MUST call super if they are subclasses. Thus, you have to call super() as long as you have a constructor. (But a subclass does not have to have a constructor)

Answer #2

Call super(props) only if you want to access this.props inside the constructor. React automatically set it for you if you want to access it anywhere else.

The effect of passing props when calling super() allows you to access this.props in the constructor:

class MyClass extends React.Component{
    constructor(props){
        super();
        console.log(this.props); // this.props is undefined

    }
}

To fix it:

class MyClass extends React.Component{
    constructor(props){
        super(props);
        console.log(this.props); // prints out whatever is inside props

    }
}

There is no need to pass props into the constructor if you want to use it in other places. Because React automatically set it for you [2]

class MyClass extends React.Component{
    render(){
        // There is no need to call `super(props)` or even having a constructor 

        // this.props is automatically set for you by React 

        // not just in render but another where else other than the constructor

        console.log(this.props);  // it works!

    }
}
 
about 2 years ago

TL;DR

For development, use cheap-module-eval-source-map. For production, use cheap-module-source-map.


Disclaimer: The following result is based on a small project. The result may vary depending on the size of your project.

Webpack currently provides seven options to produce a source map. It is nice that it gives so many choices to developers, but it also downright horrible for beginners.

As a beginner, I find the offical document impossible to understand. So I decided to test it out myself. I am testing all of the options on a project with the following attributes:

  1. 18 .js files (modules if you prefer) along with libraries they referenced are bundled into a bundle.js file
  2. The bundle.js file is minified to 680 KB
  3. I left a bug in the code on purpose so that I can see what's the differences between the source map options. The bug is on line #37 in a file named CreateLogForm.js
  4. I wrote my code in ES6 and JSX and used babel to transpile it back to ES5
  5. I tested the error in Chrome's debug tools:
    1. I verfied the line number and the file name where the error orginated
    2. I clicked on the linked error file and see if the original source is displayed

source-map

I am going to start out with this one because this option produces exactly what you would expect, a source map. After the bundling process, I got a bundle.js.map file:

  • Size: 5.44 MB
  • Bundle Time: 50949 ms (This is how long it took to pack the bundle. There are fonts, images and css being emitted by webpack, so this is not how long it took to produce the source map file. This is the result of running this operation once. Thus, it should not be interpreted as the average running time of the operation.)
  • Bug Display:
    • File name displayed correctly
    • Line number displayed correctly (the line number matches the original source file's line number)
    • The file referenced by the error: ./~/react-dnd/~/invariant/browser.js which is completely wrong

cheap-source-map

A SourceMap without column-mappings. SourceMaps from loaders are not used.

No idea what that means, but this time:

  • Size: 698 B
  • Bundle Time: 46098 ms
  • Bug Display:
    • File name displayed correctly
    • Line number displayed incorrectly (the line number matches the transpiled file's line number instead of the original)
    • The file referenced by the error: ./~/react-dnd/~/lodash/lang/isFunction.js which is completely wrong

cheap-module-source-map

A SourceMap without column-mappings. SourceMaps from loaders are simplified to a single mapping per line.

No idea what it is talking about:

  • Size: 308 B
  • Bundle time: 56611 ms
  • Bug Display:
    • File name displayed correctly
    • Line number displayed correctly
    • The file referenced by the error: ./~/react-dnd/~/dnd-core/lib/index.js which is completely wrong

Note: This is the best option for production because:

  1. Both bundle.js and bundle.js.map are smallest
  2. The correct file name and line number are provided

eval

Each module is executed with eval and //@ sourceURL

No .map file emitted and the bundle.js file size is increased to 2.34 MB:

  • Size: N/A
  • Bundle Time: 33879 ms
  • Bug Display:
    • File name displayed correctly
    • Line number displayed incorrectly (the line number matches the transpiled file's line number instead of the original)
    • The file referenced by the error: The transpiled code of the original source is displayed

eval-source-map

Each module is executed with eval and a SourceMap is added as DataUrl to the eval

No .map file emitted and the bundle.js file size is increased to 5.83 MB:

  • Size: N/A
  • Bundle Time: 34257 ms
  • Bug Display:
    • File name displayed correctly
    • Line number displayed correctly (CreateLogForm.js?b337:37 I don't know what does the b337 portion stands for though)
    • The file referenced by the error: The original source code is displayed

cheap-eval-source-map

No .map file emitted and the bundle.js file size is increased to 5.8 MB:

  • Size: N/A
  • Bundle Time: 40663 ms
  • Bug Display:
    • File name displayed correctly
    • Line number displayed incorrectly (the line number matches the transpiled file's line number instead of the original)
    • The file referenced by the error: The transpiled code of the original source is displayed

cheap-module-eval-source-map

No .map file emitted and the bundle.js file size is increased to 5.74 MB:

  • Size: N/A
  • Bundle Time: 40663 ms
  • Bug Display:
    • File name displayed correctly
    • Line number displayed correctly (CreateLogForm.js?b337:37 I don't know what does the b337 portion stands for though)
    • The file referenced by the error: The original source code is displayed

Note: This is the best option for development because it is the smallest option that shows the correct line number.

 
about 2 years ago
handleChange = (e) => {
    this.setState({[e.target.name]: e.target.value}, () => {
        console.log(e)  // <- e is an event with all of its properties set to null

    })
}

The code above prints an event object with nulls set to all of its properties. So you cannot access e.target.value or e.target.name as you normally would. This issue is explained in this thread:

Events are pooled so we wipe out their values. If you want to use the event outside the current event loop then you need to call ev.persist() which will pull that event out of the pooling.

I think what that means is that React resues a set of event objects instead of creating new event objects everytime an event comes up. persist() prevents it from cleaning:

handleChange = (e) => {
    e.persist()
    this.setState({[e.target.name]: e.target.value}, () => {
        console.log(e)  // <- now you can see all of the property values correctly

    })
}
 
about 2 years ago

Two small issues I run into when dealing with OneToOneField and iterating through a model's fields.

One to One Fields

class A(Model):
    ...
    
class B(Model):
    a = models.OneToOneField(A, primary_key=True)

When models are defined like above, you can grab a reference to B this way:

a_instance = A.objects.get(id=1)
b_instance = a_instance.b

Since B's primary key equals to A's primary key, when Django's ORM creating B in the database, it will not create an 'id' column. Instead, a column named 'A_id' is created. Thus, when ever you want to access B's primary key, you cannot do:

b_instance.id # AttributeError: 'b_instance' object has no attribute 'id'

You have to use b_instance.pk instead.

Model's _meta field

I once had a task which needs to determine if any field within a model instance is empty. To do it, I need a way to loop through all of the fields defined in the instance first:

# _meta allows you to access the fields defined in the model instance

for field in model_instace._meta.fields: 
    ...

Here is the code for determining if a model instance is empty:

def is_model_instance_empty(model_instance):
    # find all of the field's name that are not foreign keys or one to one fields

    # many to many relationship should be added to make it complete

    field_names = [field.name for field in model_instance._meta.fields if (field.get_internal_type() != 'OneToOneField' and field.get_internal_type() !='ForeignKey')]
    counter = 0
    for field_name in field_names:
        if not model_instance.__dict__[field_name]:
            counter += 1
    return counter == len(field_names)
 
about 2 years ago

Django's formset can be difficult to understand, so I will try to explain it in a more understanbable way here.

What is it used for?

Let's say you are building a website which keeps track of users' daily activities. They can logon to your site and fill out a form with the following information:

  • Date and time
  • Activity name
  • Duration

Multiple activities can be recorded throughout a day. When users start to record for a new day, he should see an empty form with the aforementioned fields and an add button below the form to add more activities:

Date and Time: ___________________
Activity Name: ___________________
Duration:      ___________________

[ + Add More Activity ]

In this case, you cannot predict how many activities users will add beforehand. Thus, you cannot create a form to prepare for it. This is when Formset comes in. Formset allows you to add/remove forms on the fly (with the help of javascript which I will talk about in detail later).

How it works?

Before getting into the implementation details, it is important to understand how formset works. The best way to learn it is to think out how you would implement it by hand.

Requirements

CRUD is a good starting point to define what needs to be accomplished:

  • Forms need to be created (i.e. create new form data that do not exist in the database)
  • Forms need to be read (i.e. fill forms with existing data and display them to the user)
  • Forms need to be updated (i.e. fetch existing data and save changes made to them)
  • Forms need to be deleted (i.e. delete an existing form)

To accomplish any of these tasks, we need a way to keep track of forms. Thus, an ID is needed for each form. Also, when a form is deleted, we need a way to detect that. Thus, a form needs to be marked as deleted or not deleted.

How does Django do it?

To manage which form is which and mark them as deleted when neccessary, Django insert hidden input fields into the rendered HTML to help itself keeping track of the forms. Django inserts the following hidden data:

<input id="id_form_set-TOTAL_FORMS" name="form_set-TOTAL_FORMS" type="hidden" value="1"> 

TOTAL_FORMS:  the total number of forms in this formset
value: 1 means this formset contains 1 form 
<input id="id_form_set-INITIAL_FORMS" name="form_set-INITIAL_FORMS" type="hidden" value="1">

INITIAL_FORMS:  the number of forms in the formset that were pre-filled
value: 1 means 1 form within this formset has been pre-filled with data
<input id="id_form_set-MIN_NUM_FORMS" name="form_set-MIN_NUM_FORMS" type="hidden" value="0">

MIN_NUM_FORMS:  the minimum number of forms within the formset
value: the minimum number, but you normally do not need to set this
<input id="id_form_set-MAX_NUM_FORMS" name="form_set-MAX_NUM_FORMS" type="hidden" value="1000">

MAX_NUM_FORMS:  the maximum number of forms a formset may contain
value: the maximum number allowed

All of these hidden data, are added by the ManagementForm. You don't need to read about ManagementForm at the moment, just knowing which componment within Django is responsible for these is enough at this point.

To keep track of each form, Django also inserts hidden primary keys that are associated with existing forms:

<input id="id_form_set-0-id" name="form_set-0-id" type="hidden" value="4">

value 4 means the primary key of this form is 4

To keep track of which form has been deleted, Django also inserts a hidden field:

<input type="hidden" name="form_set-0-DELETE" id="id_form_set-0-DELETE" value="on"> 
value: on means this form is marked as deleted. When there is no value, it means the form is not deleted

The can_delete parameter is responsible for marking forms as deleted. I will explain this parameter later.

This post is long enough for a short read. I will explain more details about formset in the next blog post.