<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
	<title>c11e</title>
	<link>https://c11e.wodemo.net/</link>
        <item>
        <title><![CDATA[Fix node.js and webpack high CPU usage on macOS]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/510556]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Fri, 07 Jun 2019 19:56:54 +0800]]></pubDate>
        <description><![CDATA[### Option 1: chokidar ###
Adding `chokidar` will fix the high CPU usage.

```
yarn add --dev chokidar
```

or if you use npm:

```
npm install --save-dev chokidar
```

(Don't forget to restart your node application.)

The module `chokidar` is a neat wrapper around node.js fs.watch / fs.watchFile / FSEvents, providing high performance file watching by using OS-specific file event API and/or node's fs module. The webpack dev server uses it to detect file changes.

On macOS it uses FSEvents, a high performance file system event API.

### Option 2: fsevents ###

Alternatively, if you don't want `chokidar`, you can install `fsevents`. But you will probably want `--optional` because it is macOS only.

```
yarn add --dev fsevents --optional
```

or if you use npm:

```
npm install --save-dev fsevents
```
]]></description>
    </item>
        <item>
        <title><![CDATA[systemctl start docker failed]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/444680]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Wed, 21 Jun 2017 21:55:26 +0800]]></pubDate>
        <description><![CDATA[Here is the solution if you see the error below:

Solution first:
Add this line
```
DOCKER_OPTS=&quot;--bip=192.168.111.3/24&quot;
```

into /etc/sysconfig/docker

Error:
```
# systemctl start docker
Job for docker.service failed because the control process exited with error code. See &quot;systemctl status docker.service&quot; and &quot;journalctl -xe&quot; for details.

# systemctl -l status docker.service

● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
  Process: 19310 ExecStart=/usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current $OPTIONS $DOCKER_STORAGE_OPTIONS $DOCKER_NETWORK_OPTIONS $ADD_REGISTRY $BLOCK_REGISTRY $INSECURE_REGISTRY (code=exited, status=1/FAILURE)

FATA[0001] Error starting daemon: Error initializing network controller: Error creating default &quot;bridge&quot; network: failed to parse pool request for address space &quot;LocalDefault&quot; pool &quot;&quot; subpool &quot;&quot;: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network 
```]]></description>
    </item>
        <item>
        <title><![CDATA[gcloud crashed (UnicodeDecodeError)]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/434099]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sat, 18 Mar 2017 18:59:24 +0800]]></pubDate>
        <description><![CDATA[Today I was trying to install kubectl for gcloud (MacOS) using socks5 proxy

```
gcloud components install kubectl
```

And it gives me this error:

```
ERROR: gcloud crashed (UnicodeDecodeError): 'utf8' codec can't decode byte 0xbb in position 1: invalid start byte
```

After searching around the Internet found nothing useful. After enabled the stack trace printing in google-cloud-sdk/lib/googlecloudsdk/command_lib/crash_handling.py, I finally figured out the problem is coming from `google-cloud-sdk/lib/third_party/socks/__init__.py`

```
in __negotiatesocks5
req += struct.pack(&quot;&gt;H&quot;, destport)
```

The req here sometimes is with the type of &quot;unicode&quot;, instead of &quot;str&quot;, while the struct.pack is always returning a str. And when doing the +=, the Python is trying to decode the str using the UTF-8 encoding so that both are with the same type

The fix was to encode the unicode req into str. So that Python is not trying to decode the result of struct.pack
```
        if isinstance(req, unicode):
            req = req.encode('UTF-8')
        req += struct.pack(&quot;&gt;H&quot;, destport)
```

And this is my gcloud version in case anyone wants to know:
```
Google Cloud SDK 147.0.0
bq 2.0.24
bq-nix 2.0.24
core 2017.03.13
core-nix 2017.03.13
gcloud 
gcloud-deps 2017.03.13
gcloud-deps-darwin-x86_64 2017.03.13
gsutil 4.22
gsutil-nix 4.22
kubectl 
kubectl-darwin-x86_64 1.5.3
```]]></description>
    </item>
        <item>
        <title><![CDATA[ERR_SSL_PROTOCOL_ERROR in Chrome and Firefox when using Jetty 9]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/433910]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Thu, 16 Mar 2017 19:13:24 +0800]]></pubDate>
        <description><![CDATA[If you are seeing ERR_SSL_PROTOCOL_ERROR in Chrome and server is Jetty 9, do this:

Edit etc/jetty-ssl-context.xml

Add these in sslContextFactory
```
&lt;Set name=&quot;ExcludeCipherSuites&quot;&gt;
    &lt;Array type=&quot;String&quot;&gt;
        &lt;Item&gt;SSL_RSA_WITH_DES_CBC_SHA&lt;/Item&gt;
        &lt;Item&gt;SSL_DHE_RSA_WITH_DES_CBC_SHA&lt;/Item&gt;
        &lt;Item&gt;SSL_DHE_DSS_WITH_DES_CBC_SHA&lt;/Item&gt;
        &lt;Item&gt;SSL_RSA_EXPORT_WITH_RC4_40_MD5&lt;/Item&gt;
        &lt;Item&gt;SSL_RSA_EXPORT_WITH_DES40_CBC_SHA&lt;/Item&gt;
        &lt;Item&gt;SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA&lt;/Item&gt;
        &lt;Item&gt;SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA&lt;/Item&gt;
    &lt;/Array&gt;
&lt;/Set&gt;
```]]></description>
    </item>
        <item>
        <title><![CDATA[NodeJS Logging - may be the best practice]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/418620]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Fri, 18 Nov 2016 12:11:51 +0800]]></pubDate>
        <description><![CDATA[There are several approaches to pass logging strings and variables into console.log/console.error

## Background:
- When doing %s, %j, the console.log will be using [util.format](https://nodejs.org/api/util.html#util_util_format_format_args), which support only %s, %j, %d, meaning that you won't be able to log 
something like exception with this approaches
- If not doing %s,%d, etc.. The console.log will be using [util.inspect](https://nodejs.org/api/util.html#util_util_inspect_object_options), which handles all objects very well, including JSON and exception

## Conclusion:

### Best one:
```
//All useful info will be printed and being consistent
console.log('name:', $username, 'details:', $detailJSON, 'exception stacks:', $ex);
```


### Good ones:
```
//This will print all useful info but we are mixing different approaches: first 2 are using placeholders %s and %j, while the last one is not
console.log('name: %s, details: %j, exception stacks:', $username, $detailJSON, $ex);
```


### Bad ones:
```
//$detailJSON will be printed as [object Object]
console.log(`name: $username, details: {$detailJSON}, exception stacks: ${ex}`);
```

```
//$ex will be printed as {}
console.log('name: %s, details: %j, exception stacks: %j', $username, $detailJSON, $ex);
```]]></description>
    </item>
        <item>
        <title><![CDATA[Vim]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/413587]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Thu, 29 Sep 2016 22:03:25 +0800]]></pubDate>
        <description><![CDATA[Visual regex matching and replace
```
'&lt;,'&gt;s/\%V\(.\+\)\%V/{_('\1')}/g
```]]></description>
    </item>
        <item>
        <title><![CDATA[arc land without pushing it]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/401060]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sat, 11 Jun 2016 12:14:59 +0800]]></pubDate>
        <description><![CDATA[Sometimes You just do not want to push right away during arc land

--hold is the way to go

```
$ arc land --onto master --hold
...
...

BUILDS PASSED  Harbormaster builds for the active diff completed successfully.
 HOLD  Holding change locally, it has not been pushed.

This local working copy now contains the merged changes in a detached state.

You can push the changes manually with this command:
    $ git push -- origin ae12...eeee
```]]></description>
    </item>
        <item>
        <title><![CDATA[Error while waiting for device: The emulator process for AVD Nexus_5X_API_23 was killed]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/393604]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Fri, 15 Apr 2016 14:20:31 +0800]]></pubDate>
        <description><![CDATA[If you see this error:

- Power off your VirtualBox Virtual Machines
- Shut down your Docker daemon

```
~/Library/Android/sdk/tools/emulator -netdelay none -netspeed full -avd Nexus_6_API_23
emulator: WARNING: VM heap size set below hardware specified minimum of 384MB
emulator: WARNING: Setting VM heap size to 384MB
Hax is enabled
Hax ram_size 0x60000000
HAX is working and emulator runs in fast virt mode.
console on port 5554, ADB on port 5555
Failed to sync vcpu reg
emulator: ERROR: Unfortunately, there's an incompatibility between HAXM hypervisor and VirtualBox 4.3.30+ which doesn't allow multiple hypervisors to co-exist.  It is being actively worked on; you can find out more about the issue at http://b.android.com/197915 (Android) and https://www.virtualbox.org/ticket/14294 (VirtualBox)
Failed to sync vcpu reg
Failed to sync vcpu reg
Internal error: initial hax sync failed
```]]></description>
    </item>
        <item>
        <title><![CDATA[Docker: No More Virtual Box for Mac OSX and Windows]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/391257]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Fri, 25 Mar 2016 10:03:27 +0800]]></pubDate>
        <description><![CDATA[Today docker released a beta version for Mac and Windows users, and docker is not using virtual  box and the virtual-box hosted docker-machine anymore

https://blog.docker.com/2016/03/docker-for-mac-windows-beta/
&gt;The Docker engine is running in an Alpine Linux distribution on top of an xhyve Virtual Machine on Mac OS X or on a Hyper-V VM on Windows, and that VM is managed by the Docker application. You don’t need docker-machine to run Docker for Mac and Windows.


For Mac OSX, docker is using the https://github.com/mist64/xhyve, which is built on top of hypervisor framework introduced in OS X v10.10

https://developer.apple.com/library/mac/releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_10.html
&gt; Hypervisor (Hypervisor.framework). The Hypervisor framework allows virtualization vendors to build virtualization solutions on top of OS X without needing to deploy third-party kernel extensions (KEXTs). Included is a lightweight hypervisor that enables virtualization of the host CPUs.]]></description>
    </item>
        <item>
        <title><![CDATA[What is ALPN (Application-Layer Protocol Negotiation)]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/390061]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Thu, 17 Mar 2016 12:44:05 +0800]]></pubDate>
        <description><![CDATA[Without ALPN, the steps to load a HTTP/2 page would be like:

1. TLS handshake
2. Browser/Client speaks HTTP/1.1 to server with &quot;Upgrade: h2c&quot; Header
3. Server responds with 101 Switching to upgrade to HTTP2
4. Now they talks via HTTP2


With ALPN, the steps would be:
1. TLS handshake and in the handshake client tells the server the list of protocol it supports and server respond in handshake saying that it supports HTTP2 as well
2. Now they talks via HTTP2


As you can see there is one less round trip with ALPN (No step of Upgrade and 101 Switching)


RFC: http://tools.ietf.org/html/rfc7301]]></description>
    </item>
        <item>
        <title><![CDATA[Difference between the "Bundle versions string, short" and the "Bundle version"]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/389671]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sun, 13 Mar 2016 22:28:25 +0800]]></pubDate>
        <description><![CDATA[. xcode-versioning.png&quot;Bundle versions string, short&quot; is the version we see it in the App Store, e.g. 1.0.1

&quot;Bundle Version&quot; is the build number, e.g. 12


When you want to submit a new APP but do not want to change the version number, you would just update the build number, with same version string

And build number can/should be start over for every version string

For example, we could have these version and build:

Version:1.0.1 Build:1
Version:1.0.1 Build:2
Version:1.0.1 Build:3


Version:1.0.2 Build:1
Version:1.0.2 Build:2
Version:1.0.2 Build:3
Version:1.0.2 Build:4


Here is a good article if you want to understand all the concepts about this version thing: [https://developer.apple.com/library/ios/technotes/tn2420/_index.html](https://developer.apple.com/library/ios/technotes/tn2420/_index.html)]]></description>
    </item>
        <item>
        <title><![CDATA[The magic of "Restart the Xcode"]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/389642]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sun, 13 Mar 2016 17:42:46 +0800]]></pubDate>
        <description><![CDATA[There is this black magic, that if you are seeing something is wrong / not working with Xcode, you may just need to restart it

For example, today I encountered into this issue:

```
Build failed:
No matching provisioning profile found: Your build settings specify a provisioning profile with the UUID “......”, however, no such provisioning profile was found.
```

The first thing came into my mind is to restart the Xcode. And you know what? It works!!]]></description>
    </item>
        <item>
        <title><![CDATA[letsencrypt几个插件(Apache, Nginx, Webroot, Standalone, Manual)的区别]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/389361]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sat, 12 Mar 2016 13:16:23 +0800]]></pubDate>
        <description><![CDATA[Letsencrypt的几个模块(插件)，原理上都是一样的:

1. 在你的 Web 服务器上生成一个临时认证文件，letsencrypt 的服务器会访问这个临时文件，来验证你对域名的所有权 (letsencrypt agent 会生成一对 key pair 来完成整个过程)
2. letsencrypt agent 使用 key pair 去请求 letsencrypt 的服务器请求certificate


Apache 和 Nginx 这两个模块，除了完成以上两步，还会对 Apache 和 Nginx 的配置文件进行修改，自动完成对 certificate 的使用

Webroot，指定一个 Web 目录，来生成临时认证文件(letsencrypt会使用一个叫.well-known的目录)，认证结束后会自动删除所有临时文件

Standalone，你的服务器的letsencrypt agent 会创建一个临时的 Web 服务器，来监听 80 端口并提供服务。以便letsencrypt 的服务器访问临时认证信息。所以这个模式要求你关闭自己的 Web 服务器，以便 letsencrypt 使用 80 端口

Manual，可以让你在别的机器或者你自己的电脑生成认证文件，然后自己手动拷贝到 Web服务器上，接着手动触发验证]]></description>
    </item>
        <item>
        <title><![CDATA[EXC_BAD_ACCESS when doing KVO(Key-Value Observing)]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/387555]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Wed, 02 Mar 2016 16:36:05 +0800]]></pubDate>
        <description><![CDATA[If you are getting EXC_BAD_ACCESS when a KVO event is generated, you probably forget to remove the observer from listening a object when the observer is deallocated


All you need to do is to call removeObserver:forKeyPath in observer's dealloc:

```
- (void)dealloc {
    @try {
    
        [SomeObj removeObserver:self forKeyPath:@&quot;price&quot;];
        
    } @catch (NSException * __unused exception) {}
}
```

If you do not remove the observer, the KVO system will be trying to access the memory space which is not available anymore for the reference KVO is using

```
(lldb) bt
* thread #1: tid = 0xb77a18, 0x000000010e66e80b libobjc.A.dylib`objc_msgSend + 11, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x000000010e66e80b libobjc.A.dylib`objc_msgSend + 11
    frame #1: 0x000000010bf5fce7 Foundation`-[NSObject(NSKeyValueObservingPrivate) _changeValueForKey:key:key:usingBlock:] + 380
    frame #2: 0x000000010bfbe35f Foundation`_NSSetObjectValueAndNotify + 261
```]]></description>
    </item>
        <item>
        <title><![CDATA[Bad Coding Behaviour]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/387458]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Tue, 01 Mar 2016 17:21:08 +0800]]></pubDate>
        <description><![CDATA[## Logging
Logging without a prefix string makes it hard - if not impossible - to find the corresponding codes by the logs

Example:
logger.info(variable)]]></description>
    </item>
        <item>
        <title><![CDATA[Auto restart NodeJS app when file and code change]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/386454]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sat, 20 Feb 2016 21:17:09 +0800]]></pubDate>
        <description><![CDATA[To automatically detect file changes and restart the app you will need a process manager to start your NodeJS app

Note: Do auto restart only on your dev deployment. Never do it in production

## Option 1: pm2
```
npm install pm2 -g
pm2 start app.js --watch
```

You can also use pm2 to start non-nodejs app
```
pm2 start app.py --interpreter python
```


## Option 2: nodemon
```
npm install -g nodemon
nodemon app.js
```

You can also use nodemon to start non-nodejs app. e.g. starting a python app:
```
nodemon --exec &quot;python -v&quot; ./app.py
```]]></description>
    </item>
        <item>
        <title><![CDATA[Compiling Nginx with HTTP/2 and ALPN]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/385459]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sat, 13 Feb 2016 22:28:25 +0800]]></pubDate>
        <description><![CDATA[To have HTTP/2 fully supported in Nginx, you will need OpenSSL 1.0.2+ to have APLN enabled ([What is APLN](/what-is-alpn-application-layer-protocol-negotiation))

Unfortunately, nowadays most linux distributions are shipping with older version of OpenSSL. For example [Ubuntu 14.04 is using openssl 1.0.1f](https://launchpad.net/ubuntu/trusty/+source/openssl)


I can also use 3rd party repositories but I couldn't find out something I think it is trusted

So it leaves me with only one option: compiling from source

Good thing is, it is pretty easy to compile nginx with a custom OpenSSL. You don't even have to compile the OpenSSL and install into the system (which could break your system dependences)

All you have to do are:

1. Download the latest stable OpenSSL from https://www.openssl.org/source/ and extract the tar
2. Download the latest stable nginx from http://nginx.org/en/download.html and extract the tar
3. Go into nginx source folder and 
```
./configure --with-openssl=/path/to/openssl-1.0.2f --with-http_ssl_module --with-http_v2_module
make &amp;&amp; make install
```
- Note: --with-openssl points to the openssl source folder instead of the installation folder
4. Enable HTTP/2 in nginx configure file
```
        listen 443 ssl http2;
```

That's it

And here is how you can verify if your website is now supporting HTTP/2 and ALPN
```
echo |  /usr/local/ssl/bin/openssl s_client -alpn h2 -connect c11e.wodemo.com:443 | grep ALPN
```
Which will report
 - &quot;ALPN protocol: h2&quot;
 - or &quot;No ALPN negotiated&quot;]]></description>
    </item>
        <item>
        <title><![CDATA[Docker Performance]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/385454]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Sat, 13 Feb 2016 21:48:14 +0800]]></pubDate>
        <description><![CDATA[Docker is almost as fast as native. But still we can get it better on performance by tuning options

## Networking

```
docker run --net=host
```
 will give you the best performance of networking

It tells docker to not containerize the container’s networking]]></description>
    </item>
        <item>
        <title><![CDATA[ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION]]></title>
		<link><![CDATA[https://c11e.wodemo.net/entry/385077]]></link>
		<dc:creator><![CDATA[@c11e]]></dc:creator>
		<pubDate><![CDATA[Wed, 10 Feb 2016 23:48:23 +0800]]></pubDate>
        <description><![CDATA[SSL server probably obsolete.

ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION

Chrome 访问光大信用卡网银出现这个错误，用 Safari 即可。光大网银似乎是用了一个低版本的SSL

curl得到这个结果
$ curl -v https://xyk.cebbank.com/
*   Trying 106.37.164.149...
* Connected to xyk.cebbank.com (106.37.164.149) port 443 (#0)
* Could not negotiate an SSL cipher suite with the server
* Closing connection 0
curl: (35) Could not negotiate an SSL cipher suite with the server. Screen Shot 2016-02-10 at 11.47.44 PM.png]]></description>
    </item>
    </channel>
</rss>
