2011-05-31

Reduce your HDD spindown time for silent SSD computing

If you've got an SSD+HDD/optibay setup in your macbook, you probably find that the thing is damn near silent when the spinning rust goes to sleep, and the silence is bliss. It's probably also great for battery life too, but I just love having a computer that sounds like it's not even on.

The thing is if you access a file on the spinning rust the drive wakes up, and like a crying baby the damn thing seems like it's never going to go back to sleep. You search in System Preferences, but the only option there is whether or not it sleeps the HDD, not how long it waits, so you put up with it.

Or... you find out that Apple provide some tools called CHUD, which include SpindownHD.app, a utility that allows you to specify how long to wait before spinning down the HDD. In a normal system where your booting off the spinning rust, the 20 minute default makes sense since there's a second or so pause when trying to access a file from the sleeping disk, but when 90% of your frequently accessed files are on the SSD you'd probably rather bring that down a lot. I've set mine to 1 minute and am finding it awesome. I started out searching for a way to manually sleep the hard drive, but a 1 minute spindown negates that for me.

If you've got the developer tools installed already, just run:
open "/Developer/Applications/Performance Tools/CHUD/Hardware Tools/SpindownHD.app"

in terminal and bring the wait time right down.

Apparently this can also be set using pmset as follows:
sudo pmset -a disksleep 1

Developer tools probably not required :D

You can track down any files that are open on the spinning rust using lsof
lsof | grep -i "/Volumes/SpinningRustDriveName"

I found some folders in my Dock were holding open files so I removed them

2010-03-02

More vim tidbits

it's been a while since I put anything new up, but I have a bunch of post-it notes stuck to my monitor that I'd be mighty peeved if the cleaner 'cleaned' them away so I'm transcribing them to the web.


C^w L => turn current pane into vertical split on the right
C^w T => turn the current pane into a tab
C^w F => open the file currently under the cursor in a new horizontal split


gi => move cursor to the last place you were in insert mode

ci" => delete the contents of a double quoted string and enter insert mode
ci] => delete the contents of matched square brackets .... you get the idea.
ct" => as above, but only deletes from the current cursor position to the end of the section


command chains: you can batch up a list of commands to execute in sequence using the | (pipe) symbol. ie. ":sp|bn" will split the window and change the selected pane to the next buffer. useful for when you open more than one file from the command line

2009-12-11

Page caching per request domain with Rails and nginx

At work we run a number of different sites of the same codebase, serving content based on the request's domain. we recently found some problems with page caching when different sites shared common urls, so domain1.com/somepage and domain2.com/somepage would end up wrongly serving the same content, randomly switching based on which was requested first after the cached version expired.

This was solved with a little modification to Rails and our nginx config.

Firstly we chucked this guy in lib/cache_page_with_domain_name.rb

require 'action_controller'
module ActionController::Caching::Pages
def cache_page_with_domain_name(content = nil, options = nil)
return unless perform_caching && caching_allowed

path = case options
when Hash
url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format]))
when String
options
else
request.path
end
#prefix the request domain so caches between sites dont interfere with each other
path = "/#{request.domain}#{path}"

self.class.cache_page(content || response.body, path)
end

alias_method_chain :cache_page, :domain_name
end


this makes the rails cache_page method write out cache files into public/#{request.domain}/ instead of just public/

next we added some config for nginx to make it look in these paths for these pages

nginx.conf

# serve any existing file in site specific cache dirs
if (-f $document_root/$host$uri) {
rewrite (.*) /$host$1
break;
}

# serve any standard Rails page cache file with .html extension in site specific cache dirs
if (-f $document_root/$host$uri) {
rewrite (.*) /$host$1.html
break;
}


I should add a note that you'll also have to modify whichever method you use to sweep stale caches to clear out the "public/#{domain}" folders, otherwise your cached pages wont update between deploys

2009-08-05

dynamically defined methods in ruby

I've been playing around with dynamically creating methods today and it's mighty cool stuff. here's a very contrived demo class:
class Demo
METHODS=["one","two","three","four"]
METHODS.each { |name|
define_method("method_#{name}") do
|arg|
puts "this method is named method_\"#{name}\" and you gave me the arg \"#{arg}\""
end
}
end


and me using it in irb
irb> demo = Demo.new
=> #<Demo:0xb7be8900>
irb> demo.method_one("this is an arg")
this method is named "method_one" and you gave me the arg "this is an arg"
=> nil
irb> demo.method_two("this is an arg")
this method is named "method_two" and you gave me the arg "this is an arg"
=> nil
irb> demo.method_four("this is another arg")
this method is named "method_four" and you gave me the arg "this is another arg"
=> nil

