- Do not use Makefiles to run application/server processes. Instead, use them to build/configure/setup your processes such than they can be invoked by a single command.
- Be idempotent. Running a make command twice in a row should be identical to running it once.
- Provide cleanup methods to delete generated content.
- Be habitual. You should use make commands constantly, otherwise your Makefile will drift out of sync from your application.
- Be complete. After a git-clone, the application should be usable after a single make command.
GET /socket.io/1/?t=1360136617252 HTTP/1.1 | |
User-Agent: node-XMLHttpRequest | |
Accept: */* | |
Host: localhost:9999 | |
Connection: keep-alive | |
HTTP/1.1 200 OK | |
Content-Type: text/plain | |
Date: Wed, 06 Feb 2013 07:43:37 GMT | |
Connection: keep-alive |
# Do comprehension chains Monads together | |
var x = do | |
a <- maybe_null( 'Hello World' ) # If returns null/None, none of the following is executed | |
b <- async_call_1( a ) # Returns a Promise | |
c <- async_call_2( b ) # Only executed once the preceding promise is fulfilled | |
d <- async_call_3( c ) | |
return d | |
x.get(function(err,ok){ | |
# function called with err if the above comprehension failed |
Application deployment should compliment rapid development, and continuous integration. It should be so easy that developers look forward to deploying updates.
The Application Bundle model is a robust method for running and developing server applications.
The constraints of deployment affects development. A good deployment should make development easy.
# SSH Key Search Order | |
# ids/$HOST/$USER/id_XXX | |
IdentityFile ~/.ssh/ids/%h/%r/id_rsa | |
IdentityFile ~/.ssh/ids/%h/%r/id_dsa | |
# ids/$HOST/id_xxx | |
IdentityFile ~/.ssh/ids/%h/id_rsa | |
IdentityFile ~/.ssh/ids/%h/id_dsa |
var http = require('http'); | |
var crypto = require('crypto'); | |
var PORT = process.env.PORT || 8888; | |
var MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; | |
function Frame(buffer){ | |
this.buffer = buffer; | |
I recommend using SSEs like an event-stream only. Do not send data through the stream, only events the client may be interested in. Clients can obtain data they are interested in by making additional HTTP calls to the server.
This keeps the data accessible via HTTP; it does not shard our API into two pieces, one HTTP-based, and one websocket based. We can check any of our endpoints with CURL, and all our routes are stateless. Even our event-stream is relatively stateless, because the server can fire-and-forget events as they occur.
Websockets are fragile. Their protocol is complciated, and the most popular websocket library socket.io is prone to memory leaks. Websockets do not cross proxies well, and debugging websocket issues is a large effort.
#!/usr/bin/env ruby | |
require 'json' | |
dat = {} | |
STDIN.read.split("\n")[4..-1].each do |line| | |
split = line.split(':') | |
if split.length > 1 | |
lhs = split[1].strip.split(/\s+/) | |
if lhs.length > 1 |
- virtualbox additions need to be installed in the global zone, then mount privileges need to be given to the guest zone using
fs_allowd
. The guest zone then mounts the virtualbox shared directory. - do not give the VM direct access to the virtualbox network, create an internal network to SmartOS and use
ipnat
to forward traffic internally. - once
ipnat
is forwarding traffic, forwarded ports from virtualbox will be redirected to the guest zone always - unpack the virtualbox guest additions for Solaris tools with
pkgtrans VBoxSolarisAdditions.pkg ~/tmp
I very often automate tasks using bash, a Makefile, or some other means. By far the best advice I can give anyone is to make your tasks idempotent. Let me say that again:
make your tasks idempotent
Having said that, it can be difficult when there are sub-tasks that should only be run once. Here is my small life-hack around that:
- check for the existence of a dot-file, e.g.
.db-create-tables