Reactサンプルアプリ開発 プラニングポーカー (9) Redisを使う

Poker サンプル開発

プラニングポーカーの場の情報(場名や参加プレイヤー名)をFlaskアプリケーションのトップレベルの変数に格納していたが、これだとHerokuにデプロイしたときにちゃんと動作しないので、Redisに永続化することにする。

ローカル環境ではDockerでRedisサーバを起動しよう。

version: '2'

services:
  redis:
    image: redis:latest
    ports:
      - "6379:6379"
    command: redis-server --appendonly yes
    volumes:
       - ./data/redis:/data

上記のdocker-compose.ymlを用意し、コンテナをバックグラウンド実行で起動する。

$ docker-compose up -d

Pythonでアクセスするためのライブラリをインストール。

(venv) $ pip install redis

Herokuにデプロイするために依存ライブラリをrequirements.txtに書き出しておく。

(venv) $ pip freeze > requirements.txt

現在のrequirements.txtはこんな感じ。

click==7.1.1
Flask==1.1.1
Flask-SocketIO==4.3.0
gunicorn==20.0.4
itsdangerous==1.1.0
Jinja2==2.11.1
MarkupSafe==1.1.1
python-engineio==3.12.1
python-socketio==4.5.1
redis==3.5.0
six==1.14.0
Werkzeug==1.0.0

Flaskアプリケーションでインポート。

import redis

初期化。

# Redis
REDIS_URL = (
    os.environ.get("REDIS_URL")
    if os.environ.get("REDIS_URL") != None
    else "redis://localhost:6379"
)
DATABASE_INDEX = 1
pool = redis.ConnectionPool.from_url(
    REDIS_URL, db=DATABASE_INDEX, decode_responses=True
)
db = redis.StrictRedis(connection_pool=pool)
EX = 86400  # 1日

Herokuにデプロイすると環境変数REDIS_URLに接続先URLがセットされているので、それを見るようにする(2-6行目)。
コネクションプールの初期化パラメータでdecode_responsesを指定し、自動デコードされるようにしておく(9行目)。
12行目の定数は、Redisに書き込んだデータの生存期限を表す定数(あとで使用する)。

データの書き込み。

    table_id = str(uuid.uuid4())
    player_id = 0  # 親は0とする
    db.hset(table_id, "name", table_name)
    db.hset(table_id, "players", parent_name)
    db.expire(table_id, EX)

場のID(table_id)をキーとして、複数の値を管理したいため、hset関数を使って書き込む(3-4行目)。
その後expire関数で生存期限を指定(5行目)。

データの読み出し。

    table = db.hgetall(table_id)
    table_name = table["name"]
    players = table["players"]

hgetall関数を使えばすべての属性をディクショナリで取り出せる(1行目)。

ローカルで動作するようになったので、Herokuにデプロイする。
その前に、gunicornのパラメータを変更しておきたい。デフォルトだと1ワーカープロセス、1スレッドなので完全直列処理になってしまう。

web: gunicorn app:app --workers 2 --thread 4 --log-file -

無料Dynoなのでこんなところか?

【2020-5-9追記】
gunicornで複数ワーカープロセス設定をすると、Flask-SocketIOで400 Bad Requestエラーが起こることが判明。詳細と対処方法は次回記事に記載。

あとはHerokuのWebコンソールからRedisアドオンを追加しておいて(これもフリープランがあるので助かる!)、いつもどおりpushすればOK。

$ git push heroku master

無事Redisを使ったデータ永続化が実現できた。
ようやくアプリケーションのバーティカルスライスが通ったので、この先は機能を作り込んでいく。

コメント

  1. […] まず初めに前回の投稿で書いた以下の設定はNGだったので修正する。具体的には、WebSocket通信が一定数で404 Bad requestになってしまう現象が起こった。どうやらgunicornのロードバランシング機能がスティッキーセッションをサポートしていないのが原因らしい。 […]

タイトルとURLをコピーしました