2009-07-28

Negative Lookbehind in vim

very similar to the last post, but this time for _not_ matching text that is preceded with some other text, and this time using the vim regex engine which is syntactically a little different
/\(Start\)\@<!Date
This will match the 'Date' in 'EndDate' and 'YesterdaysDate' but will not match 'StartDate'

and what the hell, while I'm lookup up vim syntax, here's negative lookahead:
/Start\(Date\)\@!
will match the 'Start' in 'Starting but not in 'StartDate'

Positive lookahead:
/Start\(Date\)\@=
will match the 'Start' in 'StartDate' but not in 'Starting

Positive lookbehind
/\(Start\)\@<=Date
will match the 'Date' in 'StartDate' but not in 'EndDate' and 'YesterdaysDate'

2009-07-26

Regular Expressions - Negative Lookahead

/a(?!b)/ will match an a that's not followed by a b (with the not-b character not being included in the match)

this can be built upon to match ranges that dont contain a string.

/^((?!DONT_MATCH).)*$/ will match full lines that dont contain the string "DONT_MATCH"


An example using negative look ahead in order to close <p> tags in poorly formed html:
$ irb
>> x="<p>an un-closed paragraph tag <p>and a properly formed paragraph</p>"
=> "<p>an un-closed paragraph tag <p>and a properly formed paragraph</p>"
>> x.sub(/<p>((?!</p><p>).)*/,"")
=> "<p>and a properly formed paragraph</p>"
>> x.sub(/<p>(((?!</p><p>).)*)/,"<p>\\1</p>")
=> "<p>an un-closed paragraph tag </p><p>and a properly formed paragraph</p>"


!@#$%^!! blogger seems to have "helpfully" correcting my bad html example when I tried to use the wysiwyg editor. attempt 2 as plain html.

Labels:

2009-04-02

Xcode keyboard shortcuts W.I.P

Xcode's automatic completion is called codesense, which helps when you're searching for information about it.

pressing ESC will bring up the scrollable list of codesense completion options

pressing C^/ (control and slash) will jump to the next argument in a method that's been completed for you.

2009-04-01

Happy Birthday GMail

It's been 5 years since webmail changed.

It's 5 years to the day since the introduction of GMail. I remember the announcement, I thought it was another stupid April fools day gag; 1GB of mail storage? yeah right. Hours, and then days passed and the "haha, fooled you!" never came.

These days I have amassed 1435MB of the always increasing 7311MB. If it weren't for google, I'm sure free webmail would still be stuck on 2MB hotmail accounts, with the option to pay ludicrous amounts each month for 100MB accounts.

Thank you google, you really have made the internet a better place!

edit: hehe, I beat google to the punch :P Official Google Blog: 5 years of Gmail

2009-03-26

Objective C W.I.P

The @ symbol (or at symbol)

anything preceeded with an @ is a compiler directive. keywords have specific meanings too numerous to list.

@"a string"
an immutable/constant string.

@32
an immutable/constant int.

Labels:

2009-03-21

Basic Non-destructive Backup with rsync (good for music & photos)

#!/bin/bash

EMAIL="me@myemailhost.com"
HOSTNAME="fileserver"
LOCAL_PATH="/mnt/data/photos/"
REMOTE_PATH="/Users/lucas/Pictures/iPhoto\ Library"
REMOTE_HOST="hackintosh"
WHAT="photos"

