Bruce 的玩具間

my works and notes on ruby, rails, git, ubuntu linux, mac os x, etc...

避免 pow 動不動就很長等待時間、以及 pow 如何跟 spring/zeus 合作

| Comments

避免 pow 動不動就很長等待時間

TL; DR;

在 Terminal

echo "export POW_TIMEOUT=36000" >> ~/.powconfig
# 或你想自己 vim ~/.powconfig 開來編輯也可
touch ~/.pow/restart.txt

參考 Pow 文件 - 3. Configuring Pow

為什麼要做這件事

因為我手上有幾個肥大的 projects,啟動時間可以到達 60 秒以上,而 pow 預設每 15 分鐘就會 kill 掉 idle 的 app,於是動不動就要等 60 秒啟動,很浪費時間。

如果你只是苦於每一段時間就要等啟動很久,這個方案是最簡單的方法:延長 timeout。

最開始的設定範例中

export POW_TIMEOUT=36000

的時間單位是秒。我的想法是上班時間是 8+1 小時,所以再長一點基本上就沒問題了, 每天早上來只要把所有頁面打開(我集中在一個 bookmark folder),一整天都可以快樂的使用不必等 這樣會很佔記憶體,所以還是只開有用到的吧。

必要的時候還是可以用原本的方法重新啟動 app (touch tmp/restart.txt, powder restart 或用直接用 Anvil)。

pow 如何跟 spring/zeus 合作

之所以有這個段落是因為我一開始以為解決等待時間必須用 rails preloader,後來才發現可以延長 timeout。

很不幸的,目前 pow 跟 spring/zeus 合作並不方便。不過某些情境仍是有好處的,以下說明:

讓 pow 的網址改連到 rails s 打開的 server

如此一來就可以披著 xxx.dev 的網址,實際上連到 rails s -p 3000 (或其他 port) 開好的 server。

參考 pow manual - 2.1.4 Port Proxying

  1. cd ~/.pow/
  2. rm project_name 把你原本的 link 移掉
  3. echo 13001 > project_name 把想用的 port 寫到原名的檔案裡
  4. cd 到你的 project 目錄
  5. rails s -p 13001

需注意如果你有多個 projects,必須自己管理網址跟 port 的對應。

port 我選用 13001~13050,原因是依照 Wikipedia 的 List of TCP and UDP port numbers 來看,這段比較有名的應用是 Second Life,然而現在很少人在玩 (我玩過一陣子)。

優點

  • 可以直接 binding.pry

缺點

  • 必須自己管理 port 對應
  • 必須自己啟動 rails s
  • 如果 zeus 或 terminal app crash,你需要手動刪除 .zeus.socktmp/pids/server.pid 才能順利再啟動
  • 如果你手上有 5 個站、而且還會互打 API,上面三點就會非常麻煩了(每次重開或 crash 就要處理 5~10 個 tabs)

spring 的問題

spring 的問題是它根本沒有 preload spring rails s (issue 72),所以跟 rails s 意思是一樣的。

附帶一提,關於到底該用 spring rails 還是 bin/railsspring/README 裡其實有提到:

If you don't want spring-related code checked into your source repository, it's possible to use spring without adding to your Gemfile. However, using spring binstubs without adding spring to the Gemfile is not supported.

To use spring like this, do a gem install spring and then prefix commands with spring. For example, rather than running bin/rake -T, you'd run spring rake -T.

簡單來說就是你如果不寫進 Gemfile,就必須用 spring rails

zeus 的問題

zeus 需要兩個 terminal app tabs,一個開 zeus start 另一個跑 zeus s -p 13001,所以你如果有 5 個主要 projects,就要為了這件事開 10 個 tabs...

另外雖然動到 config 時 zeus 本身會自動重開,卻不會重開 zeus s,所以你還是要手動 ctrl+c 關掉重開。據說以前會自動處理,不曉得這是 bug 還是 feature...

唯一的好處可能是動到 config 的時候,重開 zeus s 還是比 rails s 或 pow 重開快一點。

如果你手上的專案不多,想採取這個方案的話,我嘗試過這樣的技巧:

