在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ 實現(xiàn)Run
信號
創(chuàng)建目錄權(quán)限
示例程序
進(jìn)程的定義
Hello World進(jìn)程
創(chuàng)建進(jìn)程
進(jìn)程鎖
第四章 項目實例Run
Nohup命令
PID
前言
系統(tǒng)調(diào)用sendfile
進(jìn)程參數(shù)
參考書籍
后記
進(jìn)程狀態(tài)
本書概述
寫時復(fù)制(Copy On Write)
Docker簡介
第五章 注意事項
實現(xiàn)Run
孤兒進(jìn)程概念
共享內(nèi)存
衍生(Spawn)新進(jìn)程
PPID
第三章 進(jìn)程進(jìn)階
退出碼
簡介
進(jìn)程文件
Thanks for reading!
項目學(xué)習(xí)
第一章 進(jìn)程基礎(chǔ)
僵尸進(jìn)程
系統(tǒng)調(diào)用
POSIX簡介
執(zhí)行(Exec)外部程序
文件描述符
進(jìn)程名字
進(jìn)程輸入與輸出
Cgroups
進(jìn)程間通信
查看PID
死鎖概念
進(jìn)程越多越好?
Run項目架構(gòu)
  • 1.
復(fù)制(Fork)進(jìn)程
第二章 Go編程實例
活鎖概念
守護(hù)(Daemon)進(jìn)程
并發(fā)與并行
捕獲SIGKILL
Namespaces簡介

實現(xiàn)Run

實現(xiàn)Run

實現(xiàn)Flock

前面提到進(jìn)程的文件鎖,實際上Run也用到了,可以試想下以下的場景。

用戶A執(zhí)行run pt-summary,由于本地已經(jīng)緩存了所以會直接運行本地的腳本。同時用戶B執(zhí)行run -u pt-summary,加上-u或者--update參數(shù)后Run會從遠(yuǎn)端下載并運行最新的腳本。如果不加文件鎖的話,用戶A的行為就不可預(yù)測了,而文件鎖很好得解決了這個問題。

具體使用方法如下,我們封裝了以下的接口。

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)
}

在運行腳本前就調(diào)用鎖進(jìn)程的方法。

// Lock the script.
lockPath := cacheDir + ".lock"
err = flock.Flock(lockPath)
if err != nil {
  utils.LogError("%s: %v\n", lockPath, err)
  os.Exit(1)
}

實現(xiàn)HTTP請求

使用Run時它會自動從網(wǎng)上下載腳本,走的HTTP協(xié)議,具體實現(xiàn)方法如下。

// 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下載相應(yīng)的腳本并執(zhí)行。