#if we've said to delete files that are missing in the remote copy, do so and exit
if [ $# -eq 1 ]; then
  if [ $1 == delete ];then
    rsync -ai --delete "$REMOTE_HOST":"$REMOTE_PATH" "$LOCAL_PATH"
    exit
  fi
fi

#otherwise backup changes
rsync -ai "$REMOTE_HOME":"$REMOTE_PATH" "$LOCAL_PATH" |mail -e -s "$HOSTNAME: $WHAT backed-up" $EMAIL

#and make a list of files that have been deleted in the remote copy
rsync -ain --delete "$REMOTE_HOME":"$REMOTE_PATH" "$LOCAL_PATH" |mail -e -s "$HOSTNAME: $WHAT to delete" $EMAIL



i have cron on my fileserver set to run this script every night (and another very similar one for my music). I just go about my business on my desktop using iphoto and itunes as normal and everything is replicated on my fileserver within 24 hours with email notification of what is copied or should be deleted from the backups. If I accidentally delete something from either library on my desktop, the files will still be sitting on my fileserver unharmed until I manually run the script with the "delete" argument.

Labels: , ,

find and execute

find -name "*.rar" -exec unrar e {} \;
recursively searches for rar files, extracts the contents of each. matching filenames are substitutes in for the {} and executed, one at a time. this can be slower than piping the results of find to xargs, but doesnt fail when the executed command can only work on one file at a time.

Labels: ,

.bash_profile

export EDITIOR=vim
sets vim to be the default editor. it's probably not kosher to leave off the path, but it varies a lot between systems, so i just trust it's going to be available within $PATH

complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh
I'll happily admit this is voodoo to me, I could probably dissect how it works but i dont really care. takes hosts found in ~/.ssh/known_hosts and autocompletes them like filenames


alias ls='ls -FG'
alias ll='ls -FGl'
alias la='ls -aFGl'

colourful ls' with symbols to denote executable files and directories


alias h='history'
alias hg='history|grep'

less keystrokes for history and search of history means I use it more often

alias cp='cp -v'
I like to know the progress of long copy operations

alias df='df -H'
alias du='du -H'

who cares about bytes when you're dealing with hundreds of gigabytes. human readable please!

alias rm='rm -i'
saves me from brainfarts. overridden by rm -f

alias curl-easy="curl -C - -O "
an alias to make curl work more like fetch or wget. resumes automatically, saves the downloaded data named the same as it is on the server

Labels: ,

.inputrc

ok, this one is super short

set completion-ignore-case On
makes bash tab completion ignore case for file and directory names

Labels: ,

VIM

commands

:%s/find/replace/g
finds and replaces all instances in file

:%s/find/replace/gi
finds and replaces all instances in file (ignore case)

:%s/find/replace/gc
finds and replaces all instances in file (confirm each replacement)

:%g/search/s/find/replace
searches the whole file for lines with "search" in them, then runs a substitution s/find/replace on only those lines

:s/\(\d\d\)-\(\d\d\)-\(\d\d\d\d\)/\3-\1-\2
finds a date presumed to be in the broken US format (MM-dd-yyyy) and rearranges it into iso format (yyyy-MM-dd.
the key points in this are the \( and \) surround a part of the searched text we want to reuse in out substitution, and \1, \2, etc refer back to these parts of the text

:let i=10 | 'a,'bg/abc/s/def/\=i/ |let i=i+1
for the range between 'a and 'b, for lines with the string "abc" on them, replace the first occurance of "def" with an incrementing number starting from 10. I commonly have "abc" and "def" set to the same thing (for some reason it doesnt increment if you leave out the "g/abc/" part).



shortcuts

C^p
autocomplete words

z=
show spelling suggestions

zg
add to dictionary



split panes

C^w, n
new pane

:sp filename.txt
open filename.txt in a new pane

:vsp filename.txt
open filename.txt in a new vertical pane

C^w, w
cycle through panes

C^w, down arrow
select pane below

C^w, up arrow
select pane above

C^w, =
all panes equal height

C^w, +
increase selected pane height by 1

C^w, -
decrease selected pane height by 1



VIM RegEx stuff

^
start of line

$
end of line

C^v + C^m
the ^M character that windows users leave on the end of lines



.vimrc
:map <F5> :setlocal spell! spelllang=en_au
:imap <F5> <ESC>:setlocal spell! spelllang=en_au

Use F5 to toggle en_au spelling checker

:map <C-a> 0
:map <C-e> $
:cmap <C-a> <home>
:cmap <C-e> <end>
:imap <C-e> <ESC>$i<right>
:imap <C-a> <ESC>0i

Use Ctrl-a/Ctrl-e to move to the start/end of a line, emacs style i believe

set background=dark
tells vim that your terminal has a dark background, dont use light colours for text

set backspace=indent,eol,start
backspace over anything instead of that broken backspace some distros seem to include

set backup
set backupdir=~/tmp/vim

keep backup files somewhere neat and tidy, instead of having tilde files all over the place

set hlsearch
search highlights all matching terms

set ignorecase
case insensitive searching

set infercase
auto-completion automatically adjusts case of keywords

set number
line numbers

set showmatch
highlights the matching brace briefly when highlighted

set cursorcolumn
set cursorline
hi cursorcolumn ctermbg=red

turns on a row and column highlight to make it easy to find the cursor

set expandtab
set tabstop=2

switches to soft tabs, 2 characters wide

Labels:

Blog purpose

If you're reading this, you're probably a bot, or wondering what the hell this random collection of unrelated crap is for. basically, it's not really intended for anyone but myself, but left public just in case it can be useful to anyone else. not worth adding to your rss client, but if I show up as a result for something you're searching for I may be of help