echo "13001" > .pow_port    # 把要用的 port 寫到專案根目錄
zeus s -p $(more .pow_port) # 以後只要下同樣的指令就可以打開

但還不夠完美,有需要的話可以再想想怎麼改善。也歡迎留言回報你的解法囉!

結論

  • 如果你手上有很多肥大 projects,可以用延長 timeout 來節省時間
  • 如果你很常用 pry 來 debug,但覺得 binding.remote_pry 不好用的話,用 Port Proxying 解法可以維持 xxx.dev 的網址且可用 binding.pry

UPDATE:

「Deliver Project on Time 敏捷專案管理實務」上課心得

| Comments

每個組織的狀況不一樣,遇到的問題與性質都不一樣,沒有銀色子彈,聽聽別人的經驗,自己想想,依照不同環境摸索出適合的方法。

這種課其實有多實務精華在 Q&A 裡,而且花一樣的錢可以問到飽,當然要問啊! 所以請開始在工作中蒐集想問的問題。

這篇心得只整理出我新學到的要點,因為我到目前的工作都有在使用 issue tracking system 跟 git,所以很多觀念對我來說都是理所當然的,但我也知道很多公司並未導入這些制度,因此看這篇還覺得無法掌握的,建議報名去完整的聽一次主要的流程。

issue 的 email 爆炸問題

Filter 設標籤並藏起來,基本上只用 HipChat 看。

票要切到多細?

開票不用錢,就跟 git 開 branch 不用錢一樣,所以盡量開

有幾個可檢驗的指標:

  • junior developer 可以在半天內解 1~3 張票的細度。
  • 最末端的 1 張票可以 = 1 個 commit

其實還有很多觀念(User story 的寫法、SMART 原則等),這部份有需要就自己報名唄。

使用 milestone

說來慚愧,milestone 的觀念我在大學的軟體工程課就有學過,但到現在都還沒認真使用,接下來會好好利用了 QQ

xdite 的 milestone 分法是以週為單位,milestone 的名稱就是該週編號。

一般來說,以時間為 title 會面臨的問題就是當有一週延後或提早,後面的數字都要逐一補位,很麻煩。xdite 的解法是將該週可放棄的項目移到 week 999 (nice to have),或跟 project owner 討論後決定要怎麼調整。如果該週進度提早的話就拿 week 999 的來塞。

不過我認為這麼做有其前提與原因,切 milestone 要夠準(夠有經驗),且每週都有個重要的 business value 要 deliver,因此維持原本的 week 編號就很重要。

場地與伙食

場地還在 CLBC,不用脫鞋入內,這次沒有擺桌子,所以很多人都用紙筆記錄,拿 Macbook Air 當墊板...

伙食一句話就是「有誠意」(肯砸錢在外燴,以及依照經驗選擇受歡迎的料理),不過這不是學習的重點,有興趣可以自己去找別人拍的照片。

讀 Sublime Text 3 文件學到的新招

| Comments

摸熟你的開發工具是很重要的,每天都用沒效率的方法做事,長期下來很浪費時間。最近我在看《程式設計師提升生產力秘笈》一書,裡面當然也提到這個老生常談,剛好就卯起來把 Sublime Text 3 官方文件 看完了 (除了開發 API 章節),這邊整理出一些我以前還不知道的好用技巧。

不過這份文件其實很短,每一節大概都只有一個螢幕長度而已,應該比較適合新手一開始就看。也就是說,設定部分還是要親自讀一遍 Settings - Default,快速鍵則建議讀非官方文件,好用外掛或特殊設定則要搜尋看看,例如 讓 Sublime Text 也擁有 "Navigate to Definition" 功能安裝 Sublime Text 3 互動式 Ruby Debug 外掛 其實從網路上找到提示才試出來的。

警語:《程式設計師提升生產力秘笈》翻譯不太通順,如果弄得到英文版的話可考慮直接讀英文版。

多行選擇相關

一次選擇多行以後按 Command+Shift+L 即可把輸入點切成每行一個

Command+D 選擇 occurrences 時

  • 不小心選多了可以用 Command+U 倒車
  • Command+K,Command+D 跳過某個 (剛選到的) occurrence
  • 做完多行操作後,按 Esc 回到單輸入點模式

自動完成相關

  • 由於 ctrl+space 在 mac 上會跟 spotlight 快捷鍵衝突,應改掉 個人習慣改成 Command+/ 發現會跟 toggle comment 衝突,不過我發現我也很少手動 toggle 自動完成
  • 出現自動完成選單時,按 tab 會自動完成,但若真的想輸入 tab 字元的話,可以用 Shift+tab

Project

Sublime 有個 Project 選單,但好像不多人用,我也只亂玩過一下而已。但這次看到一個功能我覺得值得嘗試:

Settings 可以寫在 project 設定檔裡,這樣就可以讓所有人都使用相同的設定,例如 tab 轉 2 個 spaces、trim trailing space、newline at eof 等 coding style 問題。

過去不常使用快速鍵者

如果你有心想記起快速鍵,打開選單看到快速鍵提示後,關掉選單,用快速鍵做。浪費幾次時間以後就會記住了,接下來節省的時間絕對可以賺回來。(《程式設計師提升生產力秘笈》建議的方法)

也可以把常用又想記住的快速鍵印出來貼在座位旁邊,快速查找。(我之前用白板筆寫在玻璃 OA 隔板上)

如何簡化「常常在 rails console 裡反覆輸入某些指令」的狀況

| Comments

開發的時候常需要在 rails console 下尋找一個 user 來做某些實驗,通常是用自己的帳號,因此就會每天都在敲 user = User.find_by_email(自己的 email),很浪費時間,用這個技巧就可以改善此類問題。

解決方法

在家目錄底下建立 .irbrc (如果用 pry-rails,則是 ~/.pryrc)

~/.irbrc
def find_me
  User.find_by_email("your_mail@example.com")
end

之後就可以在 rails console 下

[1] pry(main)> user = find_me
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`email` = 'your_mail@example.com' LIMIT 1
  ...

常在 rails console 下打的指令都可以考慮如何利用這個手法,但必須注意 method 命名不能跟現有專案的衝突。

ps. 以前我會寫一支開發專用的 app/models/dev.rb,裡面有各種方便的 methods,但由於現在手上專案很多,每個都加一次很麻煩,其他人可能也不想共用這種手法,所以現在改採不會動到專案 code 的解決方案。

Capistrano 自動選擇當前 branch deploy 到 staging

| Comments

一般 config/deploy/staging.rb 的 branch 內容可能會設定成如下:

config/deploy/staging.rb
# ...

set :branch, "staging"
set :rails_env, "staging"
# ...

我們團隊使用 GitHub Flow,常常會 deploy 非 master 的 branch 到 staging 上。照上面的 config 設定,要麻把 staging branch reset 到目前的 commit (很麻煩),不然就是把 set :branch 改成當前的 branch 名稱、但不 commit。

但即使如此,還是很麻煩,而且有時候會忘記改。

搜尋 & 嘗試了一下,最後我改成:

config/deploy/staging.rb
# ...

set :branch, ENV["BRANCH"] || `git rev-parse --abbrev-ref HEAD`.chop
set :rails_env, "staging"
# ...

其中

`git rev-parse --abbrev-ref HEAD`.chop

可以丟到 rails console 執行看看,就是取得當前的 git branch name

這樣設定以後,只要在 terminal 下:

cap staging deploy

就會自動選擇當前的 branch 來 deploy 了(production 則當然保持 "master" 不改)。

另外,若有一些情況想要「在這個 branch 但 deploy 那個 branch」的話,可以:

BRANCH=other_branch cap staging deploy

這個技巧在 capistrano 2 跟 3 都適用。

2014-09-29 更新:Capistrano 不知道從何開始範例檔有以下的 code,與上面取得 branch 名稱的解法意思差不多,但使用 chomp 的確是比較好的習慣。

proc { `git rev-parse --abbrev-ref HEAD`.chomp }.call