[{"id":24641,"uuid":"3dc068f73b84cf731d02","user":{"id":853,"url_name":"fukkyy","profile_image_url":"https://twimg0-a.akamaihd.net/profile_images/2076055239/tux_tw_normal.png"},"title":"ローカルブランチとリモートブランチ","created_at":"2013-08-14 16:29:08 +0900","updated_at":"2013-08-14 16:29:08 +0900","created_at_in_words":"2分前","updated_at_in_words":"2分前","tags":[{"name":"git","url_name":"git","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/79cc9484a6f1bf99038b0b0c527a9426acb429a7/medium.jpg?1364838337","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/fukkyy/items/3dc068f73b84cf731d02","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376465348,"raw_body":"\nほい\n\n```\ngit branch --set-upstream \u003Cbranch\u003E origin/\u003Cbranch\u003E\n```","body":"\u003Cp\u003Eほい\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Egit branch --set-upstream \u0026lt;branch\u0026gt; origin/\u0026lt;branch\u0026gt;\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E"},{"id":24640,"uuid":"e6eec734fc018f570f7c","user":{"id":25380,"url_name":"ballforest","profile_image_url":"https://si0.twimg.com/profile_images/2421137085/r8gs0302skjndlzmhhhw_normal.jpeg"},"title":"FlymakeのためのHelm インターフェイス helm-flymakeを書いたので紹介","created_at":"2013-08-14 16:09:32 +0900","updated_at":"2013-08-14 16:11:15 +0900","created_at_in_words":"21分前","updated_at_in_words":"19分前","tags":[{"name":"Emacs","url_name":"emacs","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/2920f41f5aefd36267c6c04183d7e6197b4d2b99/medium.jpg?1364837723","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/ballforest/items/e6eec734fc018f570f7c","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376464172,"raw_body":"#はじめに\nFlymakeはEmacsでコードを書く諸氏なら,使っている道具の一つだろうか.\n筆者はかつてFlymakeのためのHelm インターフェイスを書いたので,ここにドキュメントを残しておく.\n\n#ソースコード\nGithubにリポジトリを作成してある.\nhttps://github.com/tam17aki/helm-flymake\nなおMELPAからもダウンロード可能である.\n\n#インストール\n以下を設定ファイルに加える.\nhelm系の拡張であるので,helm-configも念のために書いてある.\nMELPAからダウンロードしている場合,```(package-initialize)```を実行しておけば不要である(と思う).\n\n```el:\n(require 'helm-config)\n(require 'helm-flymake)\n```\n\n#使い方\nflymakeを使用中,すなわち`flymake-mode`が`t`のときに,`M-x flymake`を実行すると,\nflymakeで検出されるwarningとerrorメッセージの一覧が\\*helm flymake\\*バッファに表示される.\nwarningとerrorが何もないときはこのバッファは空になる.\n\nミニバッファに文字を入力することで候補が絞り込まれる.\nまた`C-u M-x flymake`とすると,現在カーソルがある行の行番号(厳密に言えば末尾にコロンつき)をデフォルト入力としてミニバッファに放り込む.候補絞り込みの役には立つだろう.\n\n#おわりに\nこのようにhelm-flymakeを書いてみたものの,大抵はワーニング/エラーというのはソースの先頭から潰していくので絞りこみの機能はあまり役に立たないかもしれない.\nそれでも仕事の上ではそこそこ便利に使えている.\n","body":"\u003Ch1\u003E\n        \u003Cspan id=\"1-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eはじめに\n      \u003C/h1\u003E\u003Cp\u003EFlymakeはEmacsでコードを書く諸氏なら,使っている道具の一つだろうか.\u003Cbr\u003E\n筆者はかつてFlymakeのためのHelm インターフェイスを書いたので,ここにドキュメントを残しておく.\u003C/p\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eソースコード\n      \u003C/h1\u003E\u003Cp\u003EGithubにリポジトリを作成してある.\u003Cbr\u003E\n\u003Ca href=\"https://github.com/tam17aki/helm-flymake\" title=\"https://github.com/tam17aki/helm-flymake\" target=\"_blank\"\u003Ehttps://github.com/tam17aki/helm-flymake\u003C/a\u003E\u003Cbr\u003E\nなおMELPAからもダウンロード可能である.\u003C/p\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eインストール\n      \u003C/h1\u003E\u003Cp\u003E以下を設定ファイルに加える.\u003Cbr\u003E\nhelm系の拡張であるので,helm-configも念のために書いてある.\u003Cbr\u003E\nMELPAからダウンロードしている場合,\u003Ccode\u003E(package-initialize)\u003C/code\u003Eを実行しておけば不要である(と思う).\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"ss\"\u003E\u0026#39;helm-config\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"ss\"\u003E\u0026#39;helm-flymake\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch1\u003E\n        \u003Cspan id=\"1-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E使い方\n      \u003C/h1\u003E\u003Cp\u003Eflymakeを使用中,すなわち\u003Ccode\u003Eflymake-mode\u003C/code\u003Eが\u003Ccode\u003Et\u003C/code\u003Eのときに,\u003Ccode\u003EM-x flymake\u003C/code\u003Eを実行すると,\u003Cbr\u003E\nflymakeで検出されるwarningとerrorメッセージの一覧が*helm flymake*バッファに表示される.\u003Cbr\u003E\nwarningとerrorが何もないときはこのバッファは空になる.\u003C/p\u003E\n\u003Cp\u003Eミニバッファに文字を入力することで候補が絞り込まれる.\u003Cbr\u003E\nまた\u003Ccode\u003EC-u M-x flymake\u003C/code\u003Eとすると,現在カーソルがある行の行番号(厳密に言えば末尾にコロンつき)をデフォルト入力としてミニバッファに放り込む.候補絞り込みの役には立つだろう.\u003C/p\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-5\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-5\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eおわりに\n      \u003C/h1\u003E\u003Cp\u003Eこのようにhelm-flymakeを書いてみたものの,大抵はワーニング/エラーというのはソースの先頭から潰していくので絞りこみの機能はあまり役に立たないかもしれない.\u003Cbr\u003E\nそれでも仕事の上ではそこそこ便利に使えている.\u003C/p\u003E\n"},{"id":24639,"uuid":"1710ac3259246da44697","user":{"id":13601,"url_name":"fnobi","profile_image_url":"https://secure.gravatar.com/avatar/f18575c098ff61c776f2a82ef477fadb?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"asyncって案外すぐ書ける","created_at":"2013-08-14 16:04:14 +0900","updated_at":"2013-08-14 16:04:14 +0900","created_at_in_words":"26分前","updated_at_in_words":"26分前","tags":[{"name":"async","url_name":"async","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"JavaScript","url_name":"javascript","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/c01023cf926d47b711747c9d00b00fd18dc6638a/medium.jpg?1364837881","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/fnobi/items/1710ac3259246da44697","gist_url":"https://gist.github.com/6228641","tweet":true,"private":false,"created_at_as_seconds":1376463854,"raw_body":"\n超小ネタ。\n\ncallback地獄っぽくなってきたけど、ライブラリ使うほどじゃないなーって感じだったので、\nasync(functionの配列を渡して、それぞれcallbackされたら次のを実行)を自前実装してみたら、\nあんがい短かった。\n\n```\n// 簡易な非同期処理                                                                   \nvar async = function (fns) {\n    (function exec (index) {\n        if (!fns[index]) {\n            return;\n        }\n        fns[index](function () {\n            exec(index + 1);\n        });\n    })(0);\n};\n```\n\nだいたいは使うとしてもこれだけだし、(waterfallとか使いだすとむしろややこしい)\nこれをコピペできるようにしておくだけでも十分かも。\n\n## 参考\n- [async](https://npmjs.org/package/async)\n- [heavylifters/deferred-js](https://github.com/heavylifters/deferred-js)","body":"\u003Cp\u003E超小ネタ。\u003C/p\u003E\n\u003Cp\u003Ecallback地獄っぽくなってきたけど、ライブラリ使うほどじゃないなーって感じだったので、\u003Cbr\u003E\nasync(functionの配列を渡して、それぞれcallbackされたら次のを実行)を自前実装してみたら、\u003Cbr\u003E\nあんがい短かった。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E// 簡易な非同期処理                                                                   \nvar async = function (fns) {\n    (function exec (index) {\n        if (!fns[index]) {\n            return;\n        }\n        fns[index](function () {\n            exec(index + 1);\n        });\n    })(0);\n};\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eだいたいは使うとしてもこれだけだし、(waterfallとか使いだすとむしろややこしい)\u003Cbr\u003E\nこれをコピペできるようにしておくだけでも十分かも。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E参考\n      \u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\"https://npmjs.org/package/async\" title=\"https://npmjs.org/package/async\" target=\"_blank\"\u003Easync\u003C/a\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Ca href=\"https://github.com/heavylifters/deferred-js\" title=\"https://github.com/heavylifters/deferred-js\" target=\"_blank\"\u003Eheavylifters/deferred-js\u003C/a\u003E\u003C/li\u003E\n\u003C/ul\u003E\n"},{"id":24638,"uuid":"41a855f8a372a88672f8","user":{"id":20722,"url_name":"JunSuzukiJapan@github","profile_image_url":"https://secure.gravatar.com/avatar/097319988f40151f72e50d4691e7a542?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"[Unity]Booの関数メモ","created_at":"2013-08-14 15:39:01 +0900","updated_at":"2013-08-14 16:20:41 +0900","created_at_in_words":"1時間前","updated_at_in_words":"10分前","tags":[{"name":"Boo","url_name":"boo","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/674c0383e9e2a6c2d28cabd1c5cf4ac97081a238/medium.jpg?1370243594","versions":[]},{"name":"Generic","url_name":"generic","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"Unity3D","url_name":"unity3d","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/a34e297cc90c3e48983914ae54e02c5295b09c2c/medium.jpg?1364839573","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/JunSuzukiJapan@github/items/41a855f8a372a88672f8","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376462341,"raw_body":"# ジェネリック関数\n\n## Booでジェネリック関数の宣言と、C#(など)で書かれたジェネリック関数の呼び出し\n\n```boo:\ndef aMethod[of T](anObject):\n    CSharpClass.callMethod[of T](anObject)\n```\n\nC#だと[T]とするところを、[of T]のように'of'をつけるらしい。\n\n# 可変長引数\n\n```boo:\ndef foo(format as string, *args):\n    System.String.Format(format, *args)\n```\n\n可変長引数を受け取る場合、引数名の前に'*'をつける。\nまた、受け取った引数をC#などで書かれた可変長引数を受け取る関数に、引数の値をそのまま渡す場合にも、'*'をつける。","body":"\u003Ch1\u003E\n        \u003Cspan id=\"1-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eジェネリック関数\n      \u003C/h1\u003E\u003Ch2\u003E\n        \u003Cspan id=\"2-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003EBooでジェネリック関数の宣言と、C#(など)で書かれたジェネリック関数の呼び出し\n      \u003C/h2\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"k\"\u003Edef\u003C/span\u003E \u003Cspan class=\"nf\"\u003EaMethod\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"k\"\u003Eof\u003C/span\u003E \u003Cspan class=\"n\"\u003ET\u003C/span\u003E\u003Cspan class=\"p\"\u003E](\u003C/span\u003E\u003Cspan class=\"n\"\u003EanObject\u003C/span\u003E\u003Cspan class=\"p\"\u003E):\u003C/span\u003E\n    \u003Cspan class=\"n\"\u003ECSharpClass\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003EcallMethod\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"k\"\u003Eof\u003C/span\u003E \u003Cspan class=\"n\"\u003ET\u003C/span\u003E\u003Cspan class=\"p\"\u003E](\u003C/span\u003E\u003Cspan class=\"n\"\u003EanObject\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003EC#だと[T]とするところを、[of T]のように\u0026#39;of\u0026#39;をつけるらしい。\u003C/p\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E可変長引数\n      \u003C/h1\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"k\"\u003Edef\u003C/span\u003E \u003Cspan class=\"nf\"\u003Efoo\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Eformat\u003C/span\u003E \u003Cspan class=\"k\"\u003Eas\u003C/span\u003E \u003Cspan class=\"n\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"o\"\u003E*\u003C/span\u003E\u003Cspan class=\"n\"\u003Eargs\u003C/span\u003E\u003Cspan class=\"p\"\u003E):\u003C/span\u003E\n    \u003Cspan class=\"n\"\u003ESystem\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003EString\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003EFormat\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Eformat\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"o\"\u003E*\u003C/span\u003E\u003Cspan class=\"n\"\u003Eargs\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E可変長引数を受け取る場合、引数名の前に\u0026#39;*\u0026#39;をつける。\u003Cbr\u003E\nまた、受け取った引数をC#などで書かれた可変長引数を受け取る関数に、引数の値をそのまま渡す場合にも、\u0026#39;*\u0026#39;をつける。\u003C/p\u003E\n"},{"id":24637,"uuid":"00db00e33dfd11c837fe","user":{"id":5548,"url_name":"YusukeHirao","profile_image_url":"https://si0.twimg.com/profile_images/1759213043/avatar_normal.jpg"},"title":"TypeScriptでEventDispatcherを作る","created_at":"2013-08-14 15:23:23 +0900","updated_at":"2013-08-14 15:25:27 +0900","created_at_in_words":"1時間前","updated_at_in_words":"1時間前","tags":[{"name":"JavaScript","url_name":"javascript","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/c01023cf926d47b711747c9d00b00fd18dc6638a/medium.jpg?1364837881","versions":[]},{"name":"TypeScript","url_name":"typescript","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/0dbb7f08d4ebb12cfbe9335be5bf4ce9f3d16a41/medium.jpg?1364840802","versions":["0.9.1"]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/YusukeHirao/items/00db00e33dfd11c837fe","gist_url":"https://gist.github.com/6228482","tweet":true,"private":false,"created_at_as_seconds":1376461403,"raw_body":"TypeScriptの勉強がてらよく使うクラスを実装してみた。\n\n```ts:\ninterface ICustomEvent {\n\ttype:string;\n\tdata:Object;\n\ttimeStamp:number;\n\tdefaultPrevented:boolean;\n}\n\nclass CustomEvent implements ICustomEvent {\n\tdata:Object;\n\ttimeStamp:number;\n\tdefaultPrevented:boolean = false;\n\tconstructor (public type:string) {\n\t\tthis.timeStamp = new Date().valueOf();\n\t}\n\tpreventDefault () {\n\t\tthis.defaultPrevented = true;\n\t}\n}\n\ninterface IEventListenerList {\n\t[index:string]:(e:Event) =\u003E any;\n}\n\ninterface IEventDispatcher {\n\ton(type:string, listener:(e:Event) =\u003E any):void;\n\toff(type:string, listener:Function):void;\n\ttrigger(type:string, data:Object):boolean;\n}\n\nclass EventDispacther implements IEventDispatcher {\n\tprivate _listeners:IEventListenerList = {};\n\ton (types:string, listener:(e:Event) =\u003E any):void {\n\t\tvar typeList:string[] = types.split(/\\s+/);\n\t\tvar i:number = 0;\n\t\tvar l:number = typeList.length;\n\t\tfor (; i \u003C l; i++) {\n\t\t\tthis._listeners[typeList[i]] = listener;\n\t\t}\n\t}\n\toff(types:string, listener?:Function):void {\n\t\tvar typeList:string[] = types.split(/\\s+/);\n\t\tvar i:number = 0;\n\t\tvar l:number = typeList.length;\n\t\tvar type:string;\n\t\tfor (; i \u003C l; i++) {\n\t\t\ttype = typeList[i];\n\t\t\tif (listener == null || this._listeners[type] === listener) {\n\t\t\t\tdelete this._listeners[type];\n\t\t\t}\n\t\t}\n\t}\n\ttrigger(type:string, data:Object = {}, context:any = this):boolean {\n\t\tvar listener:Function;\n\t\tif (listener = this._listeners[type]) {\n\t\t\tvar e:CustomEvent = new CustomEvent(type);\n\t\t\te.data = data;\n\t\t\tlistener.call(context, e);\n\t\t\treturn !e.defaultPrevented;\n\t\t}\n\t\treturn true;\n\t}\n}\n\n```\n\nJavaや(本格的な)ActionScript3未経験な僕とってinterfaceの実装というか概念がこれであってるのかあやふや。\n\n`listener`の第一引数を`Event`型にしてるのに、実際渡すものは`CustomEvent`型でもコンパイル通るあたり、これでいいのかよくわっていない。\n\n\n* * *\n\n`IEventListenerList `というinterfaceを作って、シグニチャの代わりみたいに扱っているけど、これもこれで使い方があってるのか疑問…。\n\n* * *\n\nまだまだよくわっておりません!\n","body":"\u003Cp\u003ETypeScriptの勉強がてらよく使うクラスを実装してみた。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"kr\"\u003Einterface\u003C/span\u003E \u003Cspan class=\"nx\"\u003EICustomEvent\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Edata\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EObject\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003EtimeStamp\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Enumber\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003EdefaultPrevented\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Eboolean\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n\u003Cspan class=\"kr\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nx\"\u003ECustomEvent\u003C/span\u003E \u003Cspan class=\"kr\"\u003Eimplements\u003C/span\u003E \u003Cspan class=\"nx\"\u003EICustomEvent\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Edata\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EObject\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003EtimeStamp\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Enumber\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003EdefaultPrevented\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Eboolean\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kc\"\u003Efalse\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"kr\"\u003Econstructor\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"kr\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003EtimeStamp\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Enew\u003C/span\u003E \u003Cspan class=\"nb\"\u003EDate\u003C/span\u003E\u003Cspan class=\"p\"\u003E().\u003C/span\u003E\u003Cspan class=\"nx\"\u003EvalueOf\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003EpreventDefault\u003C/span\u003E \u003Cspan class=\"p\"\u003E()\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003EdefaultPrevented\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kc\"\u003Etrue\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n\u003Cspan class=\"kr\"\u003Einterface\u003C/span\u003E \u003Cspan class=\"nx\"\u003EIEventListenerList\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E]\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EEvent\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eany\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n\u003Cspan class=\"kr\"\u003Einterface\u003C/span\u003E \u003Cspan class=\"nx\"\u003EIEventDispatcher\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eon\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EEvent\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eany\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"k\"\u003Evoid\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eoff\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EFunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"k\"\u003Evoid\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Etrigger\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Edata\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EObject\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"kr\"\u003Eboolean\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n\u003Cspan class=\"kr\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nx\"\u003EEventDispacther\u003C/span\u003E \u003Cspan class=\"kr\"\u003Eimplements\u003C/span\u003E \u003Cspan class=\"nx\"\u003EIEventDispatcher\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"kr\"\u003Eprivate\u003C/span\u003E \u003Cspan class=\"nx\"\u003E_listeners\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EIEventListenerList\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"p\"\u003E{};\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eon\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etypes\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EEvent\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eany\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"k\"\u003Evoid\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003EtypeList\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E[]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etypes\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Esplit\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"sr\"\u003E/\\s+/\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Enumber\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"mi\"\u003E0\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003El\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Enumber\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003EtypeList\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Elength\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Efor\u003C/span\u003E \u003Cspan class=\"p\"\u003E(;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E \u003Cspan class=\"o\"\u003E\u0026lt;\u003C/span\u003E \u003Cspan class=\"nx\"\u003El\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E\u003Cspan class=\"o\"\u003E++\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003E_listeners\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003EtypeList\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E\u003Cspan class=\"p\"\u003E]]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eoff\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etypes\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener?\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EFunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"k\"\u003Evoid\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003EtypeList\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E[]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etypes\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Esplit\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"sr\"\u003E/\\s+/\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Enumber\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"mi\"\u003E0\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003El\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Enumber\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003EtypeList\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Elength\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Efor\u003C/span\u003E \u003Cspan class=\"p\"\u003E(;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E \u003Cspan class=\"o\"\u003E\u0026lt;\u003C/span\u003E \u003Cspan class=\"nx\"\u003El\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E\u003Cspan class=\"o\"\u003E++\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003EtypeList\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ei\u003C/span\u003E\u003Cspan class=\"p\"\u003E];\u003C/span\u003E\n            \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E \u003Cspan class=\"o\"\u003E==\u003C/span\u003E \u003Cspan class=\"kc\"\u003Enull\u003C/span\u003E \u003Cspan class=\"o\"\u003E||\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003E_listeners\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E\u003Cspan class=\"p\"\u003E]\u003C/span\u003E \u003Cspan class=\"o\"\u003E===\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n                \u003Cspan class=\"k\"\u003Edelete\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003E_listeners\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E\u003Cspan class=\"p\"\u003E];\u003C/span\u003E\n            \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Etrigger\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Estring\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Edata\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EObject\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"p\"\u003E{},\u003C/span\u003E \u003Cspan class=\"nx\"\u003Econtext\u003C/span\u003E:\u003Cspan class=\"kt\"\u003Eany\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"kr\"\u003Eboolean\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E:\u003Cspan class=\"kt\"\u003EFunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethis\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003E_listeners\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E\u003Cspan class=\"p\"\u003E])\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E:\u003Cspan class=\"kt\"\u003ECustomEvent\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Enew\u003C/span\u003E \u003Cspan class=\"nx\"\u003ECustomEvent\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etype\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n            \u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Edata\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Edata\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n            \u003Cspan class=\"nx\"\u003Elistener\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ecall\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Econtext\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n            \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"o\"\u003E!\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ee\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003EdefaultPrevented\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"kc\"\u003Etrue\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003EJavaや(本格的な)ActionScript3未経験な僕とってinterfaceの実装というか概念がこれであってるのかあやふや。\u003C/p\u003E\n\u003Cp\u003E\u003Ccode\u003Elistener\u003C/code\u003Eの第一引数を\u003Ccode\u003EEvent\u003C/code\u003E型にしてるのに、実際渡すものは\u003Ccode\u003ECustomEvent\u003C/code\u003E型でもコンパイル通るあたり、これでいいのかよくわっていない。\u003C/p\u003E\n\n\u003Chr\u003E\n\u003Cp\u003E\u003Ccode\u003EIEventListenerList\u003C/code\u003Eというinterfaceを作って、シグニチャの代わりみたいに扱っているけど、これもこれで使い方があってるのか疑問…。\u003C/p\u003E\n\n\u003Chr\u003E\n\u003Cp\u003Eまだまだよくわっておりません!\u003C/p\u003E\n"},{"id":24636,"uuid":"5a4f0189ee94dadf04b7","user":{"id":26292,"url_name":"asahina_dev","profile_image_url":"https://twimg0-a.akamaihd.net/profile_images/3529128397/8b7dea7857ac7197101c18c1d0477678_normal.jpeg"},"title":"Java7でdjunit 実行時にエラーになる場合の対策","created_at":"2013-08-14 14:27:37 +0900","updated_at":"2013-08-14 14:27:37 +0900","created_at_in_words":"2時間前","updated_at_in_words":"2時間前","tags":[{"name":"Java","url_name":"java","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/c33860c6f27d6856ea351942d1edc7a6c5adc1d5/medium.jpg?1364837601","versions":["7"]},{"name":"djunit","url_name":"djunit","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/asahina_dev/items/5a4f0189ee94dadf04b7","gist_url":null,"tweet":true,"private":false,"created_at_as_seconds":1376458057,"raw_body":"```bash:~/bashrc\n  export JAVA_OPTS=\"-XX:-UseSplitVerifier $JAVA_OPTS\"\n```\nを追加","body":"\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003E~/bashrc\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E  \u003Cspan class=\"nb\"\u003Eexport \u003C/span\u003E\u003Cspan class=\"nv\"\u003EJAVA_OPTS\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;-XX:-UseSplitVerifier $JAVA_OPTS\u0026quot;\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eを追加\u003C/p\u003E\n"},{"id":24635,"uuid":"fec24b20f9271c4db185","user":{"id":25676,"url_name":"dumpty-alma@github","profile_image_url":"https://secure.gravatar.com/avatar/45f2d7880a9dae1e5edce06214125db9?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"KVMで仮想マシンをクローンする。","created_at":"2013-08-14 14:18:06 +0900","updated_at":"2013-08-14 14:18:06 +0900","created_at_in_words":"2時間前","updated_at_in_words":"2時間前","tags":[{"name":"KVM","url_name":"kvm","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/dumpty-alma@github/items/fec24b20f9271c4db185","gist_url":"https://gist.github.com/6228211","tweet":true,"private":false,"created_at_as_seconds":1376457486,"raw_body":"\n##KVMで稼動している仮想マシンのクローンをやる。\n\n- ホストOSは Ubuntu 12.04.1 LTS precise x86_64\n- Linux minerva 3.2.0-29-generic #46-Ubuntu SMP Fri Jul 27 17:03:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux\n- クローン対象OSは CentOS release 6.4 (Final) \n- Linux yui.altworks.local 2.6.32-358.14.1.el6.x86_64 #1 SMP Tue Jul 16 23:51:20 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux\n- ひとまずクローンして、OS起動後ifcfg修正したり、hosts修正したりする流れ\n\n######①クローン元となる仮想マシンを停止する。\n\n```bash:\nroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 10 CentOS_6.3_x86_64    running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n\nroot@minerva:~# \n```\n\nクローン元は「10 CentOS_6.3_x86_64」とするので、これを停止する。\n仮想マシンのコンソールに切り替えるには以下のようにする。\n\n```bash:\nvirsh console CentOS_6.3_x86_64\n```\n\nコンソールから復帰するには「Ctrl」+「]」で戻れる。\n\n```bash:\nroot@minerva:~# virsh console CentOS_6.3_x86_64\nConnected to domain CentOS_6.3_x86_64\nEscape character is ^]\n\nCentOS release 6.4 (Final)\nKernel 2.6.32-358.14.1.el6.x86_64 on an x86_64\n\nyui.altworks.local login: root\n                              Password: \n                                        Last login: Wed Aug 14 13:31:00 from 192.168.XX.XX\n                                                                                          [root@yui ~]# shutdown -h now\n                                                                                                                       \nBroadcast message from root@yui.altworks.local\n        (/dev/ttyS0) at 13:35 ...\n\nThe system is going down for halt NOW!\n[root@yui ~]# Stopping sshd: [  OK  ]\nShutting down postfix: [  OK  ]\nStopping crond: [  OK  ]\nStopping block device availability: Deactivating block devices:\n  [SKIP]: unmount of VolGroup-lv_swap (dm-1) mounted on [SWAP]\n  [SKIP]: unmount of VolGroup-lv_root (dm-0) mounted on /\n[  OK  ]\nStopping auditd: type=1305 audit(1376454936.522:1929): audit_pid=0 old=1021 auid=4294967295 ses=4294967295 subj=system_u:system_r:auditd_t:s0 res=1\n\nroot@minerva:~# \n```\n\nコンソール切替後、表示が変な風になっているのはご愛嬌です。\n※ssh経由だとどうしてもこうなっちゃう。直接ホストを操作するとそういう風にはならないけど。\n\n```bash:\nroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n  - CentOS_6.3_x86_64    shut off\n\nroot@minerva:~# \n```\n\nあ、「shutdown」じゃなくて「shut off」だった。\n\n######②クローンを行う。\n\n仮想マシンのイメージファイルみたいなのを格納する場所を作る。\n私は以下のような場所にまとめて置いているので、連番で新規ディレクトリを作った。\n\n```bash:\nroot@minerva:~# ls -al /vm/  \ntotal 36\ndrwxr-xr-x  9 root root 4096 Aug  2 11:53 .\ndrwxr-xr-x 25 root root 4096 Jan  9  2013 ..\ndrwxr-xr-x  2 root root 4096 Dec 21  2012 vmMachine001\ndrwxr-xr-x  2 root root 4096 Dec 28  2012 vmMachine002\ndrwxr-xr-x  2 root root 4096 Jan 17  2013 vmMachine003\ndrwxr-xr-x  2 root root 4096 Jan 17  2013 vmMachine004\ndrwxr-xr-x  2 root root 4096 Jan 17  2013 vmMachine005\ndrwxr-xr-x  2 root root 4096 Aug  2 11:46 vmMachine006\ndrwxr-xr-x  2 root root 4096 Aug  2 11:53 vmMachine007\nroot@minerva:~# \nroot@minerva:~# mkdir /vm/vmMachine008\nroot@minerva:~# \n```\n\n次に、クローンのコマンドを実行する。\n\n```bash:\nvirt-clone -o CentOS_6.3_x86_64 -n CentOS_6.3_x86_64-clone2 -f /vm/vmMachine007/CentOS_6.3_x86_64-clone2.img\nvirt-clone -o [クローン対象仮想マシンのName] -n [クローンした仮想マシンのName] -f [クローンした仮想マシンのイメージファイルPATH]\n```\n\n上記は以前のhistoryから。\nなので、今回はこうなる。\n\n```bash:\nvirt-clone -o CentOS_6.3_x86_64 -n CentOS_6.3_x86_64-clone3 -f /vm/vmMachine008/CentOS_6.3_x86_64-clone3.img\n```\n\n実行し、完了すると以下のようになる。\n\n```bash:\nroot@minerva:~# virt-clone -o CentOS_6.3_x86_64 -n CentOS_6.3_x86_64-clone3 -f /vm/vmMachine008/CentOS_6.3_x86_64-clone3.img\nCloning vmDisk.img                                                                                             |  20 GB     00:38     \n\nClone 'CentOS_6.3_x86_64-clone3' created successfully.\nroot@minerva:~# \n```\n\n######③あとはクローン作成した仮想マシンを起動して、必要な設定を修正する。\n\n```bash:\nvirsh start CentOS_6.3_x86_64-clone3\n```\n\n- 大体NICのMACが変更されているので、eth0が無効になり、eth1が認識されている。\n- 利用しないeth0はonboot=\"no\"等して無効化しておく。\n- system-config-network-tuiが利用出来るならば、それでIPやらDNS、gatewayを変更する。\n- system-config-network-tuiが無い人は予め「yum install system-config-network-tui」しておくといいかも。\n- SSH経由だとtuiの動作がおかしい場合があるので、ファイルを直接いじれる方がなおさらいいかも?というか、なんでSSH経由だと(ry\n- /etc/sysconfig/network hostnameとgw設定\n- /etc/sysconfig/network-scripts/ifcfg-eth* ifcfg設定\n- /etc/hosts ※私のhostsはlocalhost記述のみで特に修正無し\n\n出来た、出来た。\n\n```bash:\nroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n  - CentOS_6.3_x86_64    shut off\n  - CentOS_6.3_x86_64-clone3 shut off\n\nroot@minerva:~# virsh start CentOS_6.3_x86_64\nDomain CentOS_6.3_x86_64 started\n\nroot@minerva:~# virsh start CentOS_6.3_x86_64-clone3\nDomain CentOS_6.3_x86_64-clone3 started\n\nroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n 15 CentOS_6.3_x86_64    running\n 16 CentOS_6.3_x86_64-clone3 running\n\nroot@minerva:~# \n```\n\nvCPUは基本1OSに1cpuで1core、メモリはUbuntu系が256MBでCentOS系が512MB割り当てです。\nnodecpustats、nodememstats、nodeinfoはこんな感じになっています。\n\n```bash:\nroot@minerva:~# virsh nodecpustats\nuser:                231646870000000\nsystem:               40006610000000\nidle:              63670555720000000\niowait:               15635270000000\n\nroot@minerva:~# virsh nodememstats\ntotal  :              8125016 kB\nfree   :               126072 kB\nbuffers:               141448 kB\ncached :              5974096 kB\n\nroot@minerva:~# virsh nodeinfo\nCPU model:           x86_64\nCPU(s):              4\nCPU frequency:       800 MHz\nCPU socket(s):       1\nCore(s) per socket:  2\nThread(s) per core:  2\nNUMA cell(s):        1\nMemory size:         8125016 kB\n\nroot@minerva:~# \n```\n\n用途としては。\n\n-  2 Ubuntu_precise_12.04 running 個人wikiのWebサーバ\n-  5 Ubuntu_quantal_12.10 running Twitter連携やFacebookの連携サーバ(TwitterBOTもここで動作してる)\n- 11 CentOS_6.3_x86_64-clone2 running Git個人リポジトリ+gitwebとか\n- 12 CentOS_6.3_x86_64-clone1 running Apacheでvhostしてたり、webproxyしてたりするサーバ\n- 15 CentOS_6.3_x86_64    running ※特に利用用途無し\n- 16 CentOS_6.3_x86_64-clone3 running FTP用途\n\nそんなにCPU常時利用していないので、割と快適です。\n\n","body":"\u003Ch2\u003E\n        \u003Cspan id=\"2-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003EKVMで稼動している仮想マシンのクローンをやる。\n      \u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003EホストOSは Ubuntu 12.04.1 LTS precise x86_64\u003C/li\u003E\n\u003Cli\u003ELinux minerva 3.2.0-29-generic #46-Ubuntu SMP Fri Jul 27 17:03:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux\u003C/li\u003E\n\u003Cli\u003Eクローン対象OSは CentOS release 6.4 (Final) \u003C/li\u003E\n\u003Cli\u003ELinux yui.altworks.local 2.6.32-358.14.1.el6.x86_64 #1 SMP Tue Jul 16 23:51:20 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux\u003C/li\u003E\n\u003Cli\u003Eひとまずクローンして、OS起動後ifcfg修正したり、hosts修正したりする流れ\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch6\u003E\n        \u003Cspan id=\"6-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E①クローン元となる仮想マシンを停止する。\n      \u003C/h6\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 10 CentOS_6.3_x86_64    running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eクローン元は「10 CentOS_6.3_x86_64」とするので、これを停止する。\u003Cbr\u003E\n仮想マシンのコンソールに切り替えるには以下のようにする。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirsh console CentOS_6.3_x86_64\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eコンソールから復帰するには「Ctrl」+「]」で戻れる。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh console CentOS_6.3_x86_64\nConnected to domain CentOS_6.3_x86_64\nEscape character is ^\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n\nCentOS release 6.4 \u003Cspan class=\"o\"\u003E(\u003C/span\u003EFinal\u003Cspan class=\"o\"\u003E)\u003C/span\u003E\nKernel 2.6.32-358.14.1.el6.x86_64 on an x86_64\n\nyui.altworks.local login: root\n                              Password: \n                                        Last login: Wed Aug 14 13:31:00 from 192.168.XX.XX\n                                                                                          \u003Cspan class=\"o\"\u003E[\u003C/span\u003Eroot@yui ~\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\u003Cspan class=\"c\"\u003E# shutdown -h now\u003C/span\u003E\n\nBroadcast message from root@yui.altworks.local\n        \u003Cspan class=\"o\"\u003E(\u003C/span\u003E/dev/ttyS0\u003Cspan class=\"o\"\u003E)\u003C/span\u003E at 13:35 ...\n\nThe system is going down \u003Cspan class=\"k\"\u003Efor \u003C/span\u003Ehalt NOW!\n\u003Cspan class=\"o\"\u003E[\u003C/span\u003Eroot@yui ~\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\u003Cspan class=\"c\"\u003E# Stopping sshd: [  OK  ]\u003C/span\u003E\nShutting down postfix: \u003Cspan class=\"o\"\u003E[\u003C/span\u003E  OK  \u003Cspan class=\"o\"\u003E]\u003C/span\u003E\nStopping crond: \u003Cspan class=\"o\"\u003E[\u003C/span\u003E  OK  \u003Cspan class=\"o\"\u003E]\u003C/span\u003E\nStopping block device availability: Deactivating block devices:\n  \u003Cspan class=\"o\"\u003E[\u003C/span\u003ESKIP\u003Cspan class=\"o\"\u003E]\u003C/span\u003E: unmount of VolGroup-lv_swap \u003Cspan class=\"o\"\u003E(\u003C/span\u003Edm-1\u003Cspan class=\"o\"\u003E)\u003C/span\u003E mounted on \u003Cspan class=\"o\"\u003E[\u003C/span\u003ESWAP\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n  \u003Cspan class=\"o\"\u003E[\u003C/span\u003ESKIP\u003Cspan class=\"o\"\u003E]\u003C/span\u003E: unmount of VolGroup-lv_root \u003Cspan class=\"o\"\u003E(\u003C/span\u003Edm-0\u003Cspan class=\"o\"\u003E)\u003C/span\u003E mounted on /\n\u003Cspan class=\"o\"\u003E[\u003C/span\u003E  OK  \u003Cspan class=\"o\"\u003E]\u003C/span\u003E\nStopping auditd: \u003Cspan class=\"nb\"\u003Etype\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E1305 audit\u003Cspan class=\"o\"\u003E(\u003C/span\u003E1376454936.522:1929\u003Cspan class=\"o\"\u003E)\u003C/span\u003E: \u003Cspan class=\"nv\"\u003Eaudit_pid\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E0 \u003Cspan class=\"nv\"\u003Eold\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E1021 \u003Cspan class=\"nv\"\u003Eauid\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E4294967295 \u003Cspan class=\"nv\"\u003Eses\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E4294967295 \u003Cspan class=\"nv\"\u003Esubj\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003Esystem_u:system_r:auditd_t:s0 \u003Cspan class=\"nv\"\u003Eres\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E1\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eコンソール切替後、表示が変な風になっているのはご愛嬌です。\u003Cbr\u003E\n※ssh経由だとどうしてもこうなっちゃう。直接ホストを操作するとそういう風にはならないけど。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n  - CentOS_6.3_x86_64    shut off\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eあ、「shutdown」じゃなくて「shut off」だった。\u003C/p\u003E\n\u003Ch6\u003E\n        \u003Cspan id=\"6-5\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-5\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E②クローンを行う。\n      \u003C/h6\u003E\u003Cp\u003E仮想マシンのイメージファイルみたいなのを格納する場所を作る。\u003Cbr\u003E\n私は以下のような場所にまとめて置いているので、連番で新規ディレクトリを作った。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# ls -al /vm/  \ntotal 36\ndrwxr-xr-x  9 root root 4096 Aug  2 11:53 .\ndrwxr-xr-x 25 root root 4096 Jan  9  2013 ..\ndrwxr-xr-x  2 root root 4096 Dec 21  2012 vmMachine001\ndrwxr-xr-x  2 root root 4096 Dec 28  2012 vmMachine002\ndrwxr-xr-x  2 root root 4096 Jan 17  2013 vmMachine003\ndrwxr-xr-x  2 root root 4096 Jan 17  2013 vmMachine004\ndrwxr-xr-x  2 root root 4096 Jan 17  2013 vmMachine005\ndrwxr-xr-x  2 root root 4096 Aug  2 11:46 vmMachine006\ndrwxr-xr-x  2 root root 4096 Aug  2 11:53 vmMachine007\nroot@minerva:~# \nroot@minerva:~# mkdir /vm/vmMachine008\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E次に、クローンのコマンドを実行する。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirt-clone -o CentOS_6.3_x86_64 -n CentOS_6.3_x86_64-clone2 -f /vm/vmMachine007/CentOS_6.3_x86_64-clone2.img\nvirt-clone -o \u003Cspan class=\"o\"\u003E[\u003C/span\u003Eクローン対象仮想マシンのName\u003Cspan class=\"o\"\u003E]\u003C/span\u003E -n \u003Cspan class=\"o\"\u003E[\u003C/span\u003Eクローンした仮想マシンのName\u003Cspan class=\"o\"\u003E]\u003C/span\u003E -f \u003Cspan class=\"o\"\u003E[\u003C/span\u003Eクローンした仮想マシンのイメージファイルPATH\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E上記は以前のhistoryから。\u003Cbr\u003E\nなので、今回はこうなる。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirt-clone -o CentOS_6.3_x86_64 -n CentOS_6.3_x86_64-clone3 -f /vm/vmMachine008/CentOS_6.3_x86_64-clone3.img\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E実行し、完了すると以下のようになる。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virt-clone -o CentOS_6.3_x86_64 -n CentOS_6.3_x86_64-clone3 -f /vm/vmMachine008/CentOS_6.3_x86_64-clone3.img\nCloning vmDisk.img                                                                                             |  20 GB     00:38     \n\nClone \u003Cspan class=\"s1\"\u003E\u0026#39;CentOS_6.3_x86_64-clone3\u0026#39;\u003C/span\u003E created successfully.\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch6\u003E\n        \u003Cspan id=\"6-6\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-6\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E③あとはクローン作成した仮想マシンを起動して、必要な設定を修正する。\n      \u003C/h6\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirsh start CentOS_6.3_x86_64-clone3\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\n\u003Cul\u003E\n\u003Cli\u003E大体NICのMACが変更されているので、eth0が無効になり、eth1が認識されている。\u003C/li\u003E\n\u003Cli\u003E利用しないeth0はonboot=\u0026quot;no\u0026quot;等して無効化しておく。\u003C/li\u003E\n\u003Cli\u003Esystem-config-network-tuiが利用出来るならば、それでIPやらDNS、gatewayを変更する。\u003C/li\u003E\n\u003Cli\u003Esystem-config-network-tuiが無い人は予め「yum install system-config-network-tui」しておくといいかも。\u003C/li\u003E\n\u003Cli\u003ESSH経由だとtuiの動作がおかしい場合があるので、ファイルを直接いじれる方がなおさらいいかも?というか、なんでSSH経由だと(ry\u003C/li\u003E\n\u003Cli\u003E/etc/sysconfig/network hostnameとgw設定\u003C/li\u003E\n\u003Cli\u003E/etc/sysconfig/network-scripts/ifcfg-eth* ifcfg設定\u003C/li\u003E\n\u003Cli\u003E/etc/hosts ※私のhostsはlocalhost記述のみで特に修正無し\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003E出来た、出来た。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n  - CentOS_6.3_x86_64    shut off\n  - CentOS_6.3_x86_64-clone3 shut off\n\nroot@minerva:~# virsh start CentOS_6.3_x86_64\nDomain CentOS_6.3_x86_64 started\n\nroot@minerva:~# virsh start CentOS_6.3_x86_64-clone3\nDomain CentOS_6.3_x86_64-clone3 started\n\nroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n 15 CentOS_6.3_x86_64    running\n 16 CentOS_6.3_x86_64-clone3 running\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003EvCPUは基本1OSに1cpuで1core、メモリはUbuntu系が256MBでCentOS系が512MB割り当てです。\u003Cbr\u003E\nnodecpustats、nodememstats、nodeinfoはこんな感じになっています。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh nodecpustats\nuser:                231646870000000\nsystem:               40006610000000\nidle:              63670555720000000\niowait:               15635270000000\n\nroot@minerva:~# virsh nodememstats\ntotal  :              8125016 kB\nfree   :               126072 kB\nbuffers:               141448 kB\ncached :              5974096 kB\n\nroot@minerva:~# virsh nodeinfo\nCPU model:           x86_64\nCPU\u003Cspan class=\"o\"\u003E(\u003C/span\u003Es\u003Cspan class=\"o\"\u003E)\u003C/span\u003E:              4\nCPU frequency:       800 MHz\nCPU socket\u003Cspan class=\"o\"\u003E(\u003C/span\u003Es\u003Cspan class=\"o\"\u003E)\u003C/span\u003E:       1\nCore\u003Cspan class=\"o\"\u003E(\u003C/span\u003Es\u003Cspan class=\"o\"\u003E)\u003C/span\u003E per socket:  2\nThread\u003Cspan class=\"o\"\u003E(\u003C/span\u003Es\u003Cspan class=\"o\"\u003E)\u003C/span\u003E per core:  2\nNUMA cell\u003Cspan class=\"o\"\u003E(\u003C/span\u003Es\u003Cspan class=\"o\"\u003E)\u003C/span\u003E:        1\nMemory size:         8125016 kB\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E用途としては。\u003C/p\u003E\n\n\u003Cul\u003E\n\u003Cli\u003E 2 Ubuntu_precise_12.04 running 個人wikiのWebサーバ\u003C/li\u003E\n\u003Cli\u003E 5 Ubuntu_quantal_12.10 running Twitter連携やFacebookの連携サーバ(TwitterBOTもここで動作してる)\u003C/li\u003E\n\u003Cli\u003E11 CentOS_6.3_x86_64-clone2 running Git個人リポジトリ+gitwebとか\u003C/li\u003E\n\u003Cli\u003E12 CentOS_6.3_x86_64-clone1 running Apacheでvhostしてたり、webproxyしてたりするサーバ\u003C/li\u003E\n\u003Cli\u003E15 CentOS_6.3_x86_64    running ※特に利用用途無し\u003C/li\u003E\n\u003Cli\u003E16 CentOS_6.3_x86_64-clone3 running FTP用途\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003EそんなにCPU常時利用していないので、割と快適です。\u003C/p\u003E\n"},{"id":24634,"uuid":"1367cc0412b4b31ae29c","user":{"id":11525,"url_name":"tanakahisateru","profile_image_url":"https://secure.gravatar.com/avatar/8c1ecc738eee0254a41c2d4b33cda7b6?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"PhpStormのInspection警告を制御する","created_at":"2013-08-14 14:16:14 +0900","updated_at":"2013-08-14 14:18:18 +0900","created_at_in_words":"2時間前","updated_at_in_words":"2時間前","tags":[{"name":"PhpStorm","url_name":"phpstorm","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/caa8e62ff8cac140ccc93e8a2bade616f7d201ea/medium.jpg?1364839492","versions":[]},{"name":"PHP","url_name":"php","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/aae632f19de784bc000b317b06ed2320f2582469/medium.jpg?1364837706","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/tanakahisateru/items/1367cc0412b4b31ae29c","gist_url":null,"tweet":true,"private":false,"created_at_as_seconds":1376457374,"raw_body":"PhpStormのInspectionは、型がなかったりスクリプトだったりするPHPなのに、いろいろ厳しくバグの可能性を見てくれてありがたいのですが、ちょっと変わったトリックを使うとすぐに警告まみれになってしまいます。一気にチェックしたとき、いちいち警告の中を見て「これは大丈夫なコードだったはず」と除外してレポートを読むのが面倒です。\n\nたとえば、クラスローダやビューなどで、include/require のパスに変数を使うなどすると、Inspection で Unresolved include が出てしまいます。これは include するファイルがないかもしれないという警告です。平易なPHPスクリプトを書いているときはありがたいのですが、フレームワークレベルの開発では邪魔になります。チェックしないようオフにしてしまうのはもったいないので、特定の箇所でだけ警告が出ないようにしたいです。\n\n```php:\n\u003C?php\nclass MyClassLoader\n{\n    public function load($class)\n    {\n        // ...\n\n        /** @noinspection PhpIncludeInspection */\n        require_once dirname(__FILE__) . '/' . $classFile;\n    }\n}\n```\n\nこのアノテーションを挿入すると、そこでだけ警告を出さないようになります。\n\n例の豆電球から `Inspection 'Unresolved include' options` \u003E `Suppress for statement` でも挿入できます。\n\nまた、メソッド内で includeを呼び、その外部ファイルで使うためのローカル変数を設けるなどした場合、本当は必要なのに、使われていない変数があるという意味の、Unused local valiable 警告が出ます。\n\n```php:\n\u003C?php\nclass MyPageRenderer\n{\n    public function render($view)\n    {\n        // ...\n\n        /** @noinspection PhpUnusedLocalVariableInspection */\n        $helper = new MyViewHelper($this); // 下のrequireで使われる変数\n\n        /** @noinspection PhpIncludeInspection */\n        require dirname(__FILE__) . '/' . $viewFile;\n    }\n}\n```\n\nこれも例の豆電球から `Inspection 'Unresolved local valiable' options` \u003E `Suppress for statement` で挿入できます。\n\n便利なのはだいたいこのあたりでしょうか。\n\nほか、`@noinspection` には PhpUnusedParameterInspection という、パラメータ未使用の場合に使うものもありました。`func_get_args()` を使った可変長引数をやっている場合などに有効かもしれません。ただ、メソッド宣言のカッコの中に書かないといけないので、これは逆にちょっとうるさいかもしれませんね。\n\n他にも、こんなのもあるみたいなので、意図しない警告が出たら試してみてください。\n\n- PhpUndefinedFunctionInspection\n- PhpUndefinedConstantInspection","body":"\u003Cp\u003EPhpStormのInspectionは、型がなかったりスクリプトだったりするPHPなのに、いろいろ厳しくバグの可能性を見てくれてありがたいのですが、ちょっと変わったトリックを使うとすぐに警告まみれになってしまいます。一気にチェックしたとき、いちいち警告の中を見て「これは大丈夫なコードだったはず」と除外してレポートを読むのが面倒です。\u003C/p\u003E\n\u003Cp\u003Eたとえば、クラスローダやビューなどで、include/require のパスに変数を使うなどすると、Inspection で Unresolved include が出てしまいます。これは include するファイルがないかもしれないという警告です。平易なPHPスクリプトを書いているときはありがたいのですが、フレームワークレベルの開発では邪魔になります。チェックしないようオフにしてしまうのはもったいないので、特定の箇所でだけ警告が出ないようにしたいです。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"cp\"\u003E\u0026lt;?php\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nc\"\u003EMyClassLoader\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003Eload\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$class\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"c1\"\u003E// ...\u003C/span\u003E\n\n        \u003Cspan class=\"sd\"\u003E/** @noinspection PhpIncludeInspection */\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Erequire_once\u003C/span\u003E \u003Cspan class=\"nb\"\u003Edirname\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"k\"\u003E__FILE__\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;/\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$classFile\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこのアノテーションを挿入すると、そこでだけ警告を出さないようになります。\u003C/p\u003E\n\u003Cp\u003E例の豆電球から \u003Ccode\u003EInspection \u0026#39;Unresolved include\u0026#39; options\u003C/code\u003E \u0026gt; \u003Ccode\u003ESuppress for statement\u003C/code\u003E でも挿入できます。\u003C/p\u003E\n\u003Cp\u003Eまた、メソッド内で includeを呼び、その外部ファイルで使うためのローカル変数を設けるなどした場合、本当は必要なのに、使われていない変数があるという意味の、Unused local valiable 警告が出ます。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"cp\"\u003E\u0026lt;?php\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nc\"\u003EMyPageRenderer\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003Erender\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$view\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"c1\"\u003E// ...\u003C/span\u003E\n\n        \u003Cspan class=\"sd\"\u003E/** @noinspection PhpUnusedLocalVariableInspection */\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$helper\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Enew\u003C/span\u003E \u003Cspan class=\"nx\"\u003EMyViewHelper\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E \u003Cspan class=\"c1\"\u003E// 下のrequireで使われる変数\u003C/span\u003E\n\n        \u003Cspan class=\"sd\"\u003E/** @noinspection PhpIncludeInspection */\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"nb\"\u003Edirname\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"k\"\u003E__FILE__\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;/\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$viewFile\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこれも例の豆電球から \u003Ccode\u003EInspection \u0026#39;Unresolved local valiable\u0026#39; options\u003C/code\u003E \u0026gt; \u003Ccode\u003ESuppress for statement\u003C/code\u003E で挿入できます。\u003C/p\u003E\n\u003Cp\u003E便利なのはだいたいこのあたりでしょうか。\u003C/p\u003E\n\u003Cp\u003Eほか、\u003Ccode\u003E@noinspection\u003C/code\u003E には PhpUnusedParameterInspection という、パラメータ未使用の場合に使うものもありました。\u003Ccode\u003Efunc_get_args()\u003C/code\u003E を使った可変長引数をやっている場合などに有効かもしれません。ただ、メソッド宣言のカッコの中に書かないといけないので、これは逆にちょっとうるさいかもしれませんね。\u003C/p\u003E\n\u003Cp\u003E他にも、こんなのもあるみたいなので、意図しない警告が出たら試してみてください。\u003C/p\u003E\n\n\u003Cul\u003E\n\u003Cli\u003EPhpUndefinedFunctionInspection\u003C/li\u003E\n\u003Cli\u003EPhpUndefinedConstantInspection\u003C/li\u003E\n\u003C/ul\u003E\n"},{"id":24633,"uuid":"9cf0da1b92a166863076","user":{"id":889,"url_name":"suin","profile_image_url":"https://secure.gravatar.com/avatar/152ead2a935d1c21b585286d7587b183?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"title":"tmuxでウィンドウを閉じた時にインデックス番号を詰めるには renumber-windows on を設定する","created_at":"2013-08-14 14:02:34 +0900","updated_at":"2013-08-14 14:02:34 +0900","created_at_in_words":"2時間前","updated_at_in_words":"2時間前","tags":[{"name":"tmux","url_name":"tmux","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/suin/items/9cf0da1b92a166863076","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376456554,"raw_body":"\n次のように3つウィンドウを開いていた時に\n\n```\n1:foo-  2:bar*  3:baz\n```\n\n2番を閉じると、次のように2番が欠番してしまう\n\n```\n1:foo*  3:baz\n```\n\nこの状態で新しいウィンドウを開くと2番にウィンドウが作られてしまう。\n\n個人的にこのふるまいが馴染めず、下記のように3番が2番に付番し直されるふるまいを期待していた\n\n```\n1:foo*  2:baz\n```\n\ntmux 1.7以上では、ウィンドウを閉じた時にインデックス番号を振り直す設定ができる、設定のしかたは、`~/.tmux.conf` に下記の1行を追加する\n\n```~/.tmux.conf\nset-option -g renumber-windows on\n```\n\n","body":"\u003Cp\u003E次のように3つウィンドウを開いていた時に\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E1:foo-  2:bar*  3:baz\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E2番を閉じると、次のように2番が欠番してしまう\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E1:foo*  3:baz\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこの状態で新しいウィンドウを開くと2番にウィンドウが作られてしまう。\u003C/p\u003E\n\u003Cp\u003E個人的にこのふるまいが馴染めず、下記のように3番が2番に付番し直されるふるまいを期待していた\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E1:foo*  2:baz\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Etmux 1.7以上では、ウィンドウを閉じた時にインデックス番号を振り直す設定ができる、設定のしかたは、\u003Ccode\u003E~/.tmux.conf\u003C/code\u003E に下記の1行を追加する\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003E~/.tmux.conf\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eset-option -g renumber-windows on\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E"},{"id":24632,"uuid":"ef46e9fe3751c19b0083","user":{"id":5222,"url_name":"akiporoyopida@github","profile_image_url":"https://secure.gravatar.com/avatar/9243e1166963f773a3fa33e90c64f1f6?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"title":"drobo-utilsをcentosで動かす","created_at":"2013-08-14 13:09:08 +0900","updated_at":"2013-08-14 13:23:39 +0900","created_at_in_words":"3時間前","updated_at_in_words":"3時間前","tags":[{"name":"CentOS","url_name":"centos","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/f4669b520a7066e0c6444835638663feeea72d81/medium.jpg?1364838885","versions":[]},{"name":"drobo","url_name":"drobo","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/akiporoyopida@github/items/ef46e9fe3751c19b0083","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376453348,"raw_body":"http://drobo-utils.sourceforge.net\nhttp://sd.pot.co.jp/2011/07/08/using-a-drobo-on-linux-j\n\nyum -y install python-ctypes\n\nが必要\n\ngit clone git://drobo-utils.git.sourceforge.net/gitroot/drobo-utils/drobo-utils\n\ngitで持ってくる\n\n./drobom status\n\nmkfs -t ext3 /dev/sdb1\n\nex4ではなくext3で。","body":"\u003Cp\u003E\u003Ca href=\"http://drobo-utils.sourceforge.net\" title=\"http://drobo-utils.sourceforge.net\" target=\"_blank\"\u003Ehttp://drobo-utils.sourceforge.net\u003C/a\u003E\u003Cbr\u003E\n\u003Ca href=\"http://sd.pot.co.jp/2011/07/08/using-a-drobo-on-linux-j\" title=\"http://sd.pot.co.jp/2011/07/08/using-a-drobo-on-linux-j\" target=\"_blank\"\u003Ehttp://sd.pot.co.jp/2011/07/08/using-a-drobo-on-linux-j\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003Eyum -y install python-ctypes\u003C/p\u003E\n\u003Cp\u003Eが必要\u003C/p\u003E\n\u003Cp\u003Egit clone git://drobo-utils.git.sourceforge.net/gitroot/drobo-utils/drobo-utils\u003C/p\u003E\n\u003Cp\u003Egitで持ってくる\u003C/p\u003E\n\u003Cp\u003E./drobom status\u003C/p\u003E\n\u003Cp\u003Emkfs -t ext3 /dev/sdb1\u003C/p\u003E\n\u003Cp\u003Eex4ではなくext3で。\u003C/p\u003E\n"},{"id":24631,"uuid":"337fa537a547fad127d7","user":{"id":19180,"url_name":"bacter1a@github","profile_image_url":"https://secure.gravatar.com/avatar/6feceb2c90e746bfbe3bfbe0d03e59dc?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"Capistrano実行時にEC2とかRDSを引っ張ってきてRole設定する","created_at":"2013-08-14 12:43:43 +0900","updated_at":"2013-08-14 13:01:58 +0900","created_at_in_words":"4時間前","updated_at_in_words":"3時間前","tags":[{"name":"Ruby","url_name":"ruby","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/9de6a11d330f5694820082438f88ccf4a1b289b2/medium.jpg?1364837630","versions":[]},{"name":"capistrano","url_name":"capistrano","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"AWS","url_name":"aws","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/3d4eee7349c660a8d27c07febb777ab7141e6ef7/medium.jpg?1364839105","versions":[]},{"name":"autoscale","url_name":"autoscale","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"RDS","url_name":"rds","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/bacter1a@github/items/337fa537a547fad127d7","gist_url":null,"tweet":true,"private":false,"created_at_as_seconds":1376451823,"raw_body":"# 想定環境\n\n* AutoScalingされたりしてるアプリケーション用EC2インスタンス tagに`app:true`と設定\n* RDSはMasterとRead Replicaが複数台\n\n# やってること\n* EC2はIPアドレスをとってきてRole設定。稼働中かつ`app:true`としたサーバがデプロイ対象になる。\n* RDSはtagに対応していないので、Masterか否かを判断してendpointでアクセス。\n\n# 必要なもの\n[AWS SDK for Ruby](http://aws.amazon.com/jp/sdkforruby/)\n\n# 環境変数\n\n```shell-session:\n$ export AWS_ACCESS_KEY_ID=\"xxxxxxxxxxxxxxxxx\"\n$ export AWS_SECRET_ACCESS_KEY=\"xxxxxxxxxxxxxx\"\n$ export EC2_URL=\"http://ec2.ap-northeast-1.amazonaws.com\"\n```\n\n# Roleの設定\n\n```rb:production.rb\nrequire 'aws-sdk'\n\nset :aws_access_key_id,     ENV['AWS_ACCESS_KEY_ID']\nset :aws_secret_access_key, ENV['AWS_SECRET_ACCESS_KEY']\n\n#EC2\nif ENV['EC2_URL']\n  ec2=AWS::EC2.new(:ec2_endpoint =\u003E ENV['EC2_URL'].sub(/^https?:\\/\\//,\"\"))\nelse\n  ec2=AWS::EC2.new\nend\ninstances = ec2.instances.select {|instance| instance.tags[:app] == 'true' \u0026\u0026 instance.status == :running}.map(\u0026:private_ip_address)\n\nrole :app,  *instances, :behind_loadbalancer =\u003E true\n\n#RDS\nif ENV['EC2_URL']\n  rds=AWS::RDS.new(:rds_endpoint =\u003E ENV['EC2_URL'].sub(/^https?:\\/\\/ec2/,\"rds\"))\nelse\n  rds=AWS::RDS.new\nend\n\nrds_master = rds.instances.select {|instance| instance.read_replica_source_db_instance_identifier == nil }.map(\u0026:endpoint_address)\nrds_slave = rds.instances.select {|instance| instance.read_replica_source_db_instance_identifier != nil   }.map(\u0026:endpoint_address)\n\nrole :db_host, *rds_master, :no_release =\u003E true, :primary =\u003E true, :name =\u003E \"default\", :rds =\u003E true\nrds_slave.each_with_index{ |slave, i| @slave_num = i + 1 \nrole :db_host, slave, :no_release =\u003E true, :name =\u003E \"slave\" + @slave_num.to_s }\n```\n\n# 参考\n\n[CapistranoでELB配下のEC2インスタンスを取得してデプロイ](http://qiita.com/STAR_ZERO/items/0131c542a8951de557fd)\n[eXcale | Blog : CapstranoでAWSのAPIを使って実行時にroleを設定する](http://blog.excale.net/index.php/archives/351)","body":"\u003Ch1\u003E\n        \u003Cspan id=\"1-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E想定環境\n      \u003C/h1\u003E\n\u003Cul\u003E\n\u003Cli\u003EAutoScalingされたりしてるアプリケーション用EC2インスタンス tagに\u003Ccode\u003Eapp:true\u003C/code\u003Eと設定\u003C/li\u003E\n\u003Cli\u003ERDSはMasterとRead Replicaが複数台\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eやってること\n      \u003C/h1\u003E\n\u003Cul\u003E\n\u003Cli\u003EEC2はIPアドレスをとってきてRole設定。稼働中かつ\u003Ccode\u003Eapp:true\u003C/code\u003Eとしたサーバがデプロイ対象になる。\u003C/li\u003E\n\u003Cli\u003ERDSはtagに対応していないので、Masterか否かを判断してendpointでアクセス。\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E必要なもの\n      \u003C/h1\u003E\u003Cp\u003E\u003Ca href=\"http://aws.amazon.com/jp/sdkforruby/\" title=\"http://aws.amazon.com/jp/sdkforruby/\" target=\"_blank\"\u003EAWS SDK for Ruby\u003C/a\u003E\u003C/p\u003E\n\u003Ch1\u003E\n        \u003Cspan id=\"1-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E環境変数\n      \u003C/h1\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"go\"\u003E$ export AWS_ACCESS_KEY_ID=\u0026quot;xxxxxxxxxxxxxxxxx\u0026quot;\u003C/span\u003E\n\u003Cspan class=\"go\"\u003E$ export AWS_SECRET_ACCESS_KEY=\u0026quot;xxxxxxxxxxxxxx\u0026quot;\u003C/span\u003E\n\u003Cspan class=\"go\"\u003E$ export EC2_URL=\u0026quot;http://ec2.ap-northeast-1.amazonaws.com\u0026quot;\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch1\u003E\n        \u003Cspan id=\"1-5\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-5\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003ERoleの設定\n      \u003C/h1\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eproduction.rb\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"nb\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;aws-sdk\u0026#39;\u003C/span\u003E\n\n\u003Cspan class=\"n\"\u003Eset\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:aws_access_key_id\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E     \u003Cspan class=\"no\"\u003EENV\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;AWS_ACCESS_KEY_ID\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Eset\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:aws_secret_access_key\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"no\"\u003EENV\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;AWS_SECRET_ACCESS_KEY\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n\n\u003Cspan class=\"c1\"\u003E#EC2\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"no\"\u003EENV\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;EC2_URL\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Eec2\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E\u003Cspan class=\"ss\"\u003EAWS\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:EC2\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Enew\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:ec2_endpoint\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"no\"\u003EENV\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;EC2_URL\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E].\u003C/span\u003E\u003Cspan class=\"n\"\u003Esub\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"sr\"\u003E/^https?:\\/\\//\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eelse\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Eec2\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E\u003Cspan class=\"ss\"\u003EAWS\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:EC2\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Enew\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Einstances\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Eec2\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstances\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eselect\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E \u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Etags\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:app\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E \u003Cspan class=\"o\"\u003E==\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;true\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E\u0026amp;\u0026amp;\u003C/span\u003E \u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Estatus\u003C/span\u003E \u003Cspan class=\"o\"\u003E==\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:running\u003C/span\u003E\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Emap\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"o\"\u003E\u0026amp;\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:private_ip_address\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\n\u003Cspan class=\"n\"\u003Erole\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:app\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E  \u003Cspan class=\"o\"\u003E*\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstances\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:behind_loadbalancer\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"kp\"\u003Etrue\u003C/span\u003E\n\n\u003Cspan class=\"c1\"\u003E#RDS\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"no\"\u003EENV\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;EC2_URL\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Erds\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E\u003Cspan class=\"ss\"\u003EAWS\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:RDS\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Enew\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:rds_endpoint\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"no\"\u003EENV\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;EC2_URL\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E].\u003C/span\u003E\u003Cspan class=\"n\"\u003Esub\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"sr\"\u003E/^https?:\\/\\/ec2/\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;rds\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eelse\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Erds\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E\u003Cspan class=\"ss\"\u003EAWS\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:RDS\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Enew\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\n\u003Cspan class=\"n\"\u003Erds_master\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Erds\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstances\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eselect\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E \u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eread_replica_source_db_instance_identifier\u003C/span\u003E \u003Cspan class=\"o\"\u003E==\u003C/span\u003E \u003Cspan class=\"kp\"\u003Enil\u003C/span\u003E \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Emap\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"o\"\u003E\u0026amp;\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:endpoint_address\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Erds_slave\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Erds\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstances\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eselect\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E\u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E \u003Cspan class=\"n\"\u003Einstance\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eread_replica_source_db_instance_identifier\u003C/span\u003E \u003Cspan class=\"o\"\u003E!=\u003C/span\u003E \u003Cspan class=\"kp\"\u003Enil\u003C/span\u003E   \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Emap\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"o\"\u003E\u0026amp;\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:endpoint_address\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\n\u003Cspan class=\"n\"\u003Erole\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:db_host\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"o\"\u003E*\u003C/span\u003E\u003Cspan class=\"n\"\u003Erds_master\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:no_release\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"kp\"\u003Etrue\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:primary\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"kp\"\u003Etrue\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:name\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;default\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:rds\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"kp\"\u003Etrue\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Erds_slave\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eeach_with_index\u003C/span\u003E\u003Cspan class=\"p\"\u003E{\u003C/span\u003E \u003Cspan class=\"o\"\u003E|\u003C/span\u003E\u003Cspan class=\"n\"\u003Eslave\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Ei\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E \u003Cspan class=\"vi\"\u003E@slave_num\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Ei\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"mi\"\u003E1\u003C/span\u003E \n\u003Cspan class=\"n\"\u003Erole\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:db_host\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Eslave\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:no_release\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"kp\"\u003Etrue\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:name\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;slave\u0026quot;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"vi\"\u003E@slave_num\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eto_s\u003C/span\u003E \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch1\u003E\n        \u003Cspan id=\"1-6\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-6\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E参考\n      \u003C/h1\u003E\u003Cp\u003E\u003Ca href=\"http://qiita.com/STAR_ZERO/items/0131c542a8951de557fd\" title=\"http://qiita.com/STAR_ZERO/items/0131c542a8951de557fd\" \u003ECapistranoでELB配下のEC2インスタンスを取得してデプロイ\u003C/a\u003E\u003Cbr\u003E\n\u003Ca href=\"http://blog.excale.net/index.php/archives/351\" title=\"http://blog.excale.net/index.php/archives/351\" target=\"_blank\"\u003EeXcale | Blog : CapstranoでAWSのAPIを使って実行時にroleを設定する\u003C/a\u003E\u003C/p\u003E\n"},{"id":24630,"uuid":"9aa6e2eab63dd82c8d64","user":{"id":12272,"url_name":"shin1x1","profile_image_url":"https://si0.twimg.com/profile_images/1118038428/be5c756e-ae2f-49b6-8c7b-bd8508b6dc93_normal.png"},"title":"PhpStorm 7 EAP 130.1481 の Vagrant 対応を試してみた。","created_at":"2013-08-14 12:32:42 +0900","updated_at":"2013-08-14 12:32:42 +0900","created_at_in_words":"4時間前","updated_at_in_words":"4時間前","tags":[{"name":"vagrant","url_name":"vagrant","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/1aceab77a3ab11d00db91be3ce58eabda35f7f15/medium.jpg?1364840360","versions":[]},{"name":"PhpStorm","url_name":"phpstorm","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/caa8e62ff8cac140ccc93e8a2bade616f7d201ea/medium.jpg?1364839492","versions":[]}],"stock_count":1,"stock_users":["tanakahisateru"],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/shin1x1/items/9aa6e2eab63dd82c8d64","gist_url":null,"tweet":true,"private":false,"created_at_as_seconds":1376451162,"raw_body":"PhpStorm EAP 130.1481 で Vagrant 対応を試してみました。\nhttp://blog.jetbrains.com/phpstorm/2013/08/phpstorm-7-0-eap-130-1481/\n\nvagrant コマンドのラッパーで、VMの起動、終了( up / reload / suspend / halt / destory )ができます。\n\n「Init in Project Root」( vagrant init のラッパー)で Vagrantfile が作れます。 ただ選択した box ファイル名にプロバイダー名が含まれている`centos64(virtualbox)`ので、そのままでは起動できませんでした。\n\n```rb::Vagrantfile\nconfig.vm.box = \"centos64_ja  (virtualbox)\"\n```\n\nプロバイダー名を除けば、起動できます。\n\n```rb::Vagrantfile\nconfig.vm.box = \"centos64_ja\"\n```\n\n\n下記の issue から実装されたようなので、VM の起動、終了を IDE からできるようにした機能のようです。\nhttp://youtrack.jetbrains.com/issue/WI-15874","body":"\u003Cp\u003EPhpStorm EAP 130.1481 で Vagrant 対応を試してみました。\u003Cbr\u003E\n\u003Ca href=\"http://blog.jetbrains.com/phpstorm/2013/08/phpstorm-7-0-eap-130-1481/\" title=\"http://blog.jetbrains.com/phpstorm/2013/08/phpstorm-7-0-eap-130-1481/\" target=\"_blank\"\u003Ehttp://blog.jetbrains.com/phpstorm/2013/08/phpstorm-7-0-eap-130-1481/\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003Evagrant コマンドのラッパーで、VMの起動、終了( up / reload / suspend / halt / destory )ができます。\u003C/p\u003E\n\u003Cp\u003E「Init in Project Root」( vagrant init のラッパー)で Vagrantfile が作れます。 ただ選択した box ファイル名にプロバイダー名が含まれている\u003Ccode\u003Ecentos64(virtualbox)\u003C/code\u003Eので、そのままでは起動できませんでした。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003E:Vagrantfile\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"n\"\u003Econfig\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Evm\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ebox\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;centos64_ja  (virtualbox)\u0026quot;\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eプロバイダー名を除けば、起動できます。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003E:Vagrantfile\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"n\"\u003Econfig\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Evm\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ebox\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;centos64_ja\u0026quot;\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E下記の issue から実装されたようなので、VM の起動、終了を IDE からできるようにした機能のようです。\u003Cbr\u003E\n\u003Ca href=\"http://youtrack.jetbrains.com/issue/WI-15874\" title=\"http://youtrack.jetbrains.com/issue/WI-15874\" target=\"_blank\"\u003Ehttp://youtrack.jetbrains.com/issue/WI-15874\u003C/a\u003E\u003C/p\u003E\n"},{"id":24629,"uuid":"816dde96b0a5a453afd7","user":{"id":25676,"url_name":"dumpty-alma@github","profile_image_url":"https://secure.gravatar.com/avatar/45f2d7880a9dae1e5edce06214125db9?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"KVMコマンドをちまちま上げていく。~メモリ~","created_at":"2013-08-14 12:07:39 +0900","updated_at":"2013-08-14 12:07:39 +0900","created_at_in_words":"4時間前","updated_at_in_words":"4時間前","tags":[{"name":"KVM","url_name":"kvm","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/dumpty-alma@github/items/816dde96b0a5a453afd7","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376449659,"raw_body":"KVMを操作してて、パッと出てこないことが多いのでメモする。\n\n######登録されている仮想マシンの一覧を表示する。\n\n```bash:\nvirsh list --all\n```\n\n稼動している奴は「running」、停止しているのは「shutdown」と表示される。\n\n```bash:\nroot@minerva:~# virsh list\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 10 CentOS_6.3_x86_64    running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n\nroot@minerva:~#\n```\n\n######KVM本体(ホスト)のメモリー状態を表示する。\n\n```bash:\nvirsh nodememstats\n```\n\nこんな風に表示される。\n\n```bash:\nroot@minerva:~# virsh nodememstats\ntotal  :              8125016 kB\nfree   :               291984 kB\nbuffers:               155132 kB\ncached :              6059428 kB\n\nroot@minerva:~# \n```\n\n######仮想マシンのメモリ割り当て(設定値?)を表示する。※数値からして現在使用量じゃないっぽい?\n\n\n```bash:\nvirsh dommemstat [ID]\n```\n\n[ID]はlist --allした際のIDを指定する。\n\n```bash:\nroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 10 CentOS_6.3_x86_64    running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n\nroot@minerva:~# virsh dommemstat 2 \nactual 262144\n\nroot@minerva:~# virsh dommemstat 10\nactual 524288\n\nroot@minerva:~# \n```\n\n######メモリ関連のコマンドっぽいの。\n\n```bash:\nroot@minerva:~# virsh help|grep mem\n    memtune                        Get or set memory parameters\n    setmaxmem                      change maximum memory limit\n    setmem                         change memory allocation\n    dommemstat                     get memory statistics for a domain\n    freecell                       NUMA free memory\n    nodememstats                   Prints memory stats of the node.\nroot@minerva:~# \n```\n\nsetmaxmemとか、setmem辺りは仮想マシンの設定値を決めたり、変更したりするのかなぁ。\ndommemstatとnodememstatsは仮想マシンのメモリ設定値とホストの状態かな。\n\n\n","body":"\u003Cp\u003EKVMを操作してて、パッと出てこないことが多いのでメモする。\u003C/p\u003E\n\u003Ch6\u003E\n        \u003Cspan id=\"6-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E登録されている仮想マシンの一覧を表示する。\n      \u003C/h6\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirsh list --all\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E稼動している奴は「running」、停止しているのは「shutdown」と表示される。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh list\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 10 CentOS_6.3_x86_64    running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n\nroot@minerva:~#\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch6\u003E\n        \u003Cspan id=\"6-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003EKVM本体(ホスト)のメモリー状態を表示する。\n      \u003C/h6\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirsh nodememstats\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこんな風に表示される。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh nodememstats\ntotal  :              8125016 kB\nfree   :               291984 kB\nbuffers:               155132 kB\ncached :              6059428 kB\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch6\u003E\n        \u003Cspan id=\"6-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E仮想マシンのメモリ割り当て(設定値?)を表示する。※数値からして現在使用量じゃないっぽい?\n      \u003C/h6\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Evirsh dommemstat \u003Cspan class=\"o\"\u003E[\u003C/span\u003EID\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E[ID]はlist --allした際のIDを指定する。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh list --all\n Id Name                 State\n----------------------------------\n  2 Ubuntu_precise_12.04 running\n  5 Ubuntu_quantal_12.10 running\n 10 CentOS_6.3_x86_64    running\n 11 CentOS_6.3_x86_64-clone2 running\n 12 CentOS_6.3_x86_64-clone1 running\n\nroot@minerva:~# virsh dommemstat 2 \nactual 262144\n\nroot@minerva:~# virsh dommemstat 10\nactual 524288\n\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch6\u003E\n        \u003Cspan id=\"6-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#6-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eメモリ関連のコマンドっぽいの。\n      \u003C/h6\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eroot@minerva:~# virsh \u003Cspan class=\"nb\"\u003Ehelp\u003C/span\u003E|grep mem\n    memtune                        Get or \u003Cspan class=\"nb\"\u003Eset \u003C/span\u003Ememory parameters\n    setmaxmem                      change maximum memory limit\n    setmem                         change memory allocation\n    dommemstat                     get memory statistics \u003Cspan class=\"k\"\u003Efor \u003C/span\u003Ea domain\n    freecell                       NUMA free memory\n    nodememstats                   Prints memory stats of the node.\nroot@minerva:~# \n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Esetmaxmemとか、setmem辺りは仮想マシンの設定値を決めたり、変更したりするのかなぁ。\u003Cbr\u003E\ndommemstatとnodememstatsは仮想マシンのメモリ設定値とホストの状態かな。\u003C/p\u003E\n"},{"id":24628,"uuid":"8d59a1746f644355f7c0","user":{"id":2920,"url_name":"kouchi67","profile_image_url":"https://si0.twimg.com/profile_images/781962686/4233289_4018055517_normal.jpg"},"title":"SourceTreeで競合したとき","created_at":"2013-08-14 12:01:17 +0900","updated_at":"2013-08-14 12:01:17 +0900","created_at_in_words":"4時間前","updated_at_in_words":"4時間前","tags":[{"name":"git","url_name":"git","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/79cc9484a6f1bf99038b0b0c527a9426acb429a7/medium.jpg?1364838337","versions":[]},{"name":"Xcode","url_name":"xcode","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/9039ca23e780ba2255f64268a26fcda26e97403a/medium.jpg?1364839387","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/kouchi67/items/8d59a1746f644355f7c0","gist_url":null,"tweet":true,"private":false,"created_at_as_seconds":1376449277,"raw_body":"チームでの開発において、mergeやrebaseは欠かせないモノ。\nそれらを使っていると必ずどこかでConflictが発生する。\n(Xcodeの.xcodeprojとか、しょっちゅうConflictとの戦い。)\n\n普段はSourceTreeを使ってgitの操作を行なっているわけだけど、\n`自分の変更`だとか`相手の変更`だとかで上書きする事がよくある。\nその際の`merge`と`rebase`における`自分の変更`と`相手の変更`を間違えて記憶していたのでメモ。\n\n##以下のブランチがあると仮定\n master\n*myBranch\n(myBranchを参照しているとする)\n\n##mergeするときにConflict\n自分: myBranch\n相手: master\n\n##rebaseするときにConflict\n自分: master\n相手: myBranch\n\n\n##まとめ\nrebaseの動きをちゃんと把握してないからこういうことが起きるわけだけど、\n`$git rebase master`を実行してからの内部的な動きとしては、\n- masterブランチにCheckout\n- myBranchの変更を順次適応\nという形になるわけなので、自分=masterという事になる。\n\n参考:[Git - リベース](http://git-scm.com/book/ja/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%AA%E3%83%99%E3%83%BC%E3%82%B9)\n","body":"\u003Cp\u003Eチームでの開発において、mergeやrebaseは欠かせないモノ。\u003Cbr\u003E\nそれらを使っていると必ずどこかでConflictが発生する。\u003Cbr\u003E\n(Xcodeの.xcodeprojとか、しょっちゅうConflictとの戦い。)\u003C/p\u003E\n\u003Cp\u003E普段はSourceTreeを使ってgitの操作を行なっているわけだけど、\u003Cbr\u003E\n\u003Ccode\u003E自分の変更\u003C/code\u003Eだとか\u003Ccode\u003E相手の変更\u003C/code\u003Eだとかで上書きする事がよくある。\u003Cbr\u003E\nその際の\u003Ccode\u003Emerge\u003C/code\u003Eと\u003Ccode\u003Erebase\u003C/code\u003Eにおける\u003Ccode\u003E自分の変更\u003C/code\u003Eと\u003Ccode\u003E相手の変更\u003C/code\u003Eを間違えて記憶していたのでメモ。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E以下のブランチがあると仮定\n      \u003C/h2\u003E\u003Cp\u003E master\u003Cbr\u003E\n*myBranch\u003Cbr\u003E\n(myBranchを参照しているとする)\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003EmergeするときにConflict\n      \u003C/h2\u003E\u003Cp\u003E自分: myBranch\u003Cbr\u003E\n相手: master\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003ErebaseするときにConflict\n      \u003C/h2\u003E\u003Cp\u003E自分: master\u003Cbr\u003E\n相手: myBranch\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eまとめ\n      \u003C/h2\u003E\u003Cp\u003Erebaseの動きをちゃんと把握してないからこういうことが起きるわけだけど、\u003Cbr\u003E\n\u003Ccode\u003E$git rebase master\u003C/code\u003Eを実行してからの内部的な動きとしては、\u003Cbr\u003E\n- masterブランチにCheckout\u003Cbr\u003E\n- myBranchの変更を順次適応\u003Cbr\u003E\nという形になるわけなので、自分=masterという事になる。\u003C/p\u003E\n\u003Cp\u003E参考:\u003Ca href=\"http://git-scm.com/book/ja/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%AA%E3%83%99%E3%83%BC%E3%82%B9\" title=\"http://git-scm.com/book/ja/Git-%E3%81%AE%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%A9%9F%E8%83%BD-%E3%83%AA%E3%83%99%E3%83%BC%E3%82%B9\" target=\"_blank\"\u003EGit - リベース\u003C/a\u003E\u003C/p\u003E\n"},{"id":24627,"uuid":"e46be8ae66064f1f4657","user":{"id":15632,"url_name":"kidapu","profile_image_url":"https://twimg0-a.akamaihd.net/profile_images/2048848110/image_normal.jpg"},"title":"Cloud Watch カスタマイズ on Cent5.6","created_at":"2013-08-14 11:47:08 +0900","updated_at":"2013-08-14 11:56:08 +0900","created_at_in_words":"5時間前","updated_at_in_words":"5時間前","tags":[{"name":"ShellScript","url_name":"shellscript","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/6775262832b410128932fe1c84b8c7f5a1f33cd5/medium.jpg?1364837762","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/kidapu/items/e46be8ae66064f1f4657","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376448428,"raw_body":"以下、記事にしたがって、Cloud Watchをカスタマイズしようと思った。\nhttp://thinking.ne.jp/2013/01/aws-cloudwatch-ec2/\n\nら、2点つまったメモ。\n①jdkが入ってなかったぽいので、install\n\n```\nyum install java-1.7.0-openjdk-devel\n```\n\n②crontab -eするとなんか起こられたので、以下実行。\n\n```\n[root@vpsadmin ~]# touch ~/.bashrc\n[root@vpsadmin ~]# export VISUAL=vim\n[root@vpsadmin ~]# source ~/.bashrc\n```\n\n以上。","body":"\u003Cp\u003E以下、記事にしたがって、Cloud Watchをカスタマイズしようと思った。\u003Cbr\u003E\n\u003Ca href=\"http://thinking.ne.jp/2013/01/aws-cloudwatch-ec2/\" title=\"http://thinking.ne.jp/2013/01/aws-cloudwatch-ec2/\" target=\"_blank\"\u003Ehttp://thinking.ne.jp/2013/01/aws-cloudwatch-ec2/\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003Eら、2点つまったメモ。\u003Cbr\u003E\n①jdkが入ってなかったぽいので、install\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eyum install java-1.7.0-openjdk-devel\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E②crontab -eするとなんか起こられたので、以下実行。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E[root@vpsadmin ~]# touch ~/.bashrc\n[root@vpsadmin ~]# export VISUAL=vim\n[root@vpsadmin ~]# source ~/.bashrc\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E以上。\u003C/p\u003E\n"},{"id":24626,"uuid":"1b09f4f5b8c760cb4c67","user":{"id":6406,"url_name":"soramugi","profile_image_url":"https://si0.twimg.com/profile_images/592608397/IMG_001009_normal.jpg"},"title":"Linuxのipアドレスのみを取得","created_at":"2013-08-14 11:42:40 +0900","updated_at":"2013-08-14 11:42:40 +0900","created_at_in_words":"5時間前","updated_at_in_words":"5時間前","tags":[{"name":"Linux","url_name":"linux","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/ae420e8f134ac99c9f691b907029ae347d42c4fc/medium.jpg?1364838323","versions":[]}],"stock_count":1,"stock_users":["mosson@github"],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/soramugi/items/1b09f4f5b8c760cb4c67","gist_url":null,"tweet":true,"private":false,"created_at_as_seconds":1376448160,"raw_body":"    ifconfig eth0|grep inet|awk '{print $2}'|cut -d: -f2","body":"\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003Eifconfig eth0|grep inet|awk \u0026#39;{print $2}\u0026#39;|cut -d: -f2\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E"},{"id":24624,"uuid":"55390c60ba4a1d1fe5cd","user":{"id":12939,"url_name":"weed","profile_image_url":"https://secure.gravatar.com/avatar/7da1019ea35813b328f60f949a51ee2d?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"Node.js/Expressでのシンプルなファイルのアップロード","created_at":"2013-08-14 11:21:20 +0900","updated_at":"2013-08-14 11:36:29 +0900","created_at_in_words":"5時間前","updated_at_in_words":"5時間前","tags":[{"name":"Node.js","url_name":"node.js","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/67adbe42be3974cc849b41d2e05ae8148bb46550/medium.jpg?1364838363","versions":["0.11.4"]},{"name":"Express","url_name":"express","icon_url":"/icons/medium/missing.png","versions":["3.3.5"]},{"name":"Jade","url_name":"jade","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"CoffeeScript","url_name":"coffeescript","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/e41b881d25c683db2ce913dba0d07b9695a55741/medium.jpg?1368788624","versions":["1.3.3"]}],"stock_count":1,"stock_users":["Layzie"],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/weed/items/55390c60ba4a1d1fe5cd","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376446880,"raw_body":"基本的に以下のページと同じ内容です。\n\nNode.js/ExpressJSでのファイルのアップロード\nhttp://d.hatena.ne.jp/zebevogue/20120828/1346140796\n\nただし、何カ所か修正する必要がありました。\n\n###expressコマンド\n\n```\n$ express upload\n$ cd upload\n$ npm install\n$ mkdir uploads\n```\n\n流れとしては\n1. ```get '/'```で **routes/index.js#index** が呼ばれてフォームを表示し、\n2. ```post 'upload'```で **routes/upload.js#upload** が呼ばれてアップロードされたファイルを処理する\nという感じで良い。\n\nまず1.からやる。\n\n###app.jsを編集する\n\n下記のように編集する\n\n```js:app.js\nvar routes = {\n\tindex  : require('./routes/index'),\n};\n...\napp.get('/', routes.index.index);\n...\n```\n\n###routes/index.js\n\n個人的趣味でCoffeeScriptで書いた。```-b```オプションを付けた```coffee -bcw index.coffee```コマンドで変換するので、 **app.js** からでも中まで見える。というか、デフォルトそのまま。\n\n```coffeescript::index.coffee\nexports.index = (req, res) -\u003E\n  res.render 'index',{\n    title: 'Express'\n  }\n```\n\n```js:index.js\nexports.index = function(req, res) {\n  res.render('index', {\n    title: 'Express'\n  });\n};\n```\n\n参照する **index.jade** テンプレートにフォームを記述する。\n\n```jade:index.jade\nextends layout\n\nblock content\n  form(method=\"post\", enctype=\"multipart/form-data\", action=\"/upload\")\n    input(type=\"file\", name=\"thumbnail\")\n    input(type=\"submit\")\n```\n\nこれでフォームが見えるはず。\n\n![スクリーンショット 2013-08-14 11.15.18.png](https://qiita-image-store.s3.amazonaws.com/0/12939/1b9f1ac9-e909-62e2-2668-de3830071822.png)\n\n次に2.をやる\n\n###app.js\n\n```js:app.js\nvar routes = {\n\tindex  : require('./routes/index'),\n\tupload : require('./routes/upload')\n};\n...\n\napp.configure(function(){\n\t...\n\t//app.use(express.bodyParser());\n\tapp.use(express.bodyParser({uploadDir:'./uploads'}));\n\t...\n});\n\napp.get('/', routes.index.index);\napp.post('/upload', routes.upload.post);\n...\n```\n\n###routes/upload.js\n\n```coffeescript:upload.coffee\nfs = require 'fs'\nexports.post = (req, res) -\u003E\n  # 一時ファイルのパス\n  tmp_path = req.files.thumbnail.path\n  # public以下に置くパス\n  target_path = './uploads/' + req.files.thumbnail.name\n  # public以下に移動\n  fs.rename tmp_path, target_path, (err) -\u003E\n    if err then throw err\n    # 一時ファイルを削除\n    fs.unlink tmp_path, -\u003E\n      if err then throw err\n      res.send 'File uploaded to: ' + target_path + ' - ' + req.files.thumbnail.size + ' bytes'\n```\n\n```js:upload.js\nvar fs;\n\nfs = require('fs');\n\nexports.post = function(req, res) {\n  var target_path, tmp_path;\n  tmp_path = req.files.thumbnail.path;\n  target_path = './uploads/' + req.files.thumbnail.name;\n  fs.rename(tmp_path, target_path, function(err) {\n    if (err) {\n      throw err;\n    }\n    fs.unlink(tmp_path, function() {\n      if (err) {\n        throw err;\n      }\n      res.send('File uploaded to: ' + target_path + ' - ' + req.files.thumbnail.size + ' bytes');\n    });\n  });\n};\n```\n\nこれで以下のようにアップロードできるようになる。\n\n![スクリーンショット 2013-08-14 11.18.54.png](https://qiita-image-store.s3.amazonaws.com/0/12939/4b69bd93-f030-34c7-a346-11f977b078b7.png)\n\n-----\nブログやってます:[PAPA-tronix !](http://weed.cocolog-nifty.com/wzero3es/)\n","body":"\u003Cp\u003E基本的に以下のページと同じ内容です。\u003C/p\u003E\n\u003Cp\u003ENode.js/ExpressJSでのファイルのアップロード\u003Cbr\u003E\n\u003Ca href=\"http://d.hatena.ne.jp/zebevogue/20120828/1346140796\" title=\"http://d.hatena.ne.jp/zebevogue/20120828/1346140796\" target=\"_blank\"\u003Ehttp://d.hatena.ne.jp/zebevogue/20120828/1346140796\u003C/a\u003E\u003C/p\u003E\n\u003Cp\u003Eただし、何カ所か修正する必要がありました。\u003C/p\u003E\n\u003Ch3\u003E\n        \u003Cspan id=\"3-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#3-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eexpressコマンド\n      \u003C/h3\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E$ express upload\n$ cd upload\n$ npm install\n$ mkdir uploads\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E流れとしては\u003Cbr\u003E\n1. \u003Ccode\u003Eget \u0026#39;/\u0026#39;\u003C/code\u003Eで \u003Cstrong\u003Eroutes/index.js#index\u003C/strong\u003E が呼ばれてフォームを表示し、\u003Cbr\u003E\n2. \u003Ccode\u003Epost \u0026#39;upload\u0026#39;\u003C/code\u003Eで \u003Cstrong\u003Eroutes/upload.js#upload\u003C/strong\u003E が呼ばれてアップロードされたファイルを処理する\u003Cbr\u003E\nという感じで良い。\u003C/p\u003E\n\u003Cp\u003Eまず1.からやる。\u003C/p\u003E\n\u003Ch3\u003E\n        \u003Cspan id=\"3-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#3-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eapp.jsを編集する\n      \u003C/h3\u003E\u003Cp\u003E下記のように編集する\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eapp.js\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eroutes\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E  \u003Cspan class=\"o\"\u003E:\u003C/span\u003E \u003Cspan class=\"nx\"\u003Erequire\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;./routes/index\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E),\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E};\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E...\u003C/span\u003E\n\u003Cspan class=\"nx\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eget\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;/\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eroutes\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E...\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch3\u003E\n        \u003Cspan id=\"3-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#3-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eroutes/index.js\n      \u003C/h3\u003E\u003Cp\u003E個人的趣味でCoffeeScriptで書いた。\u003Ccode\u003E-b\u003C/code\u003Eオプションを付けた\u003Ccode\u003Ecoffee -bcw index.coffee\u003C/code\u003Eコマンドで変換するので、 \u003Cstrong\u003Eapp.js\u003C/strong\u003E からでも中まで見える。というか、デフォルトそのまま。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003E:index.coffee\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"nv\"\u003Eexports.index = \u003C/span\u003E\u003Cspan class=\"nf\"\u003E(req, res) -\u0026gt;\u003C/span\u003E\n  \u003Cspan class=\"nx\"\u003Eres\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Erender\u003C/span\u003E \u003Cspan class=\"s\"\u003E\u0026#39;index\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,{\u003C/span\u003E\n    \u003Cspan class=\"nv\"\u003Etitle: \u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026#39;Express\u0026#39;\u003C/span\u003E\n  \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eindex.js\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"nx\"\u003Eexports\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kd\"\u003Efunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eres\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n  \u003Cspan class=\"nx\"\u003Eres\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Erender\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;index\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Etitle\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;Express\u0026#39;\u003C/span\u003E\n  \u003Cspan class=\"p\"\u003E});\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E};\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E参照する \u003Cstrong\u003Eindex.jade\u003C/strong\u003E テンプレートにフォームを記述する。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eindex.jade\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"nt\"\u003Eextends\u003C/span\u003E layout\n\n\u003Cspan class=\"nt\"\u003Eblock\u003C/span\u003E content\n  \u003Cspan class=\"nt\"\u003Eform\u003C/span\u003E(\u003Cspan class=\"na\"\u003Emethod=\u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026quot;post\u0026quot;\u003C/span\u003E\u003Cspan class=\"err\"\u003E,\u003C/span\u003E \u003Cspan class=\"na\"\u003Eenctype=\u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026quot;multipart/form-data\u0026quot;\u003C/span\u003E\u003Cspan class=\"err\"\u003E,\u003C/span\u003E \u003Cspan class=\"na\"\u003Eaction=\u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026quot;/upload\u0026quot;\u003C/span\u003E)\n    \u003Cspan class=\"nt\"\u003Einput\u003C/span\u003E(\u003Cspan class=\"na\"\u003Etype=\u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026quot;file\u0026quot;\u003C/span\u003E\u003Cspan class=\"err\"\u003E,\u003C/span\u003E \u003Cspan class=\"na\"\u003Ename=\u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026quot;thumbnail\u0026quot;\u003C/span\u003E)\n    \u003Cspan class=\"nt\"\u003Einput\u003C/span\u003E(\u003Cspan class=\"na\"\u003Etype=\u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026quot;submit\u0026quot;\u003C/span\u003E)\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこれでフォームが見えるはず。\u003C/p\u003E\n\u003Cp\u003E\u003Cimg src=\"https://qiita-image-store.s3.amazonaws.com/0/12939/1b9f1ac9-e909-62e2-2668-de3830071822.png\" alt=\"スクリーンショット 2013-08-14 11.15.18.png\"\u003E\u003C/p\u003E\n\u003Cp\u003E次に2.をやる\u003C/p\u003E\n\u003Ch3\u003E\n        \u003Cspan id=\"3-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#3-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eapp.js\n      \u003C/h3\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eapp.js\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eroutes\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E  \u003Cspan class=\"o\"\u003E:\u003C/span\u003E \u003Cspan class=\"nx\"\u003Erequire\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;./routes/index\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E),\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eupload\u003C/span\u003E \u003Cspan class=\"o\"\u003E:\u003C/span\u003E \u003Cspan class=\"nx\"\u003Erequire\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;./routes/upload\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E};\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E...\u003C/span\u003E\n\n\u003Cspan class=\"nx\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Econfigure\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"kd\"\u003Efunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E(){\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E...\u003C/span\u003E\n    \u003Cspan class=\"c1\"\u003E//app.use(express.bodyParser());\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Euse\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eexpress\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003EbodyParser\u003C/span\u003E\u003Cspan class=\"p\"\u003E({\u003C/span\u003E\u003Cspan class=\"nx\"\u003EuploadDir\u003C/span\u003E\u003Cspan class=\"o\"\u003E:\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;./uploads\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E}));\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E...\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E});\u003C/span\u003E\n\n\u003Cspan class=\"nx\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eget\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;/\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eroutes\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eindex\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\u003Cspan class=\"nx\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Epost\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;/upload\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eroutes\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eupload\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Epost\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E...\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch3\u003E\n        \u003Cspan id=\"3-5\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#3-5\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eroutes/upload.js\n      \u003C/h3\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eupload.coffee\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"nv\"\u003Efs = \u003C/span\u003E\u003Cspan class=\"nx\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"s\"\u003E\u0026#39;fs\u0026#39;\u003C/span\u003E\n\u003Cspan class=\"nv\"\u003Eexports.post = \u003C/span\u003E\u003Cspan class=\"nf\"\u003E(req, res) -\u0026gt;\u003C/span\u003E\n  \u003Cspan class=\"c1\"\u003E# 一時ファイルのパス\u003C/span\u003E\n  \u003Cspan class=\"nv\"\u003Etmp_path = \u003C/span\u003E\u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Efiles\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ethumbnail\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Epath\u003C/span\u003E\n  \u003Cspan class=\"c1\"\u003E# public以下に置くパス\u003C/span\u003E\n  \u003Cspan class=\"nv\"\u003Etarget_path = \u003C/span\u003E\u003Cspan class=\"s\"\u003E\u0026#39;./uploads/\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Efiles\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ethumbnail\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ename\u003C/span\u003E\n  \u003Cspan class=\"c1\"\u003E# public以下に移動\u003C/span\u003E\n  \u003Cspan class=\"nx\"\u003Efs\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Erename\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etmp_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etarget_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nf\"\u003E(err) -\u0026gt;\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethen\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethrow\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\n    \u003Cspan class=\"c1\"\u003E# 一時ファイルを削除\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Efs\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eunlink\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etmp_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nf\"\u003E-\u0026gt;\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethen\u003C/span\u003E \u003Cspan class=\"k\"\u003Ethrow\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\n      \u003Cspan class=\"nx\"\u003Eres\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Esend\u003C/span\u003E \u003Cspan class=\"s\"\u003E\u0026#39;File uploaded to: \u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etarget_path\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"s\"\u003E\u0026#39; - \u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Efiles\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ethumbnail\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Esize\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"s\"\u003E\u0026#39; bytes\u0026#39;\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003Eupload.js\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Efs\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n\n\u003Cspan class=\"nx\"\u003Efs\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Erequire\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;fs\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n\u003Cspan class=\"nx\"\u003Eexports\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Epost\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kd\"\u003Efunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eres\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n  \u003Cspan class=\"kd\"\u003Evar\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etarget_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etmp_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n  \u003Cspan class=\"nx\"\u003Etmp_path\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Efiles\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ethumbnail\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Epath\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n  \u003Cspan class=\"nx\"\u003Etarget_path\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;./uploads/\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Efiles\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ethumbnail\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ename\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n  \u003Cspan class=\"nx\"\u003Efs\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Erename\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etmp_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etarget_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"kd\"\u003Efunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Ethrow\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"nx\"\u003Efs\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eunlink\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Etmp_path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"kd\"\u003Efunction\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ethrow\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eerr\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n      \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n      \u003Cspan class=\"nx\"\u003Eres\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Esend\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;File uploaded to: \u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etarget_path\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39; - \u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"nx\"\u003Ereq\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Efiles\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Ethumbnail\u003C/span\u003E\u003Cspan class=\"p\"\u003E.\u003C/span\u003E\u003Cspan class=\"nx\"\u003Esize\u003C/span\u003E \u003Cspan class=\"o\"\u003E+\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39; bytes\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E});\u003C/span\u003E\n  \u003Cspan class=\"p\"\u003E});\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E};\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこれで以下のようにアップロードできるようになる。\u003C/p\u003E\n\u003Cp\u003E\u003Cimg src=\"https://qiita-image-store.s3.amazonaws.com/0/12939/4b69bd93-f030-34c7-a346-11f977b078b7.png\" alt=\"スクリーンショット 2013-08-14 11.18.54.png\"\u003E\u003C/p\u003E\n\n\u003Chr\u003E\n\u003Cp\u003Eブログやってます:\u003Ca href=\"http://weed.cocolog-nifty.com/wzero3es/\" title=\"http://weed.cocolog-nifty.com/wzero3es/\" target=\"_blank\"\u003EPAPA-tronix !\u003C/a\u003E\u003C/p\u003E\n"},{"id":24619,"uuid":"ffb7d8eba3833f1e3cf6","user":{"id":27361,"url_name":"bounscale","profile_image_url":"https://secure.gravatar.com/avatar/84e756f6fd841631143905ac82f8b52c?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"zbxapi(Ruby)でZabbixから取得した結果をキャッシュする","created_at":"2013-08-14 11:05:26 +0900","updated_at":"2013-08-14 11:05:26 +0900","created_at_in_words":"5時間前","updated_at_in_words":"5時間前","tags":[{"name":"zabbix","url_name":"zabbix","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"Ruby","url_name":"ruby","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/9de6a11d330f5694820082438f88ccf4a1b289b2/medium.jpg?1364837630","versions":[]},{"name":"zbxapi","url_name":"zbxapi","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/bounscale/items/ffb7d8eba3833f1e3cf6","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376445926,"raw_body":"zbxapi(Ruby)でZabbixから取得した結果をキャッシュする\n====\n\nはじめに\n----\n[Bounscale](https://github.com/bounscale/bounscale/)というオートスケールするHeroku Addonを作っています。\n\nBounscaleはオートスケーリングの実施をするバックエンド部分にオープンソースの監視ソフト[Zabbix](https://www.zabbix.org/)を利用しています。1サーバ当たりの集約率を上げるために、Zabbix自体への接続をできるだけ回避する方法を考案したので、下記に書いておきます。\n\n背景\n----\nZabbixは[ZabbixAPIというWebAPI](https://www.zabbix.com/documentation/2.0/manual/appendix/api/api)を備えています。Bounscaleでは、フロントエンドのRubyからZabbixAPIへの接続ライブラリには[zbxapi](http://trac.red-tux.net/wiki/zbx_api)というgemを利用しています。\nZabbix上のデータが多数溜まってくると、このZabbixAPIからのレスポンスが悪くなってきて、フロントエンドがもっさりしてきます。\n\nもちろんZabbix自体のチューニングを実施する事も重要ですが、ほとんど更新のないようなデータを、Rubyが繰り返しZabbixへリクエスト部分があったので、キャッシュ化することで不要なやりとりを回避しようと考えました。\n\nアイデア\n----\nZabbixAPIはHTTPのリクエスト/レスポンスをJSON形式でやり取りします。\nそこで、リクエストのJSONデータをキー、レスポンスをバリューとしたキーバリューストアを準備すれば、キャッシングに使えそうです。\nキーは一意であれば全データである必要はありませんので、SHAなどでハッシュ化した文字列を持たせておけば十分でしょう。\n\nバージョン\n----\nZabbix 2.0.3\nzbxapi 0.2.415\n\n実装方式\n----\nzbxapiライブラリのメソッドをRubyのオープンクラスとaliasでチェーン化して、間にキャッシュの機構をはさみます。キーバリューストアは今回のサンプルでは単にグローバルなハッシュテーブルとします。\n\nソース\n----\n下記のような感じで実装してみました。\n\n一応Thread.currentでスイッチのON/OFFを切り替えていてcache_enableブロックで囲まれている箇所でのみ有効となるようにしています。(Thread.currentはノンブロッキングだと崩壊しそうですが、今回はサンプルなので多めに見てください)\n\nまた、リクエストのJSONの中に全体の問い合わせの通番のような感じでカウントアップしていく値が含まれているので、そこは塗りつぶし(gsub)しています。\n\n````ruby\nrequire 'rubygems'\nrequire 'zbxapi'\nrequire 'openssl'\n\n# 簡易なキャッシュ用のクラス\nclass ZabbixCache\n  class \u003C\u003C self\n    @@cache = {}\n\n    def set(key, value)\n      @@cache[key] = value\n    end\n\n    def get(key)\n      @@cache[key]\n    end\n\n    def cache_enable\n      begin\n        Thread.current[:zabbix_cache_enable] = true\n        yield\n      ensure\n        Thread.current[:zabbix_cache_enable] = nil\n      end\n    end\n  end\nend\n\n# zbxapiから提供されるZabbixAPIクラスを再オープン\nclass ZabbixAPI\n  alias :do_request_orig :do_request\n  private\n  def do_request(json_obj,truncate_length=5000)\n    if defined? ZabbixCache\n      json_obj_key = OpenSSL::Digest::SHA1.hexdigest(json_obj.gsub(/\"id\":\\d*/, ''))\n      cache = ZabbixCache.get(json_obj_key)\n      result = nil\n      enable = Thread.current[:zabbix_cache_enable]\n      if cache \u0026\u0026 enable\n        puts 'CACHE HIT'\n        result = cache\n      else\n        result = do_request_orig(json_obj, truncate_length)\n        ZabbixCache.set(json_obj_key, result)\n      end\n      return result\n    else\n      return do_request_orig(json_obj, truncate_length)\n    end\n  end\nend\n\n# 実行\n\nputs \"####### login ######\"\nzabbix = ZabbixAPI.new('http://localhost/zabbix', :debug =\u003E 4)\nzabbix.login('admin', 'zabbix')\n\nputs \"####### request without cache ######\"\nresult = zabbix.user.get(:filter =\u003E {:alias =\u003E ['admin']}).first\np result\n\nputs \"####### request with cache ######\"\nZabbixCache.cache_enable do\n  cached_result = zabbix.user.get(:filter =\u003E {:alias =\u003E ['admin']}).first\n  p cached_result\nend\n````\n\n結果\n----\n結果は下記です。\n\n````\n####### login ######\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\"method\":\"user.login\",\"auth\":null,\"params\":{\"password\":\"zabbix\",\"user\":\"admin\"},\"id\":0,\"jsonrpc\":\"2.0\"}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\"jsonrpc\":\"2.0\",\"result\":\"efbabb46f84d3c9f409392b575261156\",\"id\":0}\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\"method\":\"APIInfo.version\",\"auth\":\"efbabb46f84d3c9f409392b575261156\",\"params\":{},\"id\":1,\"jsonrpc\":\"2.0\"}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\"jsonrpc\":\"2.0\",\"result\":\"1.4\",\"id\":1}\n####### request without cache ######\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\"method\":\"user.get\",\"auth\":\"efbabb46f84d3c9f409392b575261156\",\"params\":{\"filter\":{\"alias\":[\"admin\"]}},\"id\":2,\"jsonrpc\":\"2.0\"}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\"jsonrpc\":\"2.0\",\"result\":[{\"userid\":\"1\"}],\"id\":2}\n{\"userid\"=\u003E\"1\"}\n####### request with cache ######\nCACHE HIT\n{\"userid\"=\u003E\"1\"}\n````\n\n下記の部分がZabbixAPIへのリクエスト処理です。\n\n````\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\"method\":\"user.get\",\"auth\":\"efbabb46f84d3c9f409392b575261156\",\"params\":{\"filter\":{\"alias\":[\"admin\"]}},\"id\":2,\"jsonrpc\":\"2.0\"}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\"jsonrpc\":\"2.0\",\"result\":[{\"userid\":\"1\"}],\"id\":2}\n````\n\nキャッシュを効かせた状態では表示されていないので、見事にキャッシュされています。\n\n終わりに\n----\nキャッシュの機構の骨子は上記で作ることができました。\n\n次はどのタイミングでリフレッシュして最新のデータに同期するのかが問題となってきますが、これについてはアプリケーション毎にタイミングが異なるので、慎重に検討する必要があるでしょう。","body":"\u003Ch1\u003E\n        \u003Cspan id=\"1-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#1-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Ezbxapi(Ruby)でZabbixから取得した結果をキャッシュする\n      \u003C/h1\u003E\u003Ch2\u003E\n        \u003Cspan id=\"2-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eはじめに\n      \u003C/h2\u003E\u003Cp\u003E\u003Ca href=\"https://github.com/bounscale/bounscale/\" title=\"https://github.com/bounscale/bounscale/\" target=\"_blank\"\u003EBounscale\u003C/a\u003EというオートスケールするHeroku Addonを作っています。\u003C/p\u003E\n\u003Cp\u003EBounscaleはオートスケーリングの実施をするバックエンド部分にオープンソースの監視ソフト\u003Ca href=\"https://www.zabbix.org/\" title=\"https://www.zabbix.org/\" target=\"_blank\"\u003EZabbix\u003C/a\u003Eを利用しています。1サーバ当たりの集約率を上げるために、Zabbix自体への接続をできるだけ回避する方法を考案したので、下記に書いておきます。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E背景\n      \u003C/h2\u003E\u003Cp\u003EZabbixは\u003Ca href=\"https://www.zabbix.com/documentation/2.0/manual/appendix/api/api\" title=\"https://www.zabbix.com/documentation/2.0/manual/appendix/api/api\" target=\"_blank\"\u003EZabbixAPIというWebAPI\u003C/a\u003Eを備えています。Bounscaleでは、フロントエンドのRubyからZabbixAPIへの接続ライブラリには\u003Ca href=\"http://trac.red-tux.net/wiki/zbx_api\" title=\"http://trac.red-tux.net/wiki/zbx_api\" target=\"_blank\"\u003Ezbxapi\u003C/a\u003Eというgemを利用しています。\u003Cbr\u003E\nZabbix上のデータが多数溜まってくると、このZabbixAPIからのレスポンスが悪くなってきて、フロントエンドがもっさりしてきます。\u003C/p\u003E\n\u003Cp\u003EもちろんZabbix自体のチューニングを実施する事も重要ですが、ほとんど更新のないようなデータを、Rubyが繰り返しZabbixへリクエスト部分があったので、キャッシュ化することで不要なやりとりを回避しようと考えました。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eアイデア\n      \u003C/h2\u003E\u003Cp\u003EZabbixAPIはHTTPのリクエスト/レスポンスをJSON形式でやり取りします。\u003Cbr\u003E\nそこで、リクエストのJSONデータをキー、レスポンスをバリューとしたキーバリューストアを準備すれば、キャッシングに使えそうです。\u003Cbr\u003E\nキーは一意であれば全データである必要はありませんので、SHAなどでハッシュ化した文字列を持たせておけば十分でしょう。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eバージョン\n      \u003C/h2\u003E\u003Cp\u003EZabbix 2.0.3\u003Cbr\u003E\nzbxapi 0.2.415\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-5\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-5\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E実装方式\n      \u003C/h2\u003E\u003Cp\u003EzbxapiライブラリのメソッドをRubyのオープンクラスとaliasでチェーン化して、間にキャッシュの機構をはさみます。キーバリューストアは今回のサンプルでは単にグローバルなハッシュテーブルとします。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-6\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-6\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003Eソース\n      \u003C/h2\u003E\u003Cp\u003E下記のような感じで実装してみました。\u003C/p\u003E\n\u003Cp\u003E一応Thread.currentでスイッチのON/OFFを切り替えていてcache_enableブロックで囲まれている箇所でのみ有効となるようにしています。(Thread.currentはノンブロッキングだと崩壊しそうですが、今回はサンプルなので多めに見てください)\u003C/p\u003E\n\u003Cp\u003Eまた、リクエストのJSONの中に全体の問い合わせの通番のような感じでカウントアップしていく値が含まれているので、そこは塗りつぶし(gsub)しています。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"nb\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;rubygems\u0026#39;\u003C/span\u003E\n\u003Cspan class=\"nb\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;zbxapi\u0026#39;\u003C/span\u003E\n\u003Cspan class=\"nb\"\u003Erequire\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;openssl\u0026#39;\u003C/span\u003E\n\n\u003Cspan class=\"c1\"\u003E# 簡易なキャッシュ用のクラス\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nc\"\u003EZabbixCache\u003C/span\u003E\n  \u003Cspan class=\"k\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"o\"\u003E\u0026lt;\u0026lt;\u003C/span\u003E \u003Cspan class=\"nb\"\u003Eself\u003C/span\u003E\n    \u003Cspan class=\"vc\"\u003E@@cache\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"p\"\u003E{}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Edef\u003C/span\u003E \u003Cspan class=\"nf\"\u003Eset\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ekey\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Evalue\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n      \u003Cspan class=\"vc\"\u003E@@cache\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"n\"\u003Ekey\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Evalue\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Edef\u003C/span\u003E \u003Cspan class=\"nf\"\u003Eget\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ekey\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n      \u003Cspan class=\"vc\"\u003E@@cache\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"n\"\u003Ekey\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Edef\u003C/span\u003E \u003Cspan class=\"nf\"\u003Ecache_enable\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Ebegin\u003C/span\u003E\n        \u003Cspan class=\"no\"\u003EThread\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ecurrent\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:zabbix_cache_enable\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kp\"\u003Etrue\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Eyield\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eensure\u003C/span\u003E\n        \u003Cspan class=\"no\"\u003EThread\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ecurrent\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:zabbix_cache_enable\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kp\"\u003Enil\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n  \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\n\u003Cspan class=\"c1\"\u003E# zbxapiから提供されるZabbixAPIクラスを再オープン\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nc\"\u003EZabbixAPI\u003C/span\u003E\n  \u003Cspan class=\"k\"\u003Ealias\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:do_request_orig\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:do_request\u003C/span\u003E\n  \u003Cspan class=\"kp\"\u003Eprivate\u003C/span\u003E\n  \u003Cspan class=\"k\"\u003Edef\u003C/span\u003E \u003Cspan class=\"nf\"\u003Edo_request\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ejson_obj\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E\u003Cspan class=\"n\"\u003Etruncate_length\u003C/span\u003E\u003Cspan class=\"o\"\u003E=\u003C/span\u003E\u003Cspan class=\"mi\"\u003E5000\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"n\"\u003Edefined?\u003C/span\u003E \u003Cspan class=\"no\"\u003EZabbixCache\u003C/span\u003E\n      \u003Cspan class=\"n\"\u003Ejson_obj_key\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"ss\"\u003EOpenSSL\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:Digest\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"no\"\u003ESHA1\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ehexdigest\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ejson_obj\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Egsub\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"sr\"\u003E/\u0026quot;id\u0026quot;:\\d*/\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E\n      \u003Cspan class=\"n\"\u003Ecache\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"no\"\u003EZabbixCache\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eget\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ejson_obj_key\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n      \u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"kp\"\u003Enil\u003C/span\u003E\n      \u003Cspan class=\"n\"\u003Eenable\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"no\"\u003EThread\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ecurrent\u003C/span\u003E\u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:zabbix_cache_enable\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"n\"\u003Ecache\u003C/span\u003E \u003Cspan class=\"o\"\u003E\u0026amp;\u0026amp;\u003C/span\u003E \u003Cspan class=\"n\"\u003Eenable\u003C/span\u003E\n        \u003Cspan class=\"nb\"\u003Eputs\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;CACHE HIT\u0026#39;\u003C/span\u003E\n        \u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Ecache\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eelse\u003C/span\u003E\n        \u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Edo_request_orig\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ejson_obj\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Etruncate_length\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n        \u003Cspan class=\"no\"\u003EZabbixCache\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eset\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ejson_obj_key\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eelse\u003C/span\u003E\n      \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"n\"\u003Edo_request_orig\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Ejson_obj\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Etruncate_length\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n  \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\n\u003Cspan class=\"c1\"\u003E# 実行\u003C/span\u003E\n\n\u003Cspan class=\"nb\"\u003Eputs\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;####### login ######\u0026quot;\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Ezabbix\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"no\"\u003EZabbixAPI\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Enew\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;http://localhost/zabbix\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:debug\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"mi\"\u003E4\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Ezabbix\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Elogin\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;admin\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;zabbix\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\n\u003Cspan class=\"nb\"\u003Eputs\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;####### request without cache ######\u0026quot;\u003C/span\u003E\n\u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Ezabbix\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Euser\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eget\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:filter\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:alias\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;admin\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\u003Cspan class=\"p\"\u003E})\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Efirst\u003C/span\u003E\n\u003Cspan class=\"nb\"\u003Ep\u003C/span\u003E \u003Cspan class=\"n\"\u003Eresult\u003C/span\u003E\n\n\u003Cspan class=\"nb\"\u003Eputs\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;####### request with cache ######\u0026quot;\u003C/span\u003E\n\u003Cspan class=\"no\"\u003EZabbixCache\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ecache_enable\u003C/span\u003E \u003Cspan class=\"k\"\u003Edo\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Ecached_result\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Ezabbix\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Euser\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eget\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:filter\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:alias\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"o\"\u003E[\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;admin\u0026#39;\u003C/span\u003E\u003Cspan class=\"o\"\u003E]\u003C/span\u003E\u003Cspan class=\"p\"\u003E})\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Efirst\u003C/span\u003E\n  \u003Cspan class=\"nb\"\u003Ep\u003C/span\u003E \u003Cspan class=\"n\"\u003Ecached_result\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Ch2\u003E\n        \u003Cspan id=\"2-7\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-7\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E結果\n      \u003C/h2\u003E\u003Cp\u003E結果は下記です。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E####### login ######\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\u0026quot;method\u0026quot;:\u0026quot;user.login\u0026quot;,\u0026quot;auth\u0026quot;:null,\u0026quot;params\u0026quot;:{\u0026quot;password\u0026quot;:\u0026quot;zabbix\u0026quot;,\u0026quot;user\u0026quot;:\u0026quot;admin\u0026quot;},\u0026quot;id\u0026quot;:0,\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;,\u0026quot;result\u0026quot;:\u0026quot;efbabb46f84d3c9f409392b575261156\u0026quot;,\u0026quot;id\u0026quot;:0}\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\u0026quot;method\u0026quot;:\u0026quot;APIInfo.version\u0026quot;,\u0026quot;auth\u0026quot;:\u0026quot;efbabb46f84d3c9f409392b575261156\u0026quot;,\u0026quot;params\u0026quot;:{},\u0026quot;id\u0026quot;:1,\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;,\u0026quot;result\u0026quot;:\u0026quot;1.4\u0026quot;,\u0026quot;id\u0026quot;:1}\n####### request without cache ######\nD4 ..././zbxapi.rb:do_request_orig:352 Sending: {\u0026quot;method\u0026quot;:\u0026quot;user.get\u0026quot;,\u0026quot;auth\u0026quot;:\u0026quot;efbabb46f84d3c9f409392b575261156\u0026quot;,\u0026quot;params\u0026quot;:{\u0026quot;filter\u0026quot;:{\u0026quot;alias\u0026quot;:[\u0026quot;admin\u0026quot;]}},\u0026quot;id\u0026quot;:2,\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;,\u0026quot;result\u0026quot;:[{\u0026quot;userid\u0026quot;:\u0026quot;1\u0026quot;}],\u0026quot;id\u0026quot;:2}\n{\u0026quot;userid\u0026quot;=\u0026gt;\u0026quot;1\u0026quot;}\n####### request with cache ######\nCACHE HIT\n{\u0026quot;userid\u0026quot;=\u0026gt;\u0026quot;1\u0026quot;}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003E下記の部分がZabbixAPIへのリクエスト処理です。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003ED4 ..././zbxapi.rb:do_request_orig:352 Sending: {\u0026quot;method\u0026quot;:\u0026quot;user.get\u0026quot;,\u0026quot;auth\u0026quot;:\u0026quot;efbabb46f84d3c9f409392b575261156\u0026quot;,\u0026quot;params\u0026quot;:{\u0026quot;filter\u0026quot;:{\u0026quot;alias\u0026quot;:[\u0026quot;admin\u0026quot;]}},\u0026quot;id\u0026quot;:2,\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;}\nD4 ..././zbxapi.rb:do_request_orig:354 Response Code: 200\nD4 ..././zbxapi.rb:do_request_orig:355 Response Body: {\u0026quot;jsonrpc\u0026quot;:\u0026quot;2.0\u0026quot;,\u0026quot;result\u0026quot;:[{\u0026quot;userid\u0026quot;:\u0026quot;1\u0026quot;}],\u0026quot;id\u0026quot;:2}\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eキャッシュを効かせた状態では表示されていないので、見事にキャッシュされています。\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-8\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-8\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E終わりに\n      \u003C/h2\u003E\u003Cp\u003Eキャッシュの機構の骨子は上記で作ることができました。\u003C/p\u003E\n\u003Cp\u003E次はどのタイミングでリフレッシュして最新のデータに同期するのかが問題となってきますが、これについてはアプリケーション毎にタイミングが異なるので、慎重に検討する必要があるでしょう。\u003C/p\u003E\n"},{"id":24618,"uuid":"a2b3233ba8eba2c2b30d","user":{"id":644,"url_name":"emegane","profile_image_url":"https://secure.gravatar.com/avatar/935270913bcb1b098691214d147b3ef3?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"},"title":"CSVファイルをオブジェクト指向な感じで取り扱う方法","created_at":"2013-08-14 10:52:20 +0900","updated_at":"2013-08-14 10:52:20 +0900","created_at_in_words":"6時間前","updated_at_in_words":"6時間前","tags":[{"name":"PHP","url_name":"php","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/aae632f19de784bc000b317b06ed2320f2582469/medium.jpg?1364837706","versions":["5.3"]}],"stock_count":0,"stock_users":[],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/emegane/items/a2b3233ba8eba2c2b30d","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376445140,"raw_body":"次のようなCSVファイルがあったとします。\n\n```\n日付,商品コード,数量\n2013-08-01,12345,1\n2013-08-01,23456,2\n2013-08-02,34567,1\n```\n\nこのファイルをPHPでいい感じに取り扱えるコードを書いてみました。\n\n```php:ImportCsv.php\n\u003C?php\nclass ImportCsv \n{\n    protected $date;\n    protected $code;\n    protected $quantity;\n\n    public function getDate()\n    {\n        return $this-\u003Edate;\n    }\n\n    public function setDate($date)\n    {\n        $this-\u003Edate = $date;\n    }\n\n    public function getCode()\n    {\n        return $this-\u003Ecode;\n    }\n\n    public function setCode($code)\n    {\n        $this-\u003Ecode = $code;\n    }\n\n    public function getQuantity()\n    {\n        return $this-\u003Equantity;\n    }\n\n    public function setQuantity($quantity)\n    {\n        $this-\u003Equantity = $quantity;\n    }\n\n    public function getLine()\n    {\n        $ret = array();\n\n        foreach (self::getSupportedColumns() as $columnName) {\n            $ret[] = !is_null($this-\u003E$columnName) ? $this-\u003E$columnName : '';\n        }\n\n        return self::convertArrayToCsv($ret);\n    }\n\n    public function setLine($line, $layout = null)\n    {\n        $columns = self::getSupportedColumns();\n\n        if (is_null($layout)) {\n            $layout = self::getHeader();\n        }\n\n        if (count($line) !== count($layout)) {\n            throw new \\InvalidArgumentException('Invalid CSV layout is given');\n        }\n\n        foreach ($layout as $key =\u003E $column) {\n            if (array_key_exists($column, $columns)) {\n                $property = $columns[$column];\n                $this-\u003E$property = trim($line[$key]);\n            }\n        }\n    }\n\n    public static function getHeader()\n    {\n        return self::convertArrayToCsv(array_keys(self::getSupportedColumns()));\n    }\n\n    public static function getSupportedColumns()\n    {\n        return array(\n                '日付' =\u003E 'date',\n                '商品コード' =\u003E 'code',\n                '数量' =\u003E 'quantity'\n        );\n    }\n\n    protected static function convertArrayToCsv(array $datas)\n    {\n        $delimiter = ',';\n\n        $csv = array();\n        foreach ($datas as $data) {\n            $csv[] = '\"' . str_replace('\"', '\"\"', $data) . '\"';\n        }\n\n        return implode($delimiter, $csv);\n    }\n}\n```\n\nで、読み込むときは\n\n```php:AwesomeAction.php\n\u003C?php\n    // CSVファイルをUTF-8に変換し、テンポラリファイルに展開\n    $buffer = preg_replace(\"/\\r\\n|\\r|\\n/\", \"\\n\", mb_convert_encoding(file_get_contents($path), 'utf-8', 'SJIS-win'));\n    $fp = tmpfile();\n    fwrite($fp, $buffer);\n    rewind($fp);\n\n    // CSVファイルを読み込み\n    $header = fgetcsv($fp);\n\n    while ($line = fgetcsv($fp)) {\n        $csv = new ImportCsv();\n        $csv-\u003EsetLine($line, $header);\n\n        $ret[] = $csv;\n    }\n\n    fclose($fp);\n\n    // 取り込んだデータを利用\n    foreach ($ret as $row) {\n        var_dump($row-\u003EgetDate());\n        var_dump($row-\u003EgetCode());\n        var_dump($row-\u003EgetQuantity());\n    }\n```\n\nで、書き込むときは\n\n```php:AwesomeAction.php\n \u003C?php\n   $fp = fopen($path, 'wb');\n\n    // ヘッダを書き込む\n    fwrite($fp, ImportCsv::getHeader() . \"\\r\\n\");\n\n    // データを書き込む\n    fwrite($fp, $csv-\u003EgetLine() . \"\\r\\n\");\n```","body":"\u003Cp\u003E次のようなCSVファイルがあったとします。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E日付,商品コード,数量\n2013-08-01,12345,1\n2013-08-01,23456,2\n2013-08-02,34567,1\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003EこのファイルをPHPでいい感じに取り扱えるコードを書いてみました。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003EImportCsv.php\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"cp\"\u003E\u0026lt;?php\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eclass\u003C/span\u003E \u003Cspan class=\"nc\"\u003EImportCsv\u003C/span\u003E \n\u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eprotected\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$date\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eprotected\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$code\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eprotected\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$quantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EgetDate\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003Edate\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EsetDate\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$date\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003Edate\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$date\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EgetCode\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003Ecode\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EsetCode\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$code\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003Ecode\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$code\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EgetQuantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003Equantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EsetQuantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$quantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003Equantity\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$quantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EgetLine\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$ret\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Earray\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n\n        \u003Cspan class=\"k\"\u003Eforeach\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eself\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetSupportedColumns\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E \u003Cspan class=\"k\"\u003Eas\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$columnName\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"nv\"\u003E$ret\u003C/span\u003E\u003Cspan class=\"p\"\u003E[]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"o\"\u003E!\u003C/span\u003E\u003Cspan class=\"nb\"\u003Eis_null\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$columnName\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E?\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$columnName\u003C/span\u003E \u003Cspan class=\"o\"\u003E:\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eself\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EconvertArrayToCsv\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$ret\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EsetLine\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$line\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$layout\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Enull\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$columns\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eself\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetSupportedColumns\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n\n        \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Eis_null\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$layout\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"nv\"\u003E$layout\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eself\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetHeader\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n        \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Ecount\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$line\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E!==\u003C/span\u003E \u003Cspan class=\"nb\"\u003Ecount\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$layout\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"k\"\u003Ethrow\u003C/span\u003E \u003Cspan class=\"k\"\u003Enew\u003C/span\u003E \u003Cspan class=\"nx\"\u003E\\InvalidArgumentException\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;Invalid CSV layout is given\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n        \u003Cspan class=\"k\"\u003Eforeach\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$layout\u003C/span\u003E \u003Cspan class=\"k\"\u003Eas\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$key\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$column\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Earray_key_exists\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$column\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$columns\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n                \u003Cspan class=\"nv\"\u003E$property\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$columns\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$column\u003C/span\u003E\u003Cspan class=\"p\"\u003E];\u003C/span\u003E\n                \u003Cspan class=\"nv\"\u003E$this\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$property\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nx\"\u003Etrim\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$line\u003C/span\u003E\u003Cspan class=\"p\"\u003E[\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$key\u003C/span\u003E\u003Cspan class=\"p\"\u003E]);\u003C/span\u003E\n            \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Estatic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EgetHeader\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"nx\"\u003Eself\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EconvertArrayToCsv\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Earray_keys\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nx\"\u003Eself\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetSupportedColumns\u003C/span\u003E\u003Cspan class=\"p\"\u003E()));\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Epublic\u003C/span\u003E \u003Cspan class=\"k\"\u003Estatic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EgetSupportedColumns\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"k\"\u003Earray\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\n                \u003Cspan class=\"s1\"\u003E\u0026#39;日付\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;date\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E\n                \u003Cspan class=\"s1\"\u003E\u0026#39;商品コード\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;code\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E\n                \u003Cspan class=\"s1\"\u003E\u0026#39;数量\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u0026gt;\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;quantity\u0026#39;\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Eprotected\u003C/span\u003E \u003Cspan class=\"k\"\u003Estatic\u003C/span\u003E \u003Cspan class=\"k\"\u003Efunction\u003C/span\u003E \u003Cspan class=\"nf\"\u003EconvertArrayToCsv\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"k\"\u003Earray\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$datas\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$delimiter\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;,\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n\n        \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Earray\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n        \u003Cspan class=\"k\"\u003Eforeach\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$datas\u003C/span\u003E \u003Cspan class=\"k\"\u003Eas\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$data\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n            \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E\u003Cspan class=\"p\"\u003E[]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;\u0026quot;\u0026#39;\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"nb\"\u003Estr_replace\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;\u0026quot;\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;\u0026quot;\u0026quot;\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$data\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;\u0026quot;\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n        \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n        \u003Cspan class=\"k\"\u003Ereturn\u003C/span\u003E \u003Cspan class=\"nb\"\u003Eimplode\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$delimiter\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eで、読み込むときは\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003EAwesomeAction.php\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"cp\"\u003E\u0026lt;?php\u003C/span\u003E\n    \u003Cspan class=\"c1\"\u003E// CSVファイルをUTF-8に変換し、テンポラリファイルに展開\u003C/span\u003E\n    \u003Cspan class=\"nv\"\u003E$buffer\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nb\"\u003Epreg_replace\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;/\u003C/span\u003E\u003Cspan class=\"se\"\u003E\\r\\n\u003C/span\u003E\u003Cspan class=\"s2\"\u003E|\u003C/span\u003E\u003Cspan class=\"se\"\u003E\\r\u003C/span\u003E\u003Cspan class=\"s2\"\u003E|\u003C/span\u003E\u003Cspan class=\"se\"\u003E\\n\u003C/span\u003E\u003Cspan class=\"s2\"\u003E/\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;\u003C/span\u003E\u003Cspan class=\"se\"\u003E\\n\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nb\"\u003Emb_convert_encoding\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nb\"\u003Efile_get_contents\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$path\u003C/span\u003E\u003Cspan class=\"p\"\u003E),\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;utf-8\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;SJIS-win\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E));\u003C/span\u003E\n    \u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nb\"\u003Etmpfile\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n    \u003Cspan class=\"nb\"\u003Efwrite\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$buffer\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n    \u003Cspan class=\"nb\"\u003Erewind\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n    \u003Cspan class=\"c1\"\u003E// CSVファイルを読み込み\u003C/span\u003E\n    \u003Cspan class=\"nv\"\u003E$header\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nb\"\u003Efgetcsv\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n    \u003Cspan class=\"k\"\u003Ewhile\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$line\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nb\"\u003Efgetcsv\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E))\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"k\"\u003Enew\u003C/span\u003E \u003Cspan class=\"nx\"\u003EImportCsv\u003C/span\u003E\u003Cspan class=\"p\"\u003E();\u003C/span\u003E\n        \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003EsetLine\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$line\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$header\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n        \u003Cspan class=\"nv\"\u003E$ret\u003C/span\u003E\u003Cspan class=\"p\"\u003E[]\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E\u003Cspan class=\"p\"\u003E;\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\n    \u003Cspan class=\"nb\"\u003Efclose\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n    \u003Cspan class=\"c1\"\u003E// 取り込んだデータを利用\u003C/span\u003E\n    \u003Cspan class=\"k\"\u003Eforeach\u003C/span\u003E \u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$ret\u003C/span\u003E \u003Cspan class=\"k\"\u003Eas\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$row\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E\n        \u003Cspan class=\"nb\"\u003Evar_dump\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$row\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetDate\u003C/span\u003E\u003Cspan class=\"p\"\u003E());\u003C/span\u003E\n        \u003Cspan class=\"nb\"\u003Evar_dump\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$row\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetCode\u003C/span\u003E\u003Cspan class=\"p\"\u003E());\u003C/span\u003E\n        \u003Cspan class=\"nb\"\u003Evar_dump\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$row\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetQuantity\u003C/span\u003E\u003Cspan class=\"p\"\u003E());\u003C/span\u003E\n    \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eで、書き込むときは\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"code-lang\"\u003E\u003Cspan class=\"bold\"\u003EAwesomeAction.php\u003C/span\u003E\u003C/div\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"x\"\u003E \u003C/span\u003E\u003Cspan class=\"cp\"\u003E\u0026lt;?php\u003C/span\u003E\n   \u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nb\"\u003Efopen\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$path\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;wb\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n    \u003Cspan class=\"c1\"\u003E// ヘッダを書き込む\u003C/span\u003E\n    \u003Cspan class=\"nb\"\u003Efwrite\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nx\"\u003EImportCsv\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetHeader\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;\u003C/span\u003E\u003Cspan class=\"se\"\u003E\\r\\n\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\n    \u003Cspan class=\"c1\"\u003E// データを書き込む\u003C/span\u003E\n    \u003Cspan class=\"nb\"\u003Efwrite\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"nv\"\u003E$fp\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"nv\"\u003E$csv\u003C/span\u003E\u003Cspan class=\"o\"\u003E-\u0026gt;\u003C/span\u003E\u003Cspan class=\"na\"\u003EgetLine\u003C/span\u003E\u003Cspan class=\"p\"\u003E()\u003C/span\u003E \u003Cspan class=\"o\"\u003E.\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;\u003C/span\u003E\u003Cspan class=\"se\"\u003E\\r\\n\u003C/span\u003E\u003Cspan class=\"s2\"\u003E\u0026quot;\u003C/span\u003E\u003Cspan class=\"p\"\u003E);\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E"},{"id":24615,"uuid":"ab81aaa9329d745fb39f","user":{"id":6635,"url_name":"gongo@github","profile_image_url":"https://secure.gravatar.com/avatar/8519a654e3b51ef7dd19486a859ca91c?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png"},"title":"local のファイルを remote のブラウザで attach_file させるには","created_at":"2013-08-14 09:50:53 +0900","updated_at":"2013-08-14 09:50:53 +0900","created_at_in_words":"7時間前","updated_at_in_words":"7時間前","tags":[{"name":"Ruby","url_name":"ruby","icon_url":"https://s3-ap-northeast-1.amazonaws.com/qiita-tag-image/9de6a11d330f5694820082438f88ccf4a1b289b2/medium.jpg?1364837630","versions":[]},{"name":"Capybara","url_name":"capybara","icon_url":"/icons/medium/missing.png","versions":["2.1.0"]},{"name":"Selenium","url_name":"selenium","icon_url":"/icons/medium/missing.png","versions":[]},{"name":"WebDriver","url_name":"webdriver","icon_url":"/icons/medium/missing.png","versions":[]}],"stock_count":1,"stock_users":["tomiacannondale@github"],"comment_count":0,"lgtm_count":0,"url":"http://qiita.com/gongo@github/items/ab81aaa9329d745fb39f","gist_url":null,"tweet":false,"private":false,"created_at_as_seconds":1376441453,"raw_body":"## 環境想定\n\n`capybara` + `selenium-webdriver` でリモートマシンのブラウザを用いて実行しているとき\n\n※ 一応 `selenium-webdriver` は 2.34.0 で確認していますが、きっと前のバージョンでも使えると思います\n\n## 目的\n\n1. `Capybara::Node::Actions#attach_file`  でファイル添付を行いたいと考える\n\n    ```rb:\n    attach_file('import', '/home/gongo/fixtures/hoge.csv')\n    ```\n\n2. ブラウザがローカルで動いている分には問題ない。\n3. ブラウザがリモートで動いている場合に失敗する。なぜならリモートマシンに `/home/gongo/fixtures/hoge.csv` が **存在しないから**\n\n対応策としては、リモートマシンにも `/home/gongo/fixtures/hoge.csv` を配置しておけばいい。しかし……\n\n* 並列化のためリモート環境を大量に準備したい → 配置めんどい\n* もしリモート環境が Windows だったら → いちいちリモート環境に併せてパスの記述を変えたくない(`C:\\Users\\gongo\\fixtures/hoge.csv` みたいに)\n    * 実は `/path/to` 形式でもよしなにしてくれるんですかね……\n\n## 対策\n\n`Selenium::WebDriver::Driver#file_detector` を使います。\n\n```rb:\nCapybara.register_driver :remote_windows do |app|\n  # リモートマシンのブラウザを使う場合によくやる設定\n  caps = Selenium::WebDriver::Remote::Capabilities.internet_explorer\n  url  = \"http://#{host}:#{port}}/wd/hub/\"\n  opts = { desired_capabilities: caps, browser: :remote, url: url }\n  driver = Capybara::Selenium::Driver.new(app, opts)\n\n  # ここからが本題。driver を返す前に ↓ をしておく。\n  driver.browser.file_detector = lambda do |args|\n    str = args.first.to_s\n    str if File.exist? str\n  end\n\n  driver\nend\n```\n\nこの設定をすることで、 `attach_file` に指定したファイルが selenium webdriver の機能で **リモートマシンに転送** され、リモートマシンのブラウザからアクセスできるようになります。\n\n補足ですが、`lambda` の書き方的には\n\n1. まずは `attach_file` で指定されたファイルを **ローカルマシンで検索**\n2. ローカルになかった場合、今度は **リモートマシンで検索**\n3. どっちにも無かったら `raise Capybara::FileNotFound`\n\nとなります\n\n## 参考\n\n別記事でもまとめてあります。\n\nhttp://gongo.hatenablog.com/entry/2013/07/24/210526","body":"\u003Ch2\u003E\n        \u003Cspan id=\"2-1\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-1\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E環境想定\n      \u003C/h2\u003E\u003Cp\u003E\u003Ccode\u003Ecapybara\u003C/code\u003E + \u003Ccode\u003Eselenium-webdriver\u003C/code\u003E でリモートマシンのブラウザを用いて実行しているとき\u003C/p\u003E\n\u003Cp\u003E※ 一応 \u003Ccode\u003Eselenium-webdriver\u003C/code\u003E は 2.34.0 で確認していますが、きっと前のバージョンでも使えると思います\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-2\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-2\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E目的\n      \u003C/h2\u003E\n\u003Col\u003E\n\u003Cli\u003E\u003Cp\u003E\u003Ccode\u003ECapybara::Node::Actions#attach_file\u003C/code\u003E  でファイル添付を行いたいと考える\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"n\"\u003Eattach_file\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"s1\"\u003E\u0026#39;import\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"s1\"\u003E\u0026#39;/home/gongo/fixtures/hoge.csv\u0026#39;\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003Eブラウザがローカルで動いている分には問題ない。\u003C/p\u003E\u003C/li\u003E\n\u003Cli\u003E\u003Cp\u003Eブラウザがリモートで動いている場合に失敗する。なぜならリモートマシンに \u003Ccode\u003E/home/gongo/fixtures/hoge.csv\u003C/code\u003E が \u003Cstrong\u003E存在しないから\u003C/strong\u003E\u003C/p\u003E\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003E対応策としては、リモートマシンにも \u003Ccode\u003E/home/gongo/fixtures/hoge.csv\u003C/code\u003E を配置しておけばいい。しかし……\u003C/p\u003E\n\n\u003Cul\u003E\n\u003Cli\u003E並列化のためリモート環境を大量に準備したい → 配置めんどい\u003C/li\u003E\n\u003Cli\u003Eもしリモート環境が Windows だったら → いちいちリモート環境に併せてパスの記述を変えたくない(\u003Ccode\u003EC:\\Users\\gongo\\fixtures/hoge.csv\u003C/code\u003E みたいに)\n\n\u003Cul\u003E\n\u003Cli\u003E実は \u003Ccode\u003E/path/to\u003C/code\u003E 形式でもよしなにしてくれるんですかね……\u003C/li\u003E\n\u003C/ul\u003E\u003C/li\u003E\n\u003C/ul\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-3\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-3\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E対策\n      \u003C/h2\u003E\u003Cp\u003E\u003Ccode\u003ESelenium::WebDriver::Driver#file_detector\u003C/code\u003E を使います。\u003C/p\u003E\n\u003Cdiv class=\"code-frame\"\u003E\u003Cdiv class=\"highlight\"\u003E\u003Cpre\u003E\u003Cspan class=\"no\"\u003ECapybara\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eregister_driver\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:remote_windows\u003C/span\u003E \u003Cspan class=\"k\"\u003Edo\u003C/span\u003E \u003Cspan class=\"o\"\u003E|\u003C/span\u003E\u003Cspan class=\"n\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E\n  \u003Cspan class=\"c1\"\u003E# リモートマシンのブラウザを使う場合によくやる設定\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Ecaps\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"ss\"\u003ESelenium\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:WebDriver\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"ss\"\u003ERemote\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:Capabilities\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Einternet_explorer\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Eurl\u003C/span\u003E  \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"s2\"\u003E\u0026quot;http://\u003C/span\u003E\u003Cspan class=\"si\"\u003E#{\u003C/span\u003E\u003Cspan class=\"n\"\u003Ehost\u003C/span\u003E\u003Cspan class=\"si\"\u003E}\u003C/span\u003E\u003Cspan class=\"s2\"\u003E:\u003C/span\u003E\u003Cspan class=\"si\"\u003E#{\u003C/span\u003E\u003Cspan class=\"n\"\u003Eport\u003C/span\u003E\u003Cspan class=\"si\"\u003E}\u003C/span\u003E\u003Cspan class=\"s2\"\u003E}/wd/hub/\u0026quot;\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Eopts\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"p\"\u003E{\u003C/span\u003E \u003Cspan class=\"n\"\u003Edesired_capabilities\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E \u003Cspan class=\"n\"\u003Ecaps\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003Ebrowser\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E \u003Cspan class=\"ss\"\u003E:remote\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"ss\"\u003Eurl\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E \u003Cspan class=\"n\"\u003Eurl\u003C/span\u003E \u003Cspan class=\"p\"\u003E}\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Edriver\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"ss\"\u003ECapybara\u003C/span\u003E\u003Cspan class=\"p\"\u003E:\u003C/span\u003E\u003Cspan class=\"ss\"\u003E:Selenium\u003C/span\u003E\u003Cspan class=\"o\"\u003E::\u003C/span\u003E\u003Cspan class=\"no\"\u003EDriver\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Enew\u003C/span\u003E\u003Cspan class=\"p\"\u003E(\u003C/span\u003E\u003Cspan class=\"n\"\u003Eapp\u003C/span\u003E\u003Cspan class=\"p\"\u003E,\u003C/span\u003E \u003Cspan class=\"n\"\u003Eopts\u003C/span\u003E\u003Cspan class=\"p\"\u003E)\u003C/span\u003E\n\n  \u003Cspan class=\"c1\"\u003E# ここからが本題。driver を返す前に ↓ をしておく。\u003C/span\u003E\n  \u003Cspan class=\"n\"\u003Edriver\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Ebrowser\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Efile_detector\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"nb\"\u003Elambda\u003C/span\u003E \u003Cspan class=\"k\"\u003Edo\u003C/span\u003E \u003Cspan class=\"o\"\u003E|\u003C/span\u003E\u003Cspan class=\"n\"\u003Eargs\u003C/span\u003E\u003Cspan class=\"o\"\u003E|\u003C/span\u003E\n    \u003Cspan class=\"n\"\u003Estr\u003C/span\u003E \u003Cspan class=\"o\"\u003E=\u003C/span\u003E \u003Cspan class=\"n\"\u003Eargs\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Efirst\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eto_s\u003C/span\u003E\n    \u003Cspan class=\"n\"\u003Estr\u003C/span\u003E \u003Cspan class=\"k\"\u003Eif\u003C/span\u003E \u003Cspan class=\"no\"\u003EFile\u003C/span\u003E\u003Cspan class=\"o\"\u003E.\u003C/span\u003E\u003Cspan class=\"n\"\u003Eexist?\u003C/span\u003E \u003Cspan class=\"n\"\u003Estr\u003C/span\u003E\n  \u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\n  \u003Cspan class=\"n\"\u003Edriver\u003C/span\u003E\n\u003Cspan class=\"k\"\u003Eend\u003C/span\u003E\n\u003C/pre\u003E\u003C/div\u003E\u003C/div\u003E\u003Cp\u003Eこの設定をすることで、 \u003Ccode\u003Eattach_file\u003C/code\u003E に指定したファイルが selenium webdriver の機能で \u003Cstrong\u003Eリモートマシンに転送\u003C/strong\u003E され、リモートマシンのブラウザからアクセスできるようになります。\u003C/p\u003E\n\u003Cp\u003E補足ですが、\u003Ccode\u003Elambda\u003C/code\u003E の書き方的には\u003C/p\u003E\n\n\u003Col\u003E\n\u003Cli\u003Eまずは \u003Ccode\u003Eattach_file\u003C/code\u003E で指定されたファイルを \u003Cstrong\u003Eローカルマシンで検索\u003C/strong\u003E\u003C/li\u003E\n\u003Cli\u003Eローカルになかった場合、今度は \u003Cstrong\u003Eリモートマシンで検索\u003C/strong\u003E\u003C/li\u003E\n\u003Cli\u003Eどっちにも無かったら \u003Ccode\u003Eraise Capybara::FileNotFound\u003C/code\u003E\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003Eとなります\u003C/p\u003E\n\u003Ch2\u003E\n        \u003Cspan id=\"2-4\" class=\"fragment\"\u003E\u003C/span\u003E\n        \u003Ca href=\"#2-4\"\u003E\u003Ci class=\"icon-link\"\u003E\u003C/i\u003E\u003C/a\u003E参考\n      \u003C/h2\u003E\u003Cp\u003E別記事でもまとめてあります。\u003C/p\u003E\n\u003Cp\u003E\u003Ca href=\"http://gongo.hatenablog.com/entry/2013/07/24/210526\" title=\"http://gongo.hatenablog.com/entry/2013/07/24/210526\" target=\"_blank\"\u003Ehttp://gongo.hatenablog.com/entry/2013/07/24/210526\u003C/a\u003E\u003C/p\u003E\n"}]