Bear Su's Blog

Ruby gem daemons 筆記

Table of Contents

cover

圖片來源 フリー写真素材ぱくたそ

daemons gem 是一個能夠讓 ruby 程式以行程(process)獨立執行的 gem

當你想要有一個程式能夠在背景持續執行時,就可以可慮使用 daemons gem 來協助開發

什麼是 daemon?可以參考鳥哥的文章 17.1 什麼是 daemon 與服務 (service)

簡單來說可以當作是在背景一直執行的服務

透過 daemons gem 你可以:

  1. 將其他 script 作為 daemon 執行
  2. 將 proc 丟到 daemon 執行
  3. 將目前執行的程式變成 daemon 執行

寫個範例


範例程式(main.rb)是一個可以用在程式中建立 每 5 秒將 Process 名稱寫入 Log 的 daemon:

# main.rb
require 'daemons'
require "logger"

# 在執行的時候先取得當前目錄的絕對路徑
DIR = File.absolute_path(File.dirname(__FILE__))

class TittleDaemon
  def run(name)
    # 修改行程 (Process) 顯示的名稱
    Process.setproctitle(name)

    logger = Logger.new(log_path(name), 'daily')

    loop do
      logger.info "daemon #{name} is running"
      sleep(5)
    end
  end

  def log_path(name)
    File.join(DIR, "#{name}-running.log")
  end
end

class Main
  def start(name)
    options = {
      :ARGV                 => ['start'], # 啟動 daemon
      :backtrace            => true # 如果有發生例外會記錄到 log 中
    }
    Daemons.run_proc(name, options) { TittleDaemon.new.run(name) }
  end

  def stop(name)
    options = {
      :ARGV               => ['stop'], # 停止 daemon
      :backtrace          => true # 如果有發生例外會記錄到 log 中
    }
    Daemons.run_proc(name, options) { TittleDaemon.new.run(name) }
  end
end

操作:

首先在 Terminal 中開啟 irb,並加上 -r 參數在啟動 irb 的同時 require ./main.rb

$ irb -r ./main.rb

在 irb 中建立 Main 的實體,並啟動一個名為 little-daemon 的 daemon

> main = Main.new
> main.start("little-daemon")
start little daemon

開啟另一個 Terminal 執行

$ ps aux | grep little
check little daemon

發現有一個名為 little-daemon 的行程正在執行

回到第一個 Terminal,這次我們請啟動另一個名為 little-daemon2 的 daemon

> main.start("little-daemon2")
start little daemon2

在第二個 Terminal 執行以下指令可以觀察到 little-daemon2 也在執行了

$ ps aux | grep little
check little daemon2

看看目錄底下有什麼:

$ ls -lh
check directory

可以發現除了預計會產生的 log 之外,還多了兩個結尾為 .pid 的檔案

用文字編輯器可以打開,裡面是記錄 daemon 的 PID

透過 PID 我們可以傳送訊號給 daemon ,像是立即停止,或是做其他運用

可以參考鳥哥文章 16.1 什麼是程序 (process)

最後我們回到第一個 Terminal 停止剛剛啟動的 daemon

> main = Main.new
> main.stop("little-daemon")
> main.stop("little-daemon2")
stop daemons

在第二個 Terminal 執行以下指令會發現 daemon 已經停止,結尾為 .pid 的檔案也已經被刪除了

$ ps aux | grep little
$ ls -lh
check pids are deleted

尾聲


想要更了解 daemons 的話,推薦玩玩 GitHub 上的 範例

還有看看程式碼裡的註解

了解一下傳入的 options 有哪些選項可以使用

要注意的是程式碼一直都有在更新,記得在閱讀的時候要將 branch 調成目前所使用的版本才不會錯亂喲

git branch

參考


Ruby daemons gem official repository

歡迎光臨鳥哥的 Linux 私房菜


如果覺得這篇文章對您有所幫助,歡迎贊助我一杯咖啡 ☕️

祝您有美好的一天 ❤️