### 實現Run
### 實現Flock
前面提到進程的文件鎖,實際上Run也用到了,可以試想下以下的場景。
用戶A執行`run pt-summary`,由于本地已經緩存了所以會直接運行本地的腳本。同時用戶B執行`run -u pt-summary`,加上`-u`或者`--update`參數后Run會從遠端下載并運行最新的腳本。如果不加文件鎖的話,用戶A的行為就不可預測了,而文件鎖很好得解決了這個問題。
具體使用方法如下,我們封裝了以下的接口。
~~~
var lockFile *os.File
// Lock the file.
func Flock(path string) error {
return fcntlFlock(syscall.F_WRLCK, path)
}
// Unlock the file.
func Funlock(path string) error {
err := fcntlFlock(syscall.F_UNLCK)
if err != nil {
return err
} else {
return lockFile.Close()
}
}
// Control the lock of file.
func fcntlFlock(lockType int16, path ...string) error {
var err error
if lockType != syscall.F_UNLCK {
mode := syscall.O_CREAT | syscall.O_WRONLY
mask := syscall.Umask(0)
lockFile, err = os.OpenFile(path[0], mode, 0666)
syscall.Umask(mask)
if err != nil {
return err
}
}
lock := syscall.Flock_t{
Start: 0,
Len: 1,
Type: lockType,
Whence: int16(os.SEEK_SET),
}
return syscall.FcntlFlock(lockFile.Fd(), syscall.F_SETLK, &lock)
}
~~~
在運行腳本前就調用鎖進程的方法。
~~~
// Lock the script.
lockPath := cacheDir + ".lock"
err = flock.Flock(lockPath)
if err != nil {
utils.LogError("%s: %v\n", lockPath, err)
os.Exit(1)
}
~~~
### 實現HTTP請求
使用Run時它會自動從網上下載腳本,走的HTTP協議,具體實現方法如下。
~~~
// Retrieve a file via HTTP GET.
func Fetch(url string, path string) error {
response, err := http.Get(url)
if err != nil {
return err
}
if response.StatusCode != 200 {
return Errorf("%s: %s", response.Status, url)
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
if strings.HasPrefix(url, MASTER_URL) {
// When fetching run.conf, etc.
return ioutil.WriteFile(path, body, 0644)
} else {
// When fetching scripts.
return ioutil.WriteFile(path, body, 0777)
}
}
`
~~~
Run的總體代碼是很簡單的,主要是通過解析run.conf下載相應的腳本并執行。
- 前言
- 致謝
- 概述
- 使用代碼
- 使用Docker
- 進程基礎
- 進程是什么
- Hello World
- PID
- PPID
- 使用PID
- 進程名字
- 進程參數
- 輸入與輸出
- 并發與并行
- 進程越多越好
- 進程狀態
- 退出碼
- 進程資源
- 死鎖
- 活鎖
- POSIX
- Nohup
- 運行進程
- Go編程實例
- 衍生新進程
- 執行外部程序
- 復制進程
- 進程進階
- 文件鎖
- 孤兒進程
- 僵尸進程
- 守護進程
- 進程間通信
- 信號
- Linux系統調用
- 文件描述符
- Epoll
- 共享內存
- Copy On Write
- Cgroups
- Namespaces
- 項目實例Run
- 項目架構
- 代碼實現
- 注意事項
- 創建目錄權限
- 捕獲SIGKILL
- Sendfile系統調用
- 后記
- 參考書籍
- 項目學習
- 再次感謝