haskellでmemcachedにアクセスする
ここ最近pythonなどでmemcacheを触ることが多かったので、「haskellにはあるのかな?」と思い探して見たところ、githubのbeketaさんのリポジトリにhaskell-memcachedが公開されていましたのでforkさせて頂き、Gentoo用のebuildを作らさせていただきました。
ありがとうございました。
haskell-memcacheインストール
自分の使用しているghcが7.6.3で現行のバージョンが動かなかったため、ちょっとcabalファイルにパッチを当てさせてもらいました。インストールはGentooでしたら、
karky7 ~ # emerge -pv dev-haskell/memcached [ebuild N ~] dev-haskell/memcached-9999:0/9999::karky7 USE="doc hscolour -profile" 0 kB karky7 ~ #
直接git cloneでしたら、
cuomo@karky7 ~/blogs $ git clone https://github.com/karky7/haskell-memcached.git Cloning into 'haskell-memcached'... remote: Counting objects: 111, done. remote: Compressing objects: 100% (58/58), done. remote: Total 111 (delta 55), reused 105 (delta 51) Receiving objects: 100% (111/111), 17.94 KiB, done. Resolving deltas: 100% (55/55), done. cuomo@karky7 ~/blogs $ cd haskell-memcached/ cuomo@karky7 ~/blogs/haskell-memcached $ runhaskell Setup.hs installでいくとは思われますが、やった事はございません。
クライアントコードを書いてみる
インストールが完了したら、実際にアクセスできるか試します、テストコードを見つつ、サンプルコードを書いてみました。処理内容は以下の3つ
- memcachedの設定値の取得
- Intの値の保存と取得
- ユーザー定義型の保存と取得
import qualified Network.Memcache as M import Network.Memcache.Protocol as P import Network.Memcache.Serializable(Serializable(..)) import Data.ByteString.Char8 as C (pack, unpack, words) data User = User { getUsername :: String, getAge :: Int } deriving Show instance Serializable User where serialize (User name age) = pack $ name ++ " " ++ show(age::Int) deserialize str = case C.words str of (un:ag:[]) -> Just (User (unpack $ un) (read (unpack ag))) _ -> Nothing main :: IO () main = do memcache <- P.connect "localhost" 11211 -- Memcacheステータス表示 putStrLn "------------------" putStrLn "Memcacheステータス" putStrLn "------------------" status <- stats memcache _ <- mapM (\tp -> do let name = fst tp val = snd tp putStr $ name ++ " = " ++ val ++ "\n") status putStrLn "" -- Int値を保存 let foo = 8888 :: Int putStr "Setting foo => 3: ... " >> M.set memcache "foo" foo >>= putResult -- Int値を取得 foo' <- M.get memcache "foo" case foo' of Nothing -> putStrLn "Retrieving foo: expired from cache?" Just v -> putStrLn ("Cached value for foo is " ++ show (v::Int) ++ ".") -- ユーザー定義型を保存 let ando = User "#Ando" 29 putStr "#A to memcache ... " >> M.set memcache "ando" ando >>= putResult -- ユーザー定義型を取得 ando' <- M.get memcache "ando" case ando' of Nothing -> putStrLn "#Aは逝ってしまいました" Just v -> putStrLn $ "#A 見っけ お名前は " ++ getUsername v ++ " お年は " ++ show (getAge v) P.disconnect memcache putResult :: Bool -> IO() putResult r = case r of True -> putStrLn "成功じゃないの" _ -> putStrLn "それそれ..."
memcachedへ接続してみる
まずmemcachedデーモンを起動しましてサンプルコードの実行karky7 ~ # /etc/init.d/memcached start * Starting memcached ... * You should edit /etc/conf.d/memcached and specify an address to listen on. * Listening on any address (check your firewall!) [ ok ] karky7 ~ #
cuomo@karky7 ~ $ runhaskell memcache_client.hs ------------------ Memcacheステータス ------------------ pid = 7704 uptime = 179 time = 1376452659 version = 1.4.5 pointer_size = 64 rusage_user = 0.016000 rusage_system = 0.000000 curr_connections = 10 total_connections = 11 connection_structures = 11 cmd_get = 0 cmd_set = 0 cmd_flush = 0 get_hits = 0 get_misses = 0 delete_misses = 0 delete_hits = 0 incr_misses = 0 incr_hits = 0 decr_misses = 0 decr_hits = 0 cas_misses = 0 cas_hits = 0 cas_badval = 0 auth_cmds = 0 auth_errors = 0 bytes_read = 7 bytes_written = 0 limit_maxbytes = 67108864 accepting_conns = 1 listen_disabled_num = 0 threads = 4 conn_yields = 0 bytes = 0 curr_items = 0 total_items = 0 evictions = 0 reclaimed = 0 Setting foo => 3: ... 成功じゃないの Cached value for foo is 8888. #A to memcache ... 成功じゃないの #A 見っけ お名前は #Ando お年は 29 cuomo@karky7 ~/Code/haskell/memcached $
memcached付属のコマンドツールでメモリをdumpしてみる
cuomo@karky7 ~ $ memcached-tool localhost dump Dumping memcache contents Number of buckets: 1 Number of items : 2 Dumping bucket 1 - 2 total items add foo 0 1376452480 4 8888 add ando 0 1376452480 8 #Ando 29 cuomo@karky7 ~ $
#A君を突っ込んで、出したりと出きるようになりました、User型みたいのは別として、シリアライズ方法がshowとreadで概ねhaskell用になっているのでjsonとかで保存すれば汎用性が上がっていいかもしれません。
しかし、haskellは書いてて楽しい
0 件のコメント:
コメントを投稿