会社の忘年会でコンテンツ作成手伝いでサービスを作ったら面白かったよ、という話
師走
1人Adventに始まり、7月?から関わってたプロジェクトの大佳境も迎えており、社内で秘密裏に企画&開発もやったり、それと加えて企画ごともしたりで、
— 今日も誰かのにちようび( クリスマス) (@o0h_) 2018年12月29日
なんというか12月は「死んで走り抜く」みたいな怒涛さがあった・・・
本当に常に寝不足というか、寝るかねないか?の判断を毎晩迫られているような日々が続いておったわけですが、一段落、開放感、よかった・・・という訳です。
特に今週1週間(火曜〜金曜。月曜は祝日でしたので)、もしかしたら、人生で1番寝てなかったかもしれないってレベル。
アドレナリン出しまくってた気がする。
「師走ぢゃなくて、これぢゃ死走だょ〜ぅ!」みたいな謎の声が頭の中で聞こえてきたときは、悲しい気持ちになった。
社内忘年会の賑やかしを依頼されまして
企画運営チームの人から突如呼び出されて、「なんかエンジニアリングで面白いことやっちゃってよ!!」みたいな依頼をされまして、あーなるほど〜そういうの面白いよね〜って食い気味に乗っかり。
「サービス」相当のものを作る、みたいな方向に
「実際にみんなが操作をして、それでなにかが起こる」みたいなの物を用意することに。そっちの方が面白いから。
何をするって指示とかがあったわけじゃないし、過去に作ったものをそのまま使うという選択肢も大いにあったし。実際、案として「SlackとかSNSとかのデータを取ってきて、何かクイズみたいなのを作るとか」みたいな、作ろ〜っていう感じよりも支援よりの案も出したりしてた。
結果的には「モバイルクライアントアプリ、データベース、管理用バックヤードアプリ、データ集計バッチ、集計結果プレゼンテーション出力機能」を備えるような、1つのサービスが出来上がりました。
どのくらいで作れる?
基本的に「業務に差し支えの無いように」というのは懸念してくださっていて、だから「無理なくできるくらいの人日で、やれる範囲のことを。支出日数を決めたら、こっちから上長に通す」という風に言われ。
すごい有り難いし楽しそうな話だし、とはいえ日数が限られていて年末までのタイムラインでの業務も現実的に設定されている、これは譲歩を引き出せても「3・・・いや、2日ちょいくらいが限界かな・・」という風に結論づけ。
2日で(クローズドとはいえ)丸々1つのサービスを作りましょう
「言われた分の通常の業務時間をまるまる使って良い」と。
2日間っていうのは、「年末の残り3週間のうちから支出する」にはものすごく大きく、素敵なサービスを作りきるには結構小さい・・・・という位のバランスだなぁ、と感じるところ。
ハッカソンとかの「本当に2日間フルコミットできる」とは違って、言うて出勤して社内にいてSlackメンションとかMTGとかも入ってくる。
そういう2日間。
となると、完全に「いかにスピードを上げて作りきれるか」みたいなチャレンジとなる訳です
やってみたら出来た
日数が限られていて、でもあまりにも中途半端になっては仕方ない、ってことで自ずと「めちゃくちゃ早く進める」方向に思考が向く。無駄なことは捨てるし、使えるものは使い切る。
請け負ったのは自分ともう1人で、こちらはCakePHPならスラスラ書ける、あちらはJSをスラスラ書ける、ってことで。「お互いに得意なことにフォーカスして最速でやろうぜ」みたいな話になり、フロントエンド/バックエンドの実装詳細とか設計とか、なんなら「どういう機能があればいいっけ」レベルの話もほとんどせず、「こんな感じで作ってみた」ていうのを形にしてから共有するような進め方に。
ちなみに、一緒にやってくれた人の感想。 medium.com
・・・考えてみたら、よくコレでうまくいったな。まぁ、不安とか未知性とか考えている時間が全くなかったんだけど。そもそも。
たぶん、結果としても良かったし、「成功」なんだと思う
「結果オーライ」みたいな立場に立つと、忘年会参加者が凄いワイワイ使ってくれたし、社長や(誘ってくれた)幹事チームからも「めっちゃ良かった!」という声を実際にいただけたので、成功。
自分としての納得感もあるし。
自分の「初期衝動」に還ってくる部分
やってみて、単純に「面白そうなものを作るの面白いよね」とか「自分のアイディアを自ら形にしていくの楽しいよね」といった感想がまずあって。
これは、学生時代に自分が初めて「PHP」とか「サーバーにアップロード」とかに手を出した時の、初期衝動と同じで。今プログラマやってるのも、そういうのに楽しさを感じるからだな〜って思うし、今回の企画は随分とそれが満たされた。
特に、自分のアウトプットを、実際に使ってもらったり楽しんでもらったり〜っていうのを見るのは誇らしい瞬間。それが目の前で起きてるんだから、そりゃテンション上がるよねー
「成長実感」も還ってきた
「まぁ我々2名なら、この程度は2日ありゃ行けるな?」という煽りをしたのは私ではあるのですが。。
たぶん、参加してくれた人たちには「2日だけでこんなに!」って言ってもらえるような気はしてる。
これを実現できたのは、プログラミングを初めてから今までの積み重ねがあるからなんだよな〜って思わされた。
appどうやって作る?CakePHPならパパっと使える 環境構築しないとね?Docker使える 公開とかデプロイの設定←この前書いたHeroku Container Registryでいいや データ管理とか更新同期どうしよ←Firestore DB楽しかったよ プロジェクト立ち上げ時って、色々と開発効率落ちるよね←PhpStormの設定とかはもう慣れた
みたいな。
いろいろな事をショートカットしまくって、本質的な「機能を作る」「快適にコードを書く」の部分まで足早に進めたなぁ〜というところは、自身の成長の1つだよねと。
あとは、今回はじめて使ったライブラリやSDK/APIもあるわけだけど、そういうときに「パッとググれる」「動かしながら理解する」という能力も、これまでの経験によって裏付けられるものなんだと思う。
「強くてニューゲーム」を何度もしたい
「ゼロからのスタート」であるのは、それこそ8年前の「はじめてのWordpressをインストール」した時も今回の「mkdirしてgit initから」をした時も全く同じはずで。
同じことを火力高めでやれているのが、なんだか「強くてニューゲーム」感があって、楽しいな〜と。
「1人Advent今の自分なら行ける!」と思ってやってみたのも、ある意味「強くてニューゲーム」だな。
あんま知っていることばっかやっていたら飽きるし鈍ると思うんだけど、「何かを作る」というのはそれ自体に刺激や意欲向上につながるような成分は多いと思うし、ちょいちょいやっていけると良いのかも知れないぞーーーって思ったのが、今回の学びになりました ☺
1人Advent最終日
1人AdventのDay- 25 です。やった〜
1人Advent Calendar戦績
カレンダーを全部埋めることに成功しました・・・
- daisuki.nichiyoubi.land
- cake.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- cake.nichiyoubi.land
- cake.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- cake.nichiyoubi.land
- cake.nichiyoubi.land
- daisuki.nichiyoubi.land
- cake.nichiyoubi.land
- daisuki.nichiyoubi.land
- daisuki.nichiyoubi.land
- cake.nichiyoubi.land
- daisuki.nichiyoubi.land
- cake.nichiyoubi.land
- cake.nichiyoubi.land
- cake.nichiyoubi.land
- cake.nichiyoubi.land
改めて、こうやって並べてみると感慨深いというか。長かった。
1番時間かかって、1番「やべー楽しーー」ってなってたのはコルーチンのやつ。
何でやり始めたか
最初の記事に書いたとおりですけど、まぁやる前は「あんまり大きい口叩けない・・」という心理もあったのですが。
今なら「いくらでも調子に乗れる」と思い、解放された気持ちで少し整理してみますと。
個人的に、今年の1年を通じて 「自分がやってきたことや、やれることに対して、ふわふわっとした自信のようなものはあるが、(とりわけ会社などの身内に対して)ふんぞり返っているだけのような、エゴの増長だけがある」というような感覚があり。そういうのは誰しもあるのだとは思うのだけど、今年はとりわけひどかった。
結局のところ「強くなっていそうな感覚はある」のに「本当に強くなっているのかが分からない」という渇きであり、じゃあ「今までにやってないよーな、"明確にハードルが高そうなこと"を1つ・・やってみるか!?」といった動機でした。
自分の等身大の知識や思考を「削り出し」するような形で、25本の記事にまとめる。そのくらいなら"今なら"できるのでは?と思ったので。
ということで、何かしらの挑戦的な意識であり、自罰的な追い込みであり、とりあえず「量」と「テンポ」でやってみよ〜なAdvent Calendarでございました。
何となくこだわったこと
最初は、「よ〜し時間があるときに書き溜めておこ!」と思っていたのですが、とあるツイートを見かけて「書き溜めやクロスポストなんて、私はしない」といった旨のことを言っており。
ああ・・・やるなら・・・俺も邪道に落ちずに・・・・・堂々と・・・「やりきった」と・・・・言ってみてぇ・・・
という悪魔に取り憑かれていました。
ので、それは貫徹。ただ家に帰るのが大体25時前とかですし、「当日24時まで」縛りは一切してないです。私が寝たところが日付変更線だ
会社のやつを2、CakePHPのものを2本とそれぞれやりきった上で1人Advent25。
やってみてどうだったの
最初の方
開始3日目くらいで、「あ。いつもの会社のブログや自分の(行動主導でなく)テーマ主導で書くようなノリと同じ気持ちでいると、相当つらい」というヤバみを感じます。
なんか おもっていた のより たいへん そう
やっぱりな〜〜!他人の目に入るような場所に置くものとして、文章にすると、しっかり調べて書くから勉強にな〜〜!!なるな〜〜〜!
— 今日も誰かのにちようび( クリスマス) (@o0h_) December 2, 2018
つって涙目になってる
そのモヤモヤが深淵に落ちていって、取り組み方として「修行のようだ」と思い始めてきた時のツイート
#phpgenba で言ってた「1時間ブログを書く時間をとってみる」みたいなやつ、「まずは現実的に実行可能なハードル = 1時間くらいなら取れるよね!」的な意味だと理解してたけど、いざやってみると「1時間で収まるネタを思いついて・構成して・綺麗にまとめる」って相当なトレーニングだ・・
— 今日も誰かのにちようび( クリスマス) (@o0h_) December 6, 2018
まぁそれでも、2本、3本と書いていくと「途切れさせたくない」という気持ちも芽生えてくるし、そういう「やってる感」を得られていくと、良いもんですね。
中盤戦
この記事から、Cake縛りブログの方はフォーマットができて来てよかった。 ずいぶんと昔(この辺からの動き)に作ったCake縛りブログの品数を拡充しよう、というのも今回のAdventで狙っていた事柄の1つだったので、これは全体を通じて得られたもののなかでも特筆したいポイントの1つ。
あと、結局エントリーを1本上げるのに油断すると2時間とか調べながらやって3時間とかかかっていく中で、「睡眠時間削れまくる・・・」というのに絶望し始めてきたり。
「毎日やる」「習慣としてやる」ような話は、何より生活リズムに組み込んで、例えば朝起きてシャワーを浴びる様な「取り掛かって当たり前」みたいなビルトインをしないといけない。そう思います。
第4週
個人的な他の事柄と相まって、17日の週からがマジで辛かった・・連日、「とにかくチョロくかける記事はないか!?」とネタを探していた気がします。ローカルにあったDockerファイルを転写しただけの「ギリギリ形になるかな!?」という内容を繰り出したり、Cake3.7.1キタ!何も考えずにかけそう!!と歓喜したり*1。
やり始める前や、最初の数日くらいは「25本出すぞ、それだけでいい!いのちを大事に!」みたいな気持ちでいたのに、結局「とにかく書けばいいから・・・」って状態にまで陥ったのは、多分このあたり。なんというか「命からがら」って気持ちだった。
あとは、この辺りからだんだんと「本を読んだり・・・ペットプロジェクト動かしたり・・・あれしたり・・それやったり・・・・したいな・・・」って感情がたくさん湧いてきて、「あ、なるほど、今は抑圧されてるんだな」と悲しい気持ちを自覚していったりしていました。
終盤
その第4週の低調から、華金+忘年会+システムトラブル+深夜対応of徹夜・・みたいなのが続いて連休中が最悪になってた。
ここまで、少なくとも「翌日朝*2までに出す」は死守できていたのに、MPカラカラ過ぎて22日のエントリー更新がめっちゃ遅れた。悲しい。
連休中にどうにか追いついて、「最終日は振り返り記事だけ書けばいいぞ!!」という状態にどうにか持っていき、今日に至る。
そうか・・・今日に至ったのか・・・・・・・
Adventやってみてどうだったの
当初の予定より、「CakePHP中心」ではなかったような。
まず前提として、自分は「Cake系の発信はもっとしていきたいな、自分の経験はコミュニティに還元できる部分もあるだろうしな」という感覚は強く。なので、このAdventもそれをするつもりだったのですが。
まぁ、別に「そうじゃないことをやっていた」のは何も悪いとは思ってないけども、何となく、蓋を開けてみてこの結果〜というのが自分的には少し意外でした。
さて。
整ったもの
Hugo + GitHub Pagesでのモノ書き環境が整った。これは地味に成果なのです。
- VS codeでMarkdownの編集&Git commit/pushをサクサクっと
- Hugoのarchtype(テンプレート)を整えた
- Cake縛りブログのテンプレートを確立できた
- 先述の通り!
- 「コードリーディングをしてその内容をそのまま書く」みたいなやり方は、アリだと思った
- 何だかんだコードリーディングは力になる
- それをテキストや言語化する時の学習性よ
(Adventと関係なく)12月に新しく1つ「書く場所」を増やした*3のと関連して、ずいぶんと「markdownで書く→pushする」みたいな動作が洗練された。
ちゃんと、何かしたくなったときの武器 = 億劫でないレベルのハードルの低さを備えた選択肢になったな、と。
身を絞りきってみたらアウトプットできることはあるんじゃないの
という感覚を、改めて得ました。
頭では、例えば「普段コードレビューで指摘した内容や示した補足など、そういうのを体裁整えてあげるだけでブログ記事になるんじゃないの?」という考えを持っています。
が、それを「テンションが上ったときだけでなく、毎日毎日やる」というのは、出汁でもとられているような、自分の身を削るような思いもありました。
そして、「そのくらいすればまぁ何かあるよ」というのを体験できたのは、自分にとって新しいゾーンでした。
普段は、ここまで「書くこと」が純粋に目的化するような状態はないので。
先程触れた「修行のような感じ」というのは、この「搾り取られる」という部分から来ています。
毎日毎日毎日・・・
「やらなきゃいけないこと」って、だいたい先延ばしにするじゃないですか。俺の魂がやる気になるのを待つ。まぁ明日やろう、週末にひっくり返そう、とか。
「毎日やる」って決めると、すごいんですね!1つ先延ばしにすると、即借金。明日サボると明後日の負荷が200%。やばい、コレは非常に逃げられない。
今年は、個人的に会社のブログの方で「月1本くらいは書こうかな」をやっていたんですが、(こちらは全然雑にやっつけてるとはいっても)25連続で来るんですよ。
1ヵ月弱を通じて、ひどい体験をしたなぁ・・・・
ただ、マゾ的な快感も一部はあると思って、この「習慣」ってやつはいいなーと思いました。自分を強くしてくれそう。
有言実行が重い
別に誰かが見てたとは思ってないのだけど・・・Adventarに入れて、「やってみるぞ!」と放言してしまった以上、「やらなきゃいけないやらなきゃいけないやらなきゃいけないやらなきゃいけない」って完全に自分で自分の首を絞めていた。
しんど・・
ただ、「やって当たり前」をちゃんとやるのは、やはり「良い」と思うので、自分の中での真っ当さみたいなとこに水を与えていくような感覚は良かった。
総論
年の瀬に、ちょっとした「やりきった感」を自ら生み出すことができたんじゃないかな〜と思います。
最後の最後で公開おくれたりとか、深夜から始めて雑なままになったりとか、とにかく「自分の理想としていたものからかけ離れてる」とか「何でこんなにうまくいかないのか」とかの嫌悪感はあるものの。
それでも、カタチとして「25記事作る」は主観客観どちらに立ってもブレずに「25本」のままそこにあるので、達成はしたんです。否定のしようのない成果というのは良い。
この先どーすんべ
「たまたまノリでやってみましたww」っていうだけのAdvent Calendarが、なにか自分を明確に1つ上のステージに押し上げてくれたりだとか、新しい扉が開くだとか、別にそういうものではないと思うのですが。
ただ、「ちゃんと続けること」という軌道を作り出せてハイになっているところは、今後もスイッチを入れて置けるとよいな〜と思います。せっかくなら。
- やるぞ!ということ
- Cake縛りブログはもうちょいどうにかする、まずは50本くらいは記事入れたいなぁ
- 直近の話でいうと、年末年始の休暇で「手を動かす」系の積読をつぶしておきたい。今の自分は心身的に「無理に向き合う」耐性が一時的に上がっているはずなので。具体的には次の2つのいずれか、もしくは両方
- 7つの言語7つの世界
- Kotlin Webアプリケーション
- やってみたいこと
- なんかコード書きたい〜〜〜我慢してる〜〜〜〜〜〜〜もう我慢しなくていいんだ〜〜
- やれるのかな・・・やれるとかっこいいぞ・・
- いい加減にxUTPを読み進めていきたいのです
- やるかな・・・
xutp.nichiyoubi.land
か・・・・?*4
ということで!おわり!
メリークリスマス〜〜〜〜〜〜
*1:それでも、関連PRさぐってコード読んでissueよんで〜ってやるのは時間そこそこ要るんですが。久しぶりにやったら、「あ、コレ思ったより辛い」て感想
*2:朝とは?人による
*3:http://daisuki.nichiyoubi.land/entry/2018/12/04/183259
*4:レポジトリはずっと前からあるんだ https://github.com/o0h/reading-xutp
PhpStormを使ってOSSにコントリビュートをする
1人AdventのDay-20です。完全に師が走っておる・・・
今日は、こんな 強そう なタイトルでブログを書いてみます。
ただ、「技術論」や「ハイレベルテクニック」というよりは、コレはもう心構えの話です。
CakePHPへのコントリビュート
私は、過去に数度CakePHPやその周辺のプラグインなどにPRを送って、取り込んでいただく!という経験をしております。
Commits · cakephp/cakephp · GitHub
ただ、これらはすべて、enhancement系や大幅なロジックの変更をキメるぜ!!といったものではなく、些細なphpdocの修正や型宣言の修正などがほとんどです。
PRを作るタイミング
「自分で使っていて困ったとき」に送る、という程度のものです。
バランスさえとれれば、「業務時間中にちょちょっとパッチ書いて投げちゃう」程度のことは許してくれるよね〜という職場環境も大いに手伝ってくれていると感じます。
例えば「ここの型宣言が実際的ではなく、静的解析をパスしない」から「PR作ってるんだけどCI通らなくて困る」なんて動機で、書いちゃったりします。
それでもPRはPRで、contributeはcontributeだと思う
あまり小さいパッチでコアメンバーの手を煩わせるのも何だかなぁ、人によってはナンセンスに感じる面もあるよなぁ〜と感じる面もあります。
それでも、「日常的な開発を行っていく中で、些細なところで感じるストレスポイントはゼロに近いに越したことはないよな」という風に思います。
普段触っているフレームワークやOSSは、めちゃくちゃお世話になっており、そこに恩義を背負っているハッキリとした自覚があります。それであれば、何かお礼をしたいし、そのやり方として些細なことでも貢献したい。
もし、自分がパッチを書くことで、同じフレームワークを利用している人が、この「オヤ?っと思ったちょっとした点」について一切の違和感を覚えなくなったり。もしくは、その品質に対して全く当たり前に「よく動くもの」という認識を持って信頼しながら開発に取り組めるようになるのであれば、とても良いな〜と思うのです。
どうやって「貢献」のハードルを下げるか
一重に「PhpStormはいいぞ」というのがあります。コレは、めちゃくちゃ大前提としている部分といえます。
例えば、 #12770などは、「本来は可能である使い方が、パッと見ではできなさそうに見える」ので直したいなという修正でした。
これは、(内部実装的には)問題なく通る部分なので、そのまま使っていても構いません。しかし、IDEを利用していることで「arrayを期待できないけど大丈夫か?」ということで、ハッキリと警告が出ます。
その段になって初めて、「じゃあパッチを書いて正しい姿にしてしまおう」というモチベーションが生まれるわけです。
同様にphan/phpstanを通したときに生じたエラーについて修正を数度投げたりもしているのですが、これも「機械が勝手に見つけてくれて、自分は折角だし数文字だけ直しちゃおう」というリアクションによるものです
普段からソースコードを読みまくる
これまでガッツリとCakePHPを触っている中で、すっかり内部での処理の流れを追うことへの抵抗は薄れてきたと感じています。
このソースコードリーディングも、優秀なIDEに依る部分が大きいです。クラス探索はもちろん、ポップアップでのdoc表示やGo to declarationに何度救われたことか。
何ならドキュメントより生のコードを読むことがすっかり当たり前になってしまったのですが、そうしていくと自然に「コードに手を入れる」ことの抵抗が薄まってきます。フラットに「ここはちょっとおかしそうだよね」と感受できるからこそ、ごくごく些細な修正も「まぁ書いちゃったほうが早いかな」という発想に立てるようになりました。
なんかあったら、パパっと直しちゃう
やはり自分が好きなもの、お世話になっているものが「より正しい姿になっていく」のは嬉しいものです。
今後も、より深い部分での設計思想や描き出す世界観を理解していきたいし、引いては機能追加だったりRFCみたいな形で貢献できたら、もっと楽しいんだろうな〜とも感じます。
現状でも「普段の労力の延長線上でできること」があるということで、それに対して「目をつぶったりスルーしないで向き合う」という形で、自分なりの貢献の仕方を考えられるとよいなぁと思うのでした。
ストームを使いこなしたい〜〜〜〜〜〜!
CakePHP3アプリケーションをPHP7.3で動かす
1人AdventのDay-18です。
手元で作っていたアプリケーションをPHP7.3に乗せて見たので、その時の内容を晒してみようというのが今回の目論見です。
ちゃちゃっと。
構成について
Herokuで動くようにしています。
ということで、以前に作成したPHP7.2用のイメージをベースにしました。
o0ho0h/heroku-php72-fpm - Docker Hub
これについては、以前まとめたものです。
ファイルの内容
こんな感じになっております
$ tree -L 2 . ├── Dockerfile ├── README.md ├── app │ ├── README.md │ ├── bin │ ├── composer.json │ ├── composer.lock │ ├── config │ ├── index.php │ ├── logs │ ├── phpunit.xml.dist │ ├── plugins │ ├── src │ ├── tests │ ├── tmp │ ├── vendor │ └── webroot ├── composer └── docker-compose.yml
$ cat .docker/etc/nginx/conf.d/default.conf server { listen __NGINX_LISTEN_PORT__; server_name _; root /var/www/html/app/webroot; index index.php; location / { try_files $uri $uri/ /index.php?$args; } location ~ \.php$ { try_files $uri =404; include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_intercept_errors on; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
$ cat .docker/usr/local/etc/php/conf.d/xdebug.ini zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20180731/xdebug.so xdebug.remote_enable = On xdebug.remote_autostart = On xdebug.remote_host = docker.for.mac.localhost xdebug.idekey = PHP_XDEBUG_IDE_KEY_HERE
FROM php:7.3-fpm-alpine RUN apk add nginx supervisor \ && mkdir -p /etc/supervisor.d/ RUN apk add \ vim \ git \ zsh RUN apk add --no-cache \ libgcc \ libtool \ pkgconfig \ re2c \ libressl \ xdg-utils \ openssh-client \ ca-certificates RUN apk add --virtual build-dependencies \ autoconf \ automake \ make \ gcc \ g++ \ libmcrypt-dev \ zlib-dev \ gmp-dev \ libzip-dev \ libxslt-dev \ icu-dev \ libmcrypt-dev \ libressl-dev # php7 WORKDIR /usr/src/php/ext RUN git clone https://github.com/xdebug/xdebug RUN NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) \ && docker-php-ext-install -j${NPROC} \ intl \ xdebug \ zip RUN docker-php-ext-enable \ #opcache \ xdebug \ && docker-php-source delete # setup web COPY .docker/supervisor.programs.ini /etc/supervisor.d/ COPY .docker/etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf fpm.d/www.conf RUN rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini COPY .docker/run.sh / RUN chmod a+x /run.sh RUN adduser -D myapp \ && apk add --update sudo \ && echo "myapp ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers COPY ./ /var/www/html WORKDIR /var/www/html CMD ["/run.sh"]
$ cat docker-compose.yml version: '3' services: web: build: . ports: - "9002:8888" volumes: - ./:/var/www/html - .docker/usr/local/etc/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
これで、「xdebugの有効なPHP7.3でCakePHPを動かす」ができると思います。
xdebugについて
Dockefile内でxdebug.inをrmすることで、xdebugを無効にしています。
その上で(localでのみ使う想定の)docker-composeではiniファイルをマウントさせており、これによって「xdebugの有効・無効を環境に応じて切り替える」ということをしています。
opcache
ちょっと問題がある?っぽく、opcacheは無効化しています・・・
最初はうまくいかなかったのですが、外してみたら無事にPHPを動作させることができました。はて・・・
まとめ
今日はかなりさっくりです!!
これだけで、簡単にherokuにCakeアプリケーションを放り込めるかな〜と思います。
あとでGitHub/Dockerhubにあげる!
コーディング規約 for small team 2018
1人AdventのDay-17です。17っていうとFLCLプログレを思い出す数字だな〜
コーディング規約というものがあります。
私は、割と「社内(のサーバサイドというかPHPというか)のコーディング規約をちゃんと皆で定めていきたいよね」側にいます。
その中にありながら、昨今では私も含めIDE/PhpStormの導入が進み、PHPCSもいるし、Phan/PHPStanもいるし、「機械的にやれること」は増えてきております。
原則として「既にあるコード」や「コードを書いた人(とその気持)」は尊重すべきだよな〜という気持ちがありまして、そういう意味で「わざわざtrailing commaをつける」だけとか「空白行を挟む」だけのコミットはしたくない、と思います。もしくは「コメントを消すだけ」とか。
自分が飛ばすPR、もしくはレビュー依頼を受ける事になる変更において「極力、diff行数が少なくなる」ように個人的には目指したかったりはするので、ケツカンマを入れる(配列に新しく要素を追加しても「前の行にカンマがついた」diffを出さなくて済むから)とか、「段落ごとに空白業を挟む」みたいなのは気をつけるわけです。
が、 それはあくまで個人的な話だ 。
コレを「チームで利用するコーディング規約に入れるか」という話を、・・・まぁ合意が取れたら規約として採用してもいいんでしょうけど、何か議論するのが疲れるってレベルのものがある。*1
規約というのはあくまで「健全性」「気持ちよさ」「効率」を引き出すためのものであって、「ストレスを抱えさせる」ためのものであってはならないよな〜と考えるのです。
愚痴を吐いたので、ここから本題です。
(先程述べた通り)私は「規約整備していこうぜ!」側でして、新しくサーバーサイドのエンジニアが入って共同のチームで動くよ!と決まったタイミングで整備をしたり、その後にはgithub管理移行とかも仕掛けたりをしました。
そうした活動を通して、自分なりに「健全性を高めるためにこういうポイントを抑えておきたい」と感じた部分があります。
その辺りの話を、少し整理してみようかなというのが今回のエントリーです。
前提のような方針のようなもの
「整備し直した」ものはCakePHP3のプロジェクト用のものでして、その「第0章」みたいな文章を書いてあったのでそれをそのまま引用してみます。
### コーディング規約の役割 チーム内で、「誰が書いても」「誰がレビューしても」同じ様にコードが書けて、違和感を持たずにコードが読めて、迷いを少なくしながら開発を進められる状態を理想とします。 狭義のスタイルガイドにとどまらず、推奨されるイディオムやプラクティスやフレームワークのバージョンアップ等に伴い生じる「注意の必要な書き方」をも示すことで、日常の開発業務において従うべき新鮮なガイドラインが欠かせません。 これを踏まえて、本文書は以下の役割を果すべきものと定義します。 * CakePHP3の経験の浅い新規参加者が、「どういう風に書くか」を把握できる * CakePHP3の経験者が、「こうやると書きやすい/読みやすい」を普及できる
このくらいでいいんでないかな〜という規約
OSSのフレームワークを利用している場合、そのフレームワークの採用している規約がある場合が多いと思います。
なので、スタイルに関しての「守らないといけないもの」は、ベースとして「フレームワークが言っていることをそのまま」で良い、くらいに思っています。
これによって、コミュニティが持っているアセットを活かしやすくなるというのも重要。拡張改変バリバリの「本来のそれとは相入れない」ようなものを制定したら茨の道に突入していきます。
その上で、やってもいいかなと思っているもの
基本的に、自分たちのために作っているプロダクトというのはOSSなフレームワークほど「汎用的である必要」がない、と思っています。
そのため、実装についてもより(自分たちのための)アグレッシブな方針を取れるものと思います。例えば、「言語バージョンを新しくしたら使える機能」などです。
これらについては、「フレームワークの本家にはなくても、快適さを向上させる見込みがある」と判断できる場合もあるのではないでしょうか。そういったものは、あっても良いと思います。
あった方がいいかなと思っているもの
逆に、自分たちで作った機構やライブラリについては「利用するように規約で縛る」事でコーディングのし易さを支援できる可能性がある、と考えています。そうしたものは、積極的に「使っていく」ことに決めても良いかと思います。
なぜなら、「自分たちが自分たちのために作ったもの」であれば、サービスドメインやチームメンバーのレベルに合わせて開発されたものであり、フィットするはずだからです。
例えば、私の場合はenumのような機構を作りました*2が、これは「使うべき」としました。オプショナルでなく「使えるときは使う」ことによって、この機構の保守改善を行っていく恩恵が、プロジェクト全体に浸透していく状況を生み出せるようになるからです。
何より「メンバーがそれぞれに同様の書き方を扱えるようになり、リーディングにも実装にも没頭しやすくなる」ことが規約を定める目的でもあるので、足並みを揃えられられたのは良い点でした。
あると良いかなと思っているもの
私の仕立てた「コーディング規約」では、規約やガイド・・の範疇を超えた「プラクティス」の賞も設けています。
「こう書くべき」というとかなり強い制約になると思うのですが、ここには「こう書くとCakePHPぽいよ」といったものを拡充させていっています。
実は(規約自体はフレームワーク本体が抱えているにもかかわらず)「社内規約」を管理したい、というモチベーションの1つはこの「プラクティスを管理してみたい」という部分にもありました。
例えば、「CakePHPのEntityに値を入れるときに、どういった場合にはpatchEntity()メソッドを利用して、どういった場合にset()を使うのか?」といった内容に触れています。
当然ながら、「全員が守るべき・意識するべき」という規約よりも、周知徹底すべきなのはどのレベルからだっけ・・・?というのがファジーになるので、メンテナンスを続けていくのは中々ハードルが高かったりします。それでも、「プルリクで何度も指摘される」ような話は、こういった仕掛けで担保できないかな?とも思うわけです。
いずれにせよ
「なぜなのか」を示していくことが重要なのでは、と感じています。
もちろん、規約の中には「スペース4つで示す」といった、理論立てて説明し/されて納得感を持ちながら扱う・・というのとはそぐわないものもあります。他方で、例えば(実際にCakePHP3が採用している例で)「privateメソッドには引数の型宣言を行わない」という話をするときに「型宣言を行った場合、それを解釈し実行するコストが必ずしも0ではない」から、スコープが限定されるときは「なるべく負荷がないようにしよう」という理屈があると、助かるだろうな!と思うわけです。更に、「根拠を示す」ことが「改定を望むときにpros/consを明確にしやすくなり、本質的な議論に進みやすくなる」という利点もあります。
理屈をしっかりと明示していくことで、「コーディング規約」が「押し付けられるもの」ではなく「民主的に取り組み、常にアップデートされていくべきもの」へと進化させ得ると考えています。
まとめ
規約は堅苦しかったりストレスになる危険性もないではないわけですが、「関わる人全員をハッピーにしようぜ」というモチベーションから生まれるものだと思います。
コミュニティに開かれたソフトウェアのコーディング規約と社内やチームに適用されるべき規約とでは、そもそも目的も異なるはずで。なので、「自分たちのチームには何が必要で、どういったものがあればコーディング時の憂いがなくなるか」という原点に立ち返りながら、「ぼくらのかんがえたさいきょうのこーでぃんぐきやく」を以てして、最高のコーディングライフを手に入れられたらハッピーなのではないでしょうか!
*1:prettierくらい強烈に書き換えてくれるものやgofmtとか、救いだな〜!と感じる
yieldとコルーチンと非同期処理
1人AdventのDay-15です。もう2週間経ったのか、12月よ・・
最近、ちらちらっと「Swoole」という単語を聞くようになった気がしており、それについて調べてみよう〜という予定でした。が、「まずコルーチンとかについて頭の中を整理したいな・・」と思ったので、このようなタイトルになっております。
きっかけ
Swooleについて初めて意識したのが、TLにこのツイートが流れてきたときかなあーと思います・・
PHP/Swoole outperformed the default Golang helloworld http server https://t.co/JkCrQq5C4M pic.twitter.com/QwgnHLyYbk
— BEAR.Sunday (@BEARSunday) 2018年11月11日
Swooleってなんなのさ
BEAR.Sundayのサイトに載っている説明はシンプルにまとまっていました。
SwooleとはC/C++で書かれたPHP拡張の1つで、イベント駆動の非同期&コルーチンベースの並行処理ネットワーキング通信エンジンです。 Swooleを使ってコマンドラインから直接BEAR.Sundayウエブアプリケーションを実行することができます。パフォーマンスが大幅に向上します。
ググったら「副題: 最近Swooleが楽しい話」というUzullaさんの記事が出てきました。
最後まで読んでみて、いろいろと「なるほど」がありました。結構ボリュームがありますね。 スライドを見ていたら、サイトも出てきました。
「プロダクション品質の非同期PHPプログラミングフレームワーク」ふむ。
・・・なんだか「こんにちは、闇の方から来ました。私、色々できます」みたいな凄みを感じます。
Sooleと非同期プログラミング
私が「Swoole気になるな」と思ったのは、「非同期」があるの?と思ったのが強いきっかけの1つです。
非同期、よいですね、ふふふ。
先のuzullaさんのスライドを見ると「Swoole、めっちゃ機能多そうだな」という感想をいだきます。何か新しい仕組みや概念を理解しようとするときに、私は「なにか1つポイントを見つけて、それを軸としてイメージを具体化していく 」というアプローチを好みます。それをしながら、「 必要になったら時点で他の筋に移動したり、行ったり戻ったりする」を繰り返して、全体像を掴んでいこうという感じです。
多機能だからこの記事で全部触れるの無理よな〜っていう思いもあり、まず「非同期プログラミング」をキーワードとして調べている内に、主題が入れ替わった形です。
PHPとコルーチン
先のスライドの中にも、「コルーチン」が出てきますね。
[
PHPでの非同期処理を得意にさせるrecoilなどにもcoroutineについて言及があります。
では、コルーチンとは一体なにで、どうしてそれが非同期処理と関係があるのでしょう?
そもそも「コルーチン」がなにか、という話をつまみ食いしておきます。
まずは、例によってWikipediaです。
コルーチンはいったん処理を中断した後、続きから処理を再開できる
とか
接頭辞 co は協調を意味するが、複数のコルーチンが中断・継続により協調動作を行うことによる。
(https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3)
なんて書かれています。
「継続」「中断」「再開」という言葉が出てきました。これらを意識することができれば、意味がつかみやすくなるのかもしれません。
継続
継続については、こちらの記事が良かった。
なんでも継続
「意識することができれば」と書きましたが、「今までもそこにあったのに、見えてなかった/認識することができなかった対象を、ふと「当たり前」に存在を感じられるようになれば」ということで、この書き方をしました。そして、この「なんでも継続」の記事が、正にそのスタンスで書かれていて良かったな〜と。。
すんごいザックリといって「なんかの処理をしていて、途中でどっか行って、戻ってきたらその 続き から処理を行う」というのを強調するために「継続」という概念が必要な気がします。「どっか行って」=中断、「戻ってきて」=再開。
関連: 制御構造 - Wikipedia
yield
さて、PHPにおいても「中断」「再開」といった単語を(サブルーチンのそれとは違い)強く意識する場面があるのではないでしょうか。
イテレータ、ジェネレータ、yieldといったキーワードを思い出してください。
ジェネレータ(Generator)とは、イテレータコンパチなインターフェイスを持つけど、 指すべきコレクションがあるわけでもなく、そのたんびに 値を作り出して返すようなモノを作るモノをいいます。
PHPはyieldによってジェネレータを作成できます。
- 中断:
- ルーチンの内部の任意の箇所で、(呼び出し側に値を返して)処理を終わらせ
- 再開:
- 「さっきやったとこ」の続きから処理を始める
という内容を備えています。「一旦処理を中断した後、続きから処理を再開できる」ということであれば、コルーチンの定義に当てはまると言って良いのでしょうか?
ジェネレータ/コルーチン
yield(PHP)はジェネレータ関数を作るのだから、じゃあyeildを使えばコルーチン?コルーチン = ジェネレータ?と思い、今度は「ジェネレータ」についてWikipediaでみてみます。
ジェネレータの実装としてはコルーチンやcall/ccやマルチスレッドを使う方法が考えられる。
ということで、どうも一致する概念ではないようです。
どういう差なのかな、と調べてみたらPythonに関しての例を説明している記事に行き当たりました。
yieldした後にコントロール出来るという点がジェネレータと違うようです。
Pythonのyield(コルーチン編) | KISO-REN
この「コントロール可能か否か」というところで、コルーチンは分類されるぞ!というような事をStackoverlowの問答で発見しました。
In the asymmetric coroutine model, "asymmetry" refers to the fact that there is a stack-like caller–callee relationship between coroutines. A coroutine can either call another coroutine or suspend itself by yielding control to its caller, typically also yielding a value to the caller at the same time.
What is the difference between asymmetric and symmetric coroutines? - Stack Overflow
ジェネレータを含む「非対称コルーチン」においては、「一旦処理に入ったら、そのまま、最後まで内部生成された値を返す」ということになり、これを「一方的(= callerには制御権がなく、コルーチンにのみ自身の制御権がある)」と言っている・・のでしょうか?そんな感じと理解しました。
そしてさらに、Pythonの例を見つけました。
魅力的なPython: ジェネレーターによるステート・マシン
かなり前のバージョンにおける言及をしている記事で、この中では「(Python2.2で導入された)yieldでのジェネレータは半コルーチンで、本当のコルーチンを実装したよ」とされています。
内容を見てみると、「ジェネレータの中から別のジェネレータを呼ぶ事は可能」というのを応用して、「ジェネレーター同士がお互いを呼び合う」ようにしている・・というのがポイントでしょうか。
先の「Pythonのyield(コルーチン編) | KISO-REN」の記事で言及されているPython Coroutineの元ネタPEPを見てみると、次のように書かれています。
However, if it were possible to pass values or exceptions into a generator at the point where it was suspended, a simple co-routine scheduler or trampoline function would let coroutines call each other without blocking -- a tremendous boon for asynchronous applications.
PEP 342 -- Coroutines via Enhanced Generators | Python.org
ということで、IBMの記事にて実装されている内容も今のPythonならシュッとかけるのかもしれません。
これ以上は、今回のエントリーの本題から外れていきそうなので話を戻します!
PHPにも同様の機能が導入されています。
yieldと非同期処理
ここまで見てきたとおりで、コルーチンは「別の何かをする処理」であると言えます。そして、「中断して(=処理を呼び出し元に戻して)」「再開して(=自身の中に状態を維持・継続ができる)」というのがポイントです。
ということは、「コルーチン内部の処理を行っている最中に、呼び出し元の処理をブロックしない」もしくは「取り急ぎ呼び出し元にコントロールを戻しつつ、自分の処理もちょいちょい進めておく」事が可能なら、実質的に非同期処理が可能という着想で合っていますか。
まさに、そのような内容を扱っている資料が上がっていました。
これは、以下の条件によって実現されているものと思います
- non-blocking APIを備えた実行内容がある
- curl_multi
- coroutineをstackさせておく
- stackされたリクエストの解決まで、無制限のループ処理によって状態のチェックを行う
そうすることで、「すべての解決を待つ」ことをしつつ「個別の処理は並列的に行う」という操作が可能になったという理解をしています。
「PHPでコルーチンを利用することはできるが、それ自体は「あらゆるものをノンブロッキングにする」ような能力はなく、あくまで並列化の可否は処理内容としてノンブロッキングAPIを利用出来るか次第で、また「整いました!」とイベントを拾いに行くのは自分で監視をじっそうしなければならない・・・」 こんなところでしょうか。
ReactはイベントループとノンブロッキングI/Oの実現を目指した、ループ機構です
感想
「なんでもすぐに並列化できちゃうすごいやつ!」というのは、PHPという言語上は存在しないんだなーというのを改めて認識しました。
その一方で、ノンブロッキングな処理が実装されている領域についてはPHP上で実装が可能そうにも思います。例えばMySQLからのデータ取得などは、個人的な関心からいっても恰好のターゲットです。
実際に手を動かしてみないとイメージ湧かないな〜とも感じたので、「引き続き模索してみたいな」と思っています。
その他の文献
本文中では触れなかったものの参考にした記事です
- Python で学ぶ、コルーチンと非同期処理 - Qiita
- PHPはReactで非同期処理対応のWEBサーバを構築する - Qiita
- ReactPHP?時代はRecoilPHPだ! - Qiita
- Kotlin Fest 2018でコルーチンの話をしてきた - visible true
- Swoole PHP Coroutine | Swoole
- ノンブロッキングI/Oと非同期I/Oの違いを理解する – PAYFORWARD
- PHPでもジェネレータを使って、非同期処理を同期処理の文法で書ける - Qiita
- 非同期とノンブロッキングとあと何か | κeenのHappy Hacκing Blog
- Cooperative multitasking using coroutines (in PHP!)