終電23時15分って早くね?

都内のIT企業で働くカラオケ大好きエンジニアの雑記

PHPerKaigi2019にスポンサーとして参加してきた

PHPerKaigi 2019に株式会社オウケイウェイヴとしてランチスポンサーをさせていただき、ランチセッションに登壇させていただきました!

f:id:blue_goheimochi:20190330122413j:plain

ランチセッション

PHPerKaigi 2019の他のスピーカーさんのセッションにおいては技術トークが大半だったかなーと思いますが、スポンサーセッションであることを存分に利用させていただきまして、会社の紹介や文化を絡めた内容で発表させていただきました。

スライド


動画


当日の様子

お弁当 - トンポー蒸籠

当日はトンポー蒸籠というお弁当を用意させていただきました!
Twitterの反応をみるによい反応をいただいたようでよかったです。
このトンポー蒸籠ですが、ランチの時間帯になると株式会社オウケイウェイヴの近くにケータリングカーがきてくれて、わたしも週1回は食べているお弁当です。
普通(?)であればスタッフさんがいい感じのお弁当を選定してくれるのかな?と思うのですが、今回、「スポンサーするならどうしてもこのお弁当を出したい!」との弊社人事の強い希望があり&わたし自身がスタッフもさせていただいていたこともあり、実現させていただきました。

余談ですが、このめちゃめちゃ美味しいトンポー蒸籠ですがWebの注文フォームなどが見当たらず、直接ケータリングカーのところに行って「大量のお弁当って用意してもらったりするの可能ですかね?」っと交渉させていただいてOKをいただきました!w
実際、羽田空港などにも出店されているようでして、機会がありましたらぜひまた食べてみてください。オウケイウェイヴに入社していただければいつでも食べれます!

セッション内容

Twitterでだいぶいい感じに要約してツイートしていたいだいて、こういう感じのことをお話しさせていただきました。

株式会社オウケイウェイヴクレドには「Take Off The Colored Glasses(色眼鏡を外そう)」という内容が含まれています。

自分のかけている「色眼鏡」を外して、他の人と同じ「色眼鏡」を選んで掛け直す。

「色眼鏡」と聞くと、ネガティブな印象がかなり強いような気がしていて、「色眼鏡」を外してまたかけるというのは、「偏見」をみずからあらためて持ち込むというように捕らえられてしまうかな?という部分があるのですが、
オウケイウェイヴでは「色眼鏡」≒「認知フレーム」というような理解を持った上でコミュニケーションを取っており、チームメンバー同士で常に「リフレーミング」をしながら、「共通認識」を作っていくというのがその意味となっています。

初見ですと「む?」っと思ってしまいそうな言い回しかなぁと思いますが、株式会社オウケイウェイヴの文化の一つであるこのクレドを丁寧に説明してみなさんに伝えてみたいなぁと思ったのがこのセッションの目的でした。

「チームが機能するにはどういうことか」「エンジニアリング組織論への招待」における「認知フレーム」の説明を引用させていただきながら、話させていただいたのですが、少しでもこの文化やいいコミュニケーションを行っていそうだな〜というのが伝わっていたら嬉しいです。

Togetterまとめ

togetter.com

まとめ

今回、株式会社オウケイウェイヴはカンファレンススポンサー自体がはじめてでして、会社としても新しいチャレンジができたのかなぁと思っています。今後もスポンサーとして技術コミュニティを支援していければ・・・というのがわたしの思いです!

株式会社オウケイウェイヴは、

  • ブルーマンデー対策として月曜午前中が休み!
  • Barスペースがあり世界のビールが常備されていて、飲み放題!

の会社です。

この記事やランチセッションなどを通じて、もし弊社に「興味が湧いた!」というようなことがあればぜひぜひお声がけいただければと思います!

PHPerKaigi2019にコアスタッフとして参加してきた

f:id:blue_goheimochi:20190330150446j:plain

PHPerKaigi 2019にコアスタッフとして参加してました!最高でしたーー!

今回はTrack Cのリーダーをやらせていただいて、ほぼほぼTrack Cにいました。
リーダーというすごい肩書きをいただきましたが、事前のMTGから当日のTrack C設営・運用まで、一緒にTrack Cの担当をしていただいたスタッフさんはもちろん、全てのスタッフの方々に助けていただいて、なんとか無事にカンファレンス終了まで頑張れたかなぁ・・と思います・・!
ありがとうございました!!!

ちょっと工夫したかな?というTrack Cのレイアウト

Track Cの入り口に立った時に、IRT・アンカンファレンスで何をやっているか?
が分かるように、IRTのホワイトボードとアンカンファレンスのスクリーンに角度をつけてみました。

これは設営中になんとなく閃いたことだったんですが、IRTやアンカンファレンス開催時によりやっている感がみえるかなぁーと思ってやってみました。みなさんどう感じていたんだろーと思ってはいるのですが、個人的にはみやすいぞっと思って勝手に満足していますw

この辺りはまた来年チャンスがあれば色々やってみたいでっす!

音響・映像がすごい!

rela1470.hatenablog.jp

音響と映像がすごくてすごかった!(語彙力

詳細は上記の @rela1470 さんのブログを参照いただければと思うのですが、これはやばいです。
(わたしは何も頑張ってないんですが・・!)

Track Cにほとんどいたので、残念ながらセッションはほとんど聞けなかったのですが、後から上がってきた動画をみさせていただいて、本当にすごいのでぜひPHPerKaigi 2019に参加できなかった方や裏のセッションも聞きたかった!という方や復習でもう1回見るぞ!って方もうみなさんぜひみてください。

とても見やすいしすごい没入感を感じられるのでとっても集中して動画が見れます!(当社比

ランチセッション

実はランチスポンサーをさせていただき、ランチセッションなんかもさせていただきました。それは別途書こうかな・・・たぶん・・・と思います。

去年と比べてどうだった?

blue-goheimochi.hatenablog.com

実は去年のPHPerKaigi 2018が初めてのスタッフだったので、とても思い入れのあるカンファレンスです。

主体的に動けずあまり役に立たなくてとても申し訳ない気持ちでいっぱいです。。

と去年のブログには書いてあって、ちょっと引きずっている部分もあったので、今回はなるべく主体的に・・ということでできるか分からないと思いつつ思い切ってTrack Cのリーダーに手をあげたり、お弁当の手配とかしたり、去年よりは頑張れたな?と思っています。

また去年もですが今年も、スタッフをしたことで新しい出会いとか繋がりが生まれてとてもよかったなぁと思っています!

まとめ

今年の反省点としてはブログをシュッと書かなかったことです・・・。
疲れたので落ち着いてから書こう・・・と思っていたら、こんなに間が空いてしまってなんかちょっと熱量が足りない感じに・・・なんか書き足りていないこともある気がする・・・・(去年の方がちゃんと書いてる気が)
来年はシュッと書くぞ・・・!

ということで、来年もスタッフできるといいな!

参加者のみなさま、スピーカーのみなさま、スポンサーのみなさま、スタッフのみなさま、本当にありがとうございました!!
また来年よろしくお願いいたします!

「PHPフレームワーク Laravel Webアプリケーション開発」を読めば開発現場で使える「ヒント」を見つけられる

今回、レビュワーをさせていただくというありがたい経験をさせていただきました!ありがとうございます。
見本誌を頂戴いたしましたので、感想を書いていきたいと思います。

f:id:blue_goheimochi:20180926182634j:plain
PHPフレームワーク Laravel Webアプリケーション開発

初心者から1歩踏み出したい!という人にはぴったりの本

とのっけから、「初心者にはちょっと・・・」というような見出しになってしまいましたが、先にそれを否定しておきます。

初心者を完全に置き去りにしているのか?というとそんなことは全くなく、「第1部 Laravelの基礎 Chapter1 Laravelの概要」ではLaravelとはどんなフレームワークか?というところからはじまり、開発環境の構築、初めてのアプリケーション作成(ルーティング、ビューの設定、ログイン認証、テストコード、マイグレーション、イベント)と1つ1つ進めていけば「Laravelってこんな感じなのねー」というのを理解しながら読み進めていけるのではないかな?と思います。
Chapter1でいったん、全体感を掴んだあとに「Chapter2 Laravelアーキテクチャ」で実際に手を動かした内容を踏まえながら、「Laravelはこう動いているんだよ」というのをさらに深く学んでいくというような構成になっているので、初心者の方でも順を追ってLaravelを学んでいくことができると思います。

初心者から1歩踏み出す

ある程度、「もうLaravelを使っているよ!」という人は、「Chapter3 アプリケーションアーキテクチャ」から読み始めるとよいのかなと思っています。
この章では、まずMVCADR(Action Domain Responder)というアプリケーション開発をする時にとりいれるパターンを対比させながらどのように責務を分けると、よりよいアプリケーションになるのか?というヒントを示してくれます。

そこからさらに、レイヤードアーキテクチャリポジトリパターン、ドメイン駆動設計などのエッセンスに触れながら、実際、どういうパターンが良い・悪いというような話ではなく、ご自身の現場で立ち向かっているアプリケーションの規模の大小や開発チームの人数、開発期間などを考えながら「このアプリケーションにとってどういう設計が望ましいのか?」というのをご自身で考えるときの指針・ヒントとして活用できるような内容になっていると思います。

全3部の構成になっている

  • 第1部 Laravelの基礎
  • 第2部 実践パターン
  • 第3部 Laravelアプリケーション開発手法

の構成になっており、前述の部分は第1部の内容にあたります。

第2部 実践パターン

第1部だけでも、かなり実践的にアプリケーション設計についてどう考えるのかということを学べるなぁという印象なのですが、第2部ではLaravelで標準で使えるような基本的なことはもちろんですがさらに、

  • Chapter5 データベース
  • Chapter6 認証と認可
    • JWT認証、OAuthクライアントによる認証・認可
  • Chapter7 処理の分離
    • イベント、キュー、CQRS
  • Chapter9 テスト

のように、一部の抜粋ではありますが、それぞれのChapterでLaravelをさらに1歩進んで使うためのヒントが散りばめられています。

第3部 Laravelアプリケーション開発手法

Chapter11 テスト駆動開発の実践」では、第1部、第2部で学んだことを、モバイルアプリケーションをTDDで実装するというお題になっていて、小さいコードからリファクタリングを進めながら徐々にアプリケーションを構築していくというフローを体験していくことができます。
本当に丁寧に1つ1つ進んでいくので、実際の業務に活かすイメージをもって読み進められるのではないかなと思いますので、ぜひ読みながら一緒に手を動かしてみて欲しいです!

まとめ

と、なんとまぁまとまりがありませんが、初心者の方もステップアップしながら読めると思いますし、 初心者から1歩踏み出したいという方にはヒントがたくさん散りばめられていて新しい発見をすることができるのではないかな思います。

Laravelでアプリケーション開発を実践されている皆さまには当然オススメしたい本であるとともに、別のフレームワークを使っているよという皆様であっても、何かステップアップのためのヒントになることがあるのではないかなーと思いますので、ぜひ読んでみていただきたいです!

PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応

おまけ

f:id:blue_goheimochi:20180926182656j:plain
vs エリック・エヴァンスのドメイン駆動設計

めっちゃ厚い!

PHPerKaigi 2018に前々夜祭から参加して最高でした

f:id:blue_goheimochi:20180309144131j:plain

phperkaigi.jp

最高&最高でした!(当社比1.5倍)
自身初のスタッフとしての参加でした。
せっかくなので、どうしてスタッフ参加したの?というところまでさかのぼって雑に書き残しておきたいなーと思ったので雑に書いていきたいと思います。

PHPerKaigiのスタッフやりたいです!と言った日

2017年10月25日のPHP勉強会で @tomzoh さんが「PHPerKaigiやるよ!」という発表をしていた日がその日でした。

speakerdeck.com

実はそのちょっと前に「何かPHPのカンファレンス的なのをやるらしい」というのを他の方から聞いていて、
「次のPHP勉強会で声かけよう・・・!」と思っていたのもあり、PHP勉強会に参加&突撃して @tomzoh さんに声をかけさせてもらったという次第です。実際は、PHP勉強会の懇親会中には声をかけられず(ビビッて)2次会のグリフォンで話しかけました。

ほんとにすごく緊張してて、なんて声かけたかは完全に忘れましたが、
この1歩がなかったら、「最高だった!」と思えてないんじゃないかなと考えると大きな1歩だった気がします。

スタッフをやりたいと思ったきっかけ

@shin1x1 さんのPodcastPHPの現場」の「12. カンファレンスの現場(tomzoh / cakephper)」を聞いたあとに無性に「やってみたいぞー」ってなりました。
Podcastではカンファレンスに一般・スピーカー・スタッフ(実行委員長)として参加されたことのあるお三方が、参加する側・主催する側の話などの色々な視点からカンファレンスについてお話しているのが印象的ですごく面白く聞いていて、主催側楽しそうだ・・とだんだんと(何回も聞くうちに)気持ちが高まっていったのですが、そんな中でも印象に残っていたのが @cakephper さんが懇親会における自分ルールとして「懇親会で1人になっている人に話しかけに行く」というのを挙げていたところでした。

Podcastの中で「誰かと話して帰ったほうが満足度は高い!大人なんだから自分から(話しかけて)楽しまなきゃ!」という話もあったのですが、自分自身が懇親会などでボッチになってしまった経験がある(大人なのに!)ので、なるほど、そういうとき話しかけられたとしたら自分ならうれしい(しホッとする)なと思っていました。

「懇親会にきてる人は、喋りたいと少しは思っている人」という話もされていて、そう話したいんだけどビビってしまうんです・・・とも思っていましたw

でもその @cakephper さんメソッドを使って少しでも自分のようなになってしまう人が少なくなって、「楽しかった!」って帰る人が増やせるかもと思ったのがスタッフやりたいなと思った一番の理由だった気がします。
(なんと前述のグリフォンには @cakephper さんもいらっしゃって勝手にうおおーってなってました)

まだ聞いていない方はぜひ聞いてみてください!
と、どうやら「PHPerKaigi の現場」というのが新たに収録されるとのこと!楽しみ。

blog.shin1x1.com

[追記:2018-03-27]
「PHPerKaigi の現場」の収録が公開されました!!

前回のと合わせて聞くと1.5倍(当社比)面白いと思うのでまだの方はぜひです!

開催までの間スタッフとしてどんなことをやった??

実は何回か行われたスタッフMTGのうち1回しか参加できませんでした・・・。(12月中旬頃にあった初回MTGにも参加できず)
乗り遅れてしまったのと、自分のチキンさがあいまって、主体的に動けずあまり役に立たなくてとても申し訳ない気持ちでいっぱいです。。
少しでも何かやらねば・・・ということで、前々夜祭で宣伝をさせていただいたのですが、それが唯一のやれたことかなと(勝手に)思っています。

PHPerKaigi 前々夜祭(非公式)

laravel-meetup-tokyo.connpass.com

ということで、宣伝をしたのが「Laravel Meetup Tokyo vol.10」でした。
非公式ですが、「Laravel MeetUp Tokyo PHPerKaigi 前々夜祭バージョン!」ということで開催されていました。

そこでLTの3番手で宣伝をしてきました!
内容としては2017年7月に「Laravel Meetup Tokyo vol.9」で発表した内容の振り返りと現状がどうなっているか?のような発表だったのですが、

ということで、この宣伝の効果があったのかどうか定かではないですが、「ちゃんと仕事したー!」というのを勝手に自分に言い聞かせながら当日を迎えることになります。(もし、このLTで行くことを決めた方がいらっしゃったら教えてくださいw)

PHPerKaigi 前夜祭

ドキドキしながらCoconeriホールに向かい、会場準備したり受け付け準備したり荷物が届いたり袋詰めしたりビデオの準備したり、何もかもがはじめての私は右往左往しながら、みなさんの動きにがんばってついていくという感じでした。
他のスタッフの方は別のカンファレンススタッフもしたことがある人が多いようでとてもテキパキとあっという間に会場が出来上がって行きました!すごかった。

袋詰めがホントに高速でした。

前夜祭はTrack A以外の場所にいた感じだったのでトークは聞けなかったのですが、QRコードをスキャンしたり、バドワイザーを飲んだり、Track Bの準備をしたり、ソフトドリンクを買いに行ったり、バドワイザーを飲んだりしていました。

あっという間にクロージングとなり、少し片付けをしてから PHPreParty へ移動しました。

PHPerKaigi 前夜祭終了後に・・・

参加者のみなさんのお見送り最中に、1人の方が名札を見せながら近づいてこられて、「明日名札どうするか聞かれるのかな?」とか思ったのですが、そうではありませでんした・・!なぜ話しかけてくれたか?なんですが、なんと「PHPerKaigi 前々夜祭」の発表(宣伝)を見ていただいたからだったんです。

すごい。めちゃくちゃにうれしい瞬間でした。
スタッフをされていた @uzulla さんもおっしゃっているのですが、

トーク以外の所について言えば、アイコンつきの名札はとてもいいですね、話している相手が誰なのかわかる。

PHPerKaigi 2018に行ってきた、やってきた、話してきた #phperkaigi - uzullaがブログ

をまさに体感した瞬間でした。
もしアイコンが印刷されていなかったとしたら、見つけていただけなかったかもしれないし、自分からも見つけられなかったのかもしれないなぁーと。本当によかった!
@kunit さんとはほとんどお話はできなかったのでどこかでお話せねば)

PHPerKaigi 本編

前日、寝る前にTwitterで前夜祭のTLをニヤニヤしながら読んでいたのですが、寝落ちしていて、パッと起きてスマホ見たら電源が切れていて、「えっ・・・」と思って時計を確認したらまだ大丈夫な時間・・・セーフ・・!という目覚めから1日がスタート。

この日の前半はQRコードスキャン業を行い、受付縮小に伴い、Track BのLaravel相談会をがっつり覗き込んだり、IRTに人が多くなってきたので椅子を運んだりなどをしていた。
Track Bの雰囲気はすごく良かった気がします!後半はTrack Aで質問マイクを持っていく職人をしていました。
ランチタイムセッションのあとは急にTrack Aの温度が上がるのを感じで「人間ごはんを食べると発熱するんだなぁ」とか意味わからないことを考えながら空調の調整ボタンを押したりしていた。

少しだけ聞けた発表の中では、

speakerdeck.com

BEAR.Sunday 作者の @koriym さんが発表の中で言っていた、

がとても心に残っています。

あとは漢の中の漢にいつかなりたい。(Hack)

少しTrack Bの片付けをしてあっという間にLTがはじまりあっという間に終わり。すごい熱量。

「Lumenで堅牢なAPIを設計する」の えんどぅーさん(@Fendo181)の落ちが面白すぎました!

PHPerKaigi 懇親会

ついに懇親会! @cakephper さんメソッドを使いました!!
緊張しすぎててどなたと喋ったかが分からない・・・のですが、ボッチ(になっていたのかは定かではないのですが)お一人でいた方に突撃して話しました!きっと少しは楽しんでいただけたのではないだろうか・・
もしかしたらほかにもお一人だったかたがいたのかな・・・

鞠花がおいしかったりハンバーガーがおいしかったり、ロゴの秘密が明かされたりとまたあっという間に過ぎていきました。
ものすごい余韻を残しつつの終了。

PHPostParty

懇親会のあとさらに池袋に移動し、最後のワイワイ。
そーだいさん(@soudai1025)さんとチームの文化作り的な話をさせていただいたのがとても心に残っていて、
「1人~2人で社内勉強会とか何かしら行動に移すと、ポツポツと人が増えてきて、どこかのタイミングで急にブレイクスルーがくるんですよね〜」というようなことをおっしゃっていました。
これは前々夜祭で発表した部分にもつながってるなと思ったのですが、「なるほどやっぱりまだまだ自分は頑張りが足らないのかもなー!」と感じました。ブレイクスルーがくるまで頑張らねば。

まとめ?

ものすごく雑に脈絡なく思ったことやあった出来事を書くだけになってしまったのですが、わたしのPHPerKaigi 2018はこんな感じで個人的にはものすごく最高&最高でした。

スタッフをやらせていただいたおかげで体験できたことが、たくさんあったということは間違いないと思います!!いろいろ感じたこと学んだことをこれからに活かしていきたい!

そして振り返ってみるとやはり1番最初の1歩がなかったらこんなに最高に思えなかったかなと思うので、スピーカーでもスタッフでも懇親会で一声かけるでも、仕事で何かやってみるとかでも、新しい趣味に挑戦しようでも、もし何かを「ちょっとやってみようかな」と思っている人がいたら1歩踏み出してみるのがよいのかなと思います!
来年もスタッフできるといいな!

参加者のみなさま、スピーカーのみなさま、スポンサーのみなさま、スタッフのみなさま、本当にありがとうございました!!
また来年よろしくお願いいたします!

PHP CodeSnifferでtestsディレクトリにだけ除外ルールを追加する

最近はPSR-2の規約に沿ってコードを書くことを意識しています。

www.php-fig.org

特にチームで開発している状況でコーディングスタイルのルールが明確に決まってないと、
A「インデントはスペース2つ!」
B「いや、スペース4つ!!」
C「タブやろ」
みたいな細かい話になりがちだと思います。
(PSR-2ではスペース4つのルール)

そんなときにPSR-2のようなコーディングスタイルガイドに寄り添っていくのはとてもいいなーと感じています。
(自分が今まで書いてきたルールと違う部分は慣れるまでちょっと気持ち悪いですが)

なぜtestsディレクトリだけに除外ルールを追加したかったか?

プロジェクトのコード全体をPSR-2に沿って書くようにしてたなかで、
テストを書く際に2つ困ったことがあったからです。

  • テスト名を日本語にした場合にエラーになる
  • 抽象クラス(abstract)のテストの場合にエラーになる

テスト名を日本語にした場合にエラーになる

PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
----------------------------------------------------------------------
SOURCE                                                           COUNT
----------------------------------------------------------------------
PSR1.Methods.CamelCapsMethodName.NotCamelCaps                    9
----------------------------------------------------------------------
A TOTAL OF 9 SNIFF VIOLATIONS WERE FOUND IN 1 SOURCE
----------------------------------------------------------------------

「メソッドがキャメルケースではないよ!」というエラーになります。

/**
 * @test
 */
public function 保存ができること()
{
    $this->todo->addItem('アイテム1');
    $this->assertTrue($this->todo->save());
}

public function test取得ができること()
{
    $this->todo->addItem('アイテム1');
    $this->assertTrue($this->todo->save());
}

PHP@testアノテーションをつけることで、日本語だけの関数名でテストを書けます。
(下のようにtestをプレフィックスにつけても日本語で書けます。)

日本語なのでエラーになるのは当然ですね。
英語が苦手なメンバーがいたり、日本語のほうがテスト内容が分かりやすかったりはするのでたまに日本語でテストを書いたりしています。

でもアプリケーションのコードでは関数は日本語で書いていない。
全体の除外ルールとしてしまうこともできますが、アプリケーションのコードのほうで、もしキャメルケースで書かれていない場合はエラーとして拾えなくなってしまいます。

抽象クラス(abstract)のテストの場合にエラーになる

PHP CODE SNIFFER VIOLATION SOURCE SUMMARY
----------------------------------------------------------------------
SOURCE                                                           COUNT
----------------------------------------------------------------------
PSR1.Classes.ClassDeclaration.MultipleClasses                    2
----------------------------------------------------------------------
A TOTAL OF 2 SNIFF VIOLATIONS WERE FOUND IN 1 SOURCE
----------------------------------------------------------------------

「1つのファイルに複数クラスの定義があるよ!」というエラーになります。

抽象クラスのテストをしたいときは、テストのクラスのなかにもう1つクラスを書いています。

class FugaTest extends \PHPUnit\Framework\TestCase
{
    public function testReturnFuga()
    {
        $fuga = new Fuga();
        $this->assertSame('fuga', $fuga->get());
    }
}

class Fuga extends Hoge
{
}

めちゃくちゃ適当ですがこんな感じ。

2つのルールをtestsディレクトリで除外するphpcs.xmlの書き方

PSR1.Methods.CamelCapsMethodName.NotCamelCaps
PSR1.Classes.ClassDeclaration.MultipleClasses

この2つのルールをtestsディレクトリ以下のみ除外するには下記のように設定すればOKでした。

<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
    <exclude-pattern>*/tests/*</exclude-pattern>
</rule>
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
    <exclude-pattern>*/tests/*</exclude-pattern>
</rule>

それぞれのルールに対して除外ディレクトリを設定してあげればOKです。
全体としてはこんな感じ。

<?xml version="1.0"?>
<ruleset name="Custom_PSR2">
  <description>Custom ruleset Based on PSR2</description>
  <exclude-pattern>*/vendor/*</exclude-pattern>
  <exclude-pattern>*/bootstrap/cache/*</exclude-pattern>
  <exclude-pattern>*/database/*</exclude-pattern>
  <exclude-pattern>*/node_modules/*</exclude-pattern>
  <exclude-pattern>*/public/*</exclude-pattern>
  <exclude-pattern>*/resources/*</exclude-pattern>
  <exclude-pattern>*/storage/*</exclude-pattern>
  <rule ref="PSR2">
    <exclude name="Generic.Files.LineLength.TooLong" />
  </rule>
  <rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
    <exclude-pattern>*/tests/*</exclude-pattern>
  </rule>
  <rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
    <exclude-pattern>*/tests/*</exclude-pattern>
  </rule>
</ruleset>

※メソッド名が長くなりがちなので全体のルールにGeneric.Files.LineLength.TooLongも設定してます

ちょっと場所が分かりづらいですが、PHP CodeSnifferのWikiにこのやり方で書いてあります。
github.com

MySQL5.5.6(以下?)でSupersetがうまく動かない(場合がある)

f:id:blue_goheimochi:20170210100609p:plain

AirbnbによるオープンソースのBIツールのSuperset

github.com

Re:dashもちょろちょろ触っているのですが、
ダッシュボードのカスタマイズが柔軟そうだなー
と思いSupersetの環境を作ってみたのですがデモは動くんだけど、
手元のDBに接続してみるとうまくいかない・・・となりました。

原因

おそらくMySQL5.5.6(以下?)で発生するSTR_TO_DATEをWHERE句に使うことによるバグ。
MySQL Bugs: #56271: STR_TO_DATE in date compare incorrect results

Supersetが内部でdateのフォーマットを整形した形でSQLを発行しているのですが、
その部分でSTR_TO_DATEが使われているためだと思われます。

if target_type.upper() in ('DATETIME', 'DATE'):
    return "STR_TO_DATE('{}', '%Y-%m-%d %H:%i:%s')".format(
        dttm.strftime('%Y-%m-%d %H:%M:%S'))
return "'{}'".format(dttm.strftime('%Y-%m-%d %H:%M:%S'))

superset/db_engine_specs.py at 37fb56c61ceb339079ff117971fc91bdd678db80 · airbnb/superset · GitHub
ifの条件にはまらなければ(DATETIME、DATEのカラムじゃなければ)大丈夫なのかな。

どんなSQLが発行されるか?

こんな。

mysql> SELECT COUNT(*) AS count
    -> FROM items
    -> WHERE created_at >= STR_TO_DATE('2000-01-01 00:00:00', '%Y-%m-%d %H:%i:%s')
    -> AND created_at <= STR_TO_DATE('2017-12-31 23:59:59', '%Y-%m-%d %H:%i:%s');

一見正しそうに見える。

STR_TO_DATEの結果

mysql> SELECT STR_TO_DATE('2000-01-01 00:00:00', '%Y-%m-%d %H:%i:%s');
+---------------------------------------------------------+
| STR_TO_DATE('2000-01-01 00:00:00', '%Y-%m-%d %H:%i:%s') |
+---------------------------------------------------------+
| 2000-01-01 00:00:00                                     |
+---------------------------------------------------------+

mysql> SELECT STR_TO_DATE('2017-12-31 23:59:59', '%Y-%m-%d %H:%i:%s');
+---------------------------------------------------------+
| STR_TO_DATE('2017-12-31 23:59:59', '%Y-%m-%d %H:%i:%s') |
+---------------------------------------------------------+
| 2017-12-31 23:59:59                                     |
+---------------------------------------------------------+

たぶん大丈夫。

SQLの結果

mysql> SELECT COUNT(*) AS count
    -> FROM items
    -> WHERE created_at >= STR_TO_DATE('2000-01-01 00:00:00', '%Y-%m-%d %H:%i:%s')
    -> AND created_at <= STR_TO_DATE('2017-12-31 23:59:59', '%Y-%m-%d %H:%i:%s');
+-------+
| count |
+-------+
|     0 |
+-------+

0件・・・・・

STR_TO_DATEを使わないで直接指定してみる

mysql> SELECT COUNT(*) AS count
    -> FROM items
    -> WHERE created_at >= '2000-01-01 00:00:00'
    -> AND created_at <= '2017-12-31 23:59:59';
+-------+
| count |
+-------+
|   999 |
+-------+

カウントがちゃんと取れる・・・・。

MySQLのバージョン確認

mysql> SELECT version();
+--------------+
| version()    |
+--------------+
| 5.5.6-rc-log |
+--------------+

MySQLの別のバージョンで試す

mysql> SELECT version();
+-------------------+
| version()         |
+-------------------+
| 5.7.12-0ubuntu1.1 |
+-------------------+

mysql> SELECT COUNT(*) AS count
    -> FROM items
    -> WHERE created_at >= STR_TO_DATE('2000-01-01 00:00:00', '%Y-%m-%d %H:%i:%s')
    -> AND created_at <= STR_TO_DATE('2017-12-31 23:59:59', '%Y-%m-%d %H:%i:%s');
+-------+
| count |
+-------+
|   999 |
+-------+

>|abc|
mysql> SELECT COUNT(*) AS count
    -> FROM items
    -> WHERE created_at >= '2000-01-01 00:00:00'
    -> AND created_at <= '2017-12-31 23:59:59';
+-------+
| count |
+-------+
|   999 |
+-------+

どっちも取れる・・・!!!!

MySQLのリリースノートをあさったり

MySQL 5.5 Release Notes

MySQL Bugs: #56271: STR_TO_DATE in date compare incorrect results
これだ!

51 Changes in MySQL 5.5.7 (2010-10-14, Release Candidate)

Comparison of one STR_TO_DATE() result with another could return incorrect results. (Bug #56271)

5.5.7で直ったっぽい!!!!

まとめ

ということで、5.5.7以上を使っていればたぶん大丈夫だと思われます。
5.5.6以下でもうまく行くケースはたぶんある。(TIMESTAMPとかのカラムをTime Columnに設定すればたぶん大丈夫)
strftimeで変換したあともう一度STR_TO_DATEする必要あるのか・・な・・?

【Laravel Practice04】AnsibleでNTPサーバーを構築

f:id:blue_goheimochi:20160629162151p:plain

デプロイサーバーにNTPサーバーをAnsibleで構築してみます。
今回、仮想環境にはCentOS7を使っているので、chronyをインストールしてみます。

ntpdとchronyの違い

CentOS6まではデフォルトのNTPサーバーはntpdだったようですが、
CentOS7ではchronyが標準となっているようです。

大きな違いとしては

ntpd と chronyd の大きな違いの 1 つは、コンピューターのクロックを管理するために使われるアルゴリズムにあります。

とのことで、システムクロックをntpdより迅速に調整することが可能らしいです。

[参考]
第15章 chrony スイートを使用した NTP 設定

yumモジュールでchronyをインストール

今回作業したところは、以下のコミットログにまとまっていますのでご参照ください。
github.com
今回は、ansible/roles/chrony/tasks/main.ymlの1ファイルのみ追加しています。

- name: install chrony
  yum: name=chrony state=latest

Ansibleのyumモジュールでchronyをインストールする際の記述です。

$ sudo yum install -y chrony

と同等の処理が行われます。

Ansible yumモジュールのドキュメント
yum - Manages packages with the yum package manager — Ansible Documentation

他のパッケージをインストールしたい場合は、
たとえばhttpdであれば

- name: install httpd
  yum: name=httpd state=latest

と書けばOKです!簡単ですね。

デフォルトで設定されているNTPサーバーを無効にする

デフォルトで設定されているNTPサーバーを無効にします。
pool.ntp.orgのサーバーは世界中すべてのタイムサーバーを指定しているそうで、
時刻を精度よく保つためには近いゾーンのものを設定するのがよいみたい。
(あとで設定します)

[参考]
pool.ntp.org: プールを利用するためにNTPを設定する方法は?

chronyの設定ファイルは/etc/chrony.confに作成されていると思うので、これを今回はAnsibleのreplaceモジュールで操作してみます。

Ansible replaceモジュールのドキュメント
replace - Replace all instances of a particular string in a file using a back-referenced regular expression. — Ansible Documentation

- name: disable servers
  replace: >
    dest=/etc/chrony.conf
    regexp='^(server \d+.centos.pool.ntp.org iburst)'
    replace='# \1'

destで対象のファイルを指定して、
regexpでファイル内の変更したい箇所を正規表現で指定できます。
replaceは変換後の文字列ですね。

今回は、regexpでマッチする行の先頭に#がつくようにタスクを書いてみました。
2回目以降のAnsible実行の際は、正規表現に当てはまらなくなるので、変更はされません。
changedになってしまう場合は正規表現の書き方を変えてみるとよいと思われます。

日本のタイムゾーンのNTPサーバーを追加する

先述した通り、最も近い日本のタイムゾーンのNTPサーバーを設定します。

- name: add servers
  blockinfile:
    dest: /etc/chrony.conf
    state: present
    content: |

      # ntp servers
      server ntp.jst.mfeed.ad.jp iburst
      server ntp.nict.jp iburst

Ansible blockinfileモジュールのドキュメント
blockinfile - Insert/update/remove a text block surrounded by marker lines. — Ansible Documentation

blockinfileはAnsible 2.0から追加されたモジュールです。
複数行を追加したいときなんかに使います。

insertafter: '[対象の文字列(正規表現可)]'を指定すると対象の行の後に追加したりできますが、今回はファイルの一番最後に、NTPサーバーの設定を追記するようにしています。
詳しい書き方はAnsibleのドキュメントをご参照ください。

ntp.jst.mfeed.ad.jpntp.nict.jpの2つのNTPサーバーが日本標準時を提供してくれているのでそちらを指定させていただきました。

時刻同期を内部から許可する設定を追加

ローカルネットワークからのアクセスを許可する設定を追加します。

- name: add allow ntp client
  lineinfile: >
    dest=/etc/chrony.conf
    insertafter="#allow 192.168/16"
    line="allow 192.168.1.0/24"

Ansible lineinfileモジュールのドキュメント
lineinfile - Ensure a particular line is in a file, or replace an existing line using a back-referenced regular expression. — Ansible Documentation

今度はlineinfileモジュールを使ってみました。
1行の行追加の場合、こちらのモジュールを使うとよさそう。
#allow 192.168/16の下の行にallow 192.168.1.0/24を追加するタスクです。

サービスの起動と自動起動の設定

- name: chrony start and enable
  service: name=chronyd state=started enabled=yes

serviceモジュールを使って、chronydのスタートと自動起動の設定ができます。

Ansible serviceモジュールのドキュメント
service - Manage services. — Ansible Documentation

$ systemctl start chronyd
$ systemctl enable chronyd

のコマンドの実行と同様のタスクになります。
nameに対象のサービスを指定することで別のサービスに対しても実行可能です。

手動での時刻あわせ

手動での時刻あわせのコマンドを実行します。

- name: adjust the time
  shell: chronyc -a makestep
  changed_when: false

shellモジュールはその名前の通り、シェルコマンドを実行できるモジュールです。

Ansible shellモジュールのドキュメント
shell - Execute commands in nodes. — Ansible Documentation

shellモジュールを利用する場合、冪統制は自分で担保する必要があります。(と思います。。)
特に先述のファイルに何かを追加するような処理をshellモジュールで書くと、実行するたびに同様の記述がファイルに書き込まれてしまいます。

例)

- name: add hoge
  shell: echo 'hoge' >> /tmp/text.txt

このような場合実行するたびにhoge/tmp/text.txtに追記されてしまい、そのつど、changedのステータスになってしまいます。
Ansibleのモジュールにはそういう冪統制を担保してくれるものが多いと思うので、可能な限りAnsibleのモジュールに頼ったほうがよいでしょう。
様々なモジュールがあるのでぜひドキュメントを眺めてみてください。

今回の場合は、手動の時刻あわせのコマンドを実行することになりますが、これは毎回実行されても影響はないと考えます。(ファイルの書き込みとかは起こらないと思うので)
こういう場合は、changed_when: falseを指定しておくと必ず、okのステータスになりますので指定してみました。
changed_when: [条件]という風な指定で、条件に合致したときだけchangedとできるので、特定の条件がある場合はそのように記述しましょう。

以上、NTPサーバーを構築するときのAnsibleのタスクを説明してみました!
内容はボリューミーですが、Ansibleの基本っぽい部分が分かるのではないかなぁと思います。

Ansibleはドキュメントもしっかりしていて、日本語の情報も結構あるので、
「このコマンドに対応するモジュールはあるかな?」と思ったら検索してみてください!
大体あります。笑

まとめ

  • CentOS7はchronyが標準のNTPサーバー
  • ntpdよりchronydのほうが時間調整が早いらしい
  • Ansible yumモジュールの簡単な使い方
  • Ansible replaceモジュールの簡単な使い方
  • NTPサーバーはタイムゾーンが近いところを設定する
  • Ansible lineinfileモジュールの簡単な使い方
  • Ansible serviceモジュールの簡単な使い方
  • Ansible shellモジュールの簡単な使い方
  • shellモジュールを使うときは冪統制は自分で考えなきゃいけないから可能な限りAnsibleのモジュールを使うと楽
  • Ansibleはドキュメントがしっかりしてるので見るとはかどる

次回もAnsibleを使ってさらにデプロイサーバーの環境を整えます!
ユーザー追加とかを想定中。

ツッコミお待ちしております!!

初めてのAnsible

初めてのAnsible