SessionのBackendをRedisにする
Yesodでディフォルトのセッションストレージはファイルになっているので、そのBackendをRedisにする。
今回使用したライブラリは
- lts-9.10をベースに作成
- serversession-frontend-yesod
- serversession-backend-redis
- hedis
- hedis-config
セイッ
サンプルコード
さんぷるはここへおいときます
https://github.com/calimakvo/sessredis.git
Redisへの接続設定を作成
かいつまんで...
* config/settings.yml
当な場所へ追加、環境変数も利用可能
redis:
host: "_env:REDIS_HOST:localhost" # host name or address
port: "_env:REDIS_PORT:6379" # you can specify either port
# socket: /run/redis.socket # or unix socket path
# service: redis # or service name
password: "_env:REDIS_PASSWORD:" # if not specified then no password used
database: "_env:REDIS_DATABASE:0" # database number to connect to
max-connections: "_env:REDIS_MAX_CONNECTIONS:5" # max 5 connections in pool
max-idle-time: "_env:REDIS_MAX_IDLE_TIME:30" # max 30 idle time in pool
* package.yaml
dependenciesへ追加
dependencies:
..
..
- hedis
- hedis-config
- serversession-backend-redis
- serversession-frontend-yesod
* stack.yaml
extra-depsへ追加
lts-9.10に入っていないパッケージをextra-depsへ追加
extra-deps:
- hedis-config-0.0.3
- serversession-backend-redis-1.0.2
...
ソースをイジる
* src/Settings.hs
import宣言と、RedisConfigの1行を追加、AppSettingsのFromJSONインスタンス宣言にfromYamlAppRedisConfを追加
..
import Database.Redis.Config (RedisConfig (..))
..
..
data AppSettings = AppSettings
{ appStaticDir :: String
-- ^ Directory from which to serve static files.
, appDatabaseConf :: MySQLConf
-- ^ Configuration settings for accessing the database.
, appRedisConf :: RedisConfig
-- ^ Configuration settings for accessing the redis.
, appRoot :: Maybe Text
...
...
instance FromJSON AppSettings where
parseJSON = withObject "AppSettings" $ \o -> do
let defaultDev =
#ifdef DEVELOPMENT
True
#else
False
#endif
appStaticDir <- o .: "static-dir"
fromYamlAppDatabaseConf <- o .: "database"
fromYamlAppRedisConf <- o .: "redis"
appRoot <- o .:? "approot"
appHost <- fromString <$> o .: "host"
appPort <- o .: "port"
...
...
let appRedisConf = fromYamlAppRedisConf {
getConnectInfo = getConnectInfo fromYamlAppRedisConf
}
appAuthDummyLogin <- o .:? "auth-dummy-login" .!= defaultDev
return AppSettings {..}
...
* src/Foundation.hs
import宣言と、関数の宣言、makeSessionBackendの切り替え
...
import qualified Database.Redis as R
import Database.Redis.Config (RedisConfig (..))
import Web.ServerSession.Backend.Redis (RedisStorage(..))
import Web.ServerSession.Frontend.Yesod (setCookieName,
setAbsoluteTimeout,
setIdleTimeout,
simpleBackend)
...
sessionCookieName :: Text
sessionCookieName = "SESSION"
redisStorage :: RedisConfig -> IO (RedisStorage sess)
redisStorage rc = do
conn <- R.connect $ getConnectInfo rc
return $ RedisStorage conn Nothing Nothing
..
..
instance Yesod App where
...
makeSessionBackend app = do
let redisConf = appRedisConf $ appSettings app
simpleBackend opts =<< redisStorage redisConf
where opts = setIdleTimeout (Just $ 30 * 60) -- 30 minutes
. setAbsoluteTimeout (Just $ 2 * 60 * 60 * 24) -- 2 days minutes
. setCookieName sessionCookieName
..
buildと実行
redisサーバーを起動しておいてね
sessredis $ sudo systemctl start redis
sessredis $ stack build && stack exec -- yesod devel
確認
ブラウザからログインして、redisの中をみてみる
karky7 ~ # redis-cli
127.0.0.1:6379> KEYS *
(empty list or set)
127.0.0.1:6379> KEYS *
1) "ssr:session:XSkbZBiMlMsw-yqCGJXNSIxF"
2) "ssr:authid:1"
127.0.0.1:6379>
はいってる
調査不足なところが、RedisStorageのidleTimeoutとabsoluteTimeoutが、simpleBackendのoptsで設定する、timeoutとabsoluteの設定にどう効いてくるのか調べてないとこ、今度しらべる...だれか教えて。
haskellはとにかくたのしい