EnsekiTT Blog

EnsekiTTが書くブログです。

Pythonでデーモンを召喚した話

デーモンってちゃんと説明するとなんだっけ?

と思ってWikipediaで調べてきた。
UNIXなどのマルチタスクオペレーティング・システムにおいてバックグラウンドプロセスとして動作するプログラムを意味する。ユーザが直接対話的に制御するプログラムではない。典型的なデーモンは名前の最後尾に”d”がつく。例えばSyslogdはシステムログを扱うデーモンだ。
UNIX系の環境では、デーモンの親プロセスはinitプロセスになっていることが多い。
デーモンは起動処理内でForkで子プロセスを作成し、親プロセスのほうが即座に終了するため、initが里親となる。更に、デーモンまたはOSは制御端末(tty)からの切り離しなどの処理も行う必要がある。こういったデーモンを生成するための手続きをUNIX系ではdaemon(3)などの便利なルーチンにまとめて実装していることが多い。

Pythonによるデーモンのサンプルスクリプト

import os
import sys
import time

def createDaemon():
    pid = os.fork()

    if pid > 0:
        f2 = open('/var/run/oredaemon.pid','w')
        f2.write(str(pid)+"\n")
        f2.close()        
        sys.exit()

    if pid == 0:
        i = 0
        while True:
            f = open('/home/ensekitt/testest.txt','a')
            f.write(str(i) + "\n")
            f.close()
            time.sleep(1)

            i += 1

if __name__ == '__main__':
    createDaemon()

HerokuボタンでイカしたTornadoアプリをみんなに使ってもらいたい

つまり何したの?

Tornadoアプリを作ってフォークして使ってもらえるようにした。

環境:

前回のDjangoの例から拾い上げた必要そうな要素:

  • Procfile
  • runtime.txt
  • requirements.txt
  • app.json

すぐ使えるように作ったリポジトリがこちら
github.com

試してみる

# 拾ってくる
% git clone https://github.com/EnsekiTT/HerokuTest.git
% cd HerokuTest

# Heroku上で実行する
% heroku create
% git push heroku master
% heroku open

# ローカルで実行する
% pyenv virtualenv 3.5.2 herokutest
% pyenv local herokutest
% pip install -r requirements.txt

必要そうな要素の説明

Procfile: 実行するコマンドを指定する

web: python server.py --port=$PORT

Herokuのポート番号は$PORTで与えられることに注意

runtime.txt: Pythonのバージョンを指定する

python-3.5.2

このファイルを用意しないでPythonを実行すると2.7系が選択される

requirements.txt: 必要なPythonのパッケージを指定する

tornado==4.4.2

ここではTornadoだけ。必要に応じて

pip freeze > requirements.txt

などして追加編集する

server.py: サーバ本体

import tornado.ioloop
import tornado.web

from tornado.options import define, options
define("port", default=5000, help="run on the given port", type=int)
tornado.options.parse_command_line()

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(tornado.options.options.port)
tornado.ioloop.IOLoop.current().start()

Tornadoのチュートリアルとほとんど同じ。
Tornado Web Server — Tornado 4.4.2 documentation


Procfileの指定の通り、ポート番号を引数で得るように変更してある。

App.json: Herokuボタンのための設定JSON

{
  "name": "HerokuTest",
  "env": {
    "APP_USER_NAME": ""
  }
}

アプリの名前と、このタイミングで入れてもらいたい環境変数などを指定できる。
(どっかのAPIを使っているならAPIキー等)

まとめ

これでHerokuボタンで使ってもらえるかも知れないアプリが作れるようになった。

クリエイティブ・コモンズ・ライセンス
この 作品 は クリエイティブ・コモンズ 表示 4.0 国際 ライセンスの下に提供されています。