チームで中規模Perlアプリケーションを開発する工夫
Perl Advent Calendar 2018 13 日目の記事です。
チームで開発を行うとき、機能単位で担当者を割り振り、実装することが多いかと思います。
しかし、実際には一人で実装するにはボリュームが大きく、機能も分割しにくいケースがよくあります。
このような時には、ビジネスロジックをプラガブルに設計しておくことで、開発のスケールアウトをしやすくなります。
プラグインの実装
複数の処理を繋ぎ合わせ、次処理に回すような流れを想定した場合、菱形多重継承のような実装モデルが想像されます。
各クラスで実装した処理をメソッド順序解決を行いながら順次実行されるわけです。
このようなプラガブルな構造を実装する方法としては、古くはClass::C3のようなモジュールがありました。
しかし、次処理にまわしたい要件を実現することに、多重継承を用いて解決することには牛刀感があります。
合成の利用
MooseにはRoleという仕組みがあり、これを使うことでモジュールへの合成を行うことができます。
呼び出し元にプラグインを追加して行くことにより機能を追加していくことになります。
処理をクラス毎に分割し実装担当者が メソッドの in -out のチェックを行うようにすれば、個々人が並列に実装作業を行うことができるようになります。
package Yyy; use Mouse::Role; before 'init' => sub { my $self = shift; push @{$self->list}, 'y'; }; 1; package Zzz; use Mouse::Role; before 'init' => sub { my $self = shift; push @{$self->list}, 'z'; }; 1; package Main; use Mouse; with ' 'Yyy', 'Zzz'; has list => ( is => 'rw', isa => 'ArrayRef', default => sub { []; } ); sub init { my $self = shift; my $string = join ('-', @{$self->list}); return $string; } 1;
use Main; my $m = Main->new(); print $m->init(); # 呼び出し順をたどって z-y が出力される
with に追記した逆順に各クラスの before 'init'
が実行処理されるようになっています。上記のコードの場合は Yyy, Zzzのそれぞれのクラスを担当者で実装してもらうわけです。
道具の進歩(github)により開発が衝突する機会が少なくなってきてはいますが、それでも時には人的リソースのスケールアウトが可能なように設計をしておくことも一つの案だと思っています。
現場では依然として活発に稼働しているPerlプロダクトが多数あります。枯れた技術を工夫しながら日々改善するのが長期運用のコツではないかと感じています。
builderscon 2018 に参加(登壇)してきました
数年放置していた本ブログですが、私は元気です。
builderscon 2018に参加してきました。
オープニングには間に合いませんでしたが、色々なセッションに刺激をもらいました
開発現場で役立たせるための設計原則とパターン
実況中継シリーズ 「開発現場で役立たせるための設計原則とパターン」 #builderscon 2018 - 猫型の蓄音機は 1 分間に 45 回にゃあと鳴く
設計に関しては、抽象論の空中戦になることが多い実感。「個人の感想です」が顔を出しがちになるホントこれ。設計原則に当てはめて考察するってのは筋がいい。設計コストの問題もあるにせよ、これは自身やチームのレビューに有効そうだなと実感。
Webサービスにて200週連続で新機能をリリースする舞台裏
Webサービスにて200週連続で新機能をリリースする舞台裏 / builderscon tokyo 2018 - Speaker Deck
毎週リリースとなると週刊連載を持つようなものだよなぁと思ってたけど、実際にネタのストックをためておいたりとか1話完結の漫画家ぽい
それでも毎週リリース出せるのはチームの自力があってのことだろうし、ここ数年のMackreleの開発状況を見ると尊敬せざるをえない。スタートアップ期が終わったっていうのは良い判断だし素晴らしいスピード感だったと思う (Mackerelガンガン使っております
機械学習を用いず数学でゲーム内の需要予測をする
機械学習を用いず数学でゲーム内の需要予測をする - Speaker Deck
会社の同僚のセッション。機械学習で使えるような形式やデータ量でもない場合には数式(+人間)で予測することができる。ソーシャルゲームで需要予測を行ったの実例を紹介。山場はホワイトボードで数式を書き始めたあたり、かっこいい!
Webサービスの品質とは何か?アラート地獄と監視の失敗、サービスレベル目標設計から学んだ3つの答え
Webサービスの品質とは何か?アラート地獄と監視の失敗、サービスレベル目標設計 から学んだ3つの答え - Speaker Deck
大変身につまされる思いがしました...ごめんなさい。忙しさにかまけて、ついつい放置しがちになってしまい云々....アラートがアクションにつながらないってのは本当
証券トレーディング業務におけるExcel依存を脱却するプロジェクトで直面した技術的選択とプロジェクト運営の失敗
録画撮影禁止だけのことはある、業界自体が怖いよ。ヒットマンが飛んできそうだ。 社内システムの顛末なんだけど、当初の要件としてはシステム規模が大きくならないはずなのにね。 あまり関わることのない世界だと思いたい。
ブログサービスのHTTPS化を支えたAWSで作るピタゴラスイッチ
そーだいなるピタゴラスイッチだ。色々悲鳴が聞こえて来てはいた(?)けどよくぞ作ったものだと尊敬する。実にはてなっぽい。
要素技術的にはDynamoDBのTTLをトリガーにするのが良さそう。ドミノを倒すトリガーについて考えていたので参考になりそう。
RDB THE Right Way ~壮大なるRDBリファクタリング物語
RDB THE Right Way - builderscon 2018/ RDB_THE_Right_Way - Speaker Deck
「データベースの寿命はアプリケーションより長い」が重い。世の10年超えのサービスはすごいよなぁ。 データと情報、技術的根拠。そして本読む時間作ろう。
ちなみに自分は以下のセッションで登壇をしてきました。
SNSでの反応を見る限りでは結構楽しめたようなので安心しました。 ここ数年ほとんど表に出ていなかったので色々緊張しました....
ソーシャルゲームが高負荷に陥っているとき、何が起こっているのか
運営スタッフ・スポンサー・関係者の皆様、楽しいイベントありがとうございました
来年も機会があれば参加したいと思います!
APIドキュメントからモックサーバを立ち上げるWeb::API::Mockを書いた
APIドキュメント(API Blueprint)からモックサーバを立ち上げるWeb::API::Mockを書きました
Plackで作った事もあり以前紹介したapi-mockよりも、ちょっと便利になっています
APIドキュメントからモックサーバを立ち上げたい - akihitoのログ置き場
モックサーバからアプリケーションサーバへURL毎にスイッチする
3番目の仕組みを利用することで、nginxを使ってモックサーバからサーバアプリケーションに差し替える事が出来ます
upstream mock_backend { server 127.0.0.1:5001; } upstream prod_backend { server 127.0.0.1:5002; } server { location ~ ^/ { proxy_intercept_errors on; proxy_pass http://mock_backend; proxy_set_header Host $host; } error_page 501 =200 @prod; location @prod { proxy_pass http://prod_backend; proxy_set_header Host $host; }
モックサーバ(mock_backend)にnot-implemented-urlsオプションで渡したURLが501で返ってくるので、 nginx側でキャッチして、実装したサーバアプリケーションにURL毎にまわせるようになります
APIドキュメントからモックサーバを立ち上げたい
APIドキュメント(API Blueprint)を記述するとモックサーバを立ち上げてくれるサービスがあります。 GitHubでAPIドキュメントを管理したり、モックサーバのアクセスログが見えたりの中々の優れ物です。
提供されるモックサーバがRESTful APIで少々融通が効かないこと、外部のWebサービスなので場合によっては採用しづらいのが難点。
ただ、API BlueprintのテストツールやモックサーバはOSSで提供されているので、サービスを使わずに利用することも可能のようです
api-mockで手軽にモックサーバを立ち上げる
公開されているモックサーバがJavaだったりして、ちょっと入れづらいなぁと思っていたら、api-mockなるモジュールがあるようですね。これもAPI Blueprintからモックサーバをたち上げてくれるようです
API Blueprint形式のAPIドキュメントを用意する
API Blueprintは、Markdownを拡張した形式です。
API Blueprint詳細
こんな感じでMethod,URI,Request,Response等を記述していきます
FORMAT: 1A HOST: http://example # Nopaste タイトルと本文を投稿します ## POST /api/nopaste + Request + Header Host: example + Parameters + title (required, string) ... タイトル + body (required, string) ... 本文 + Response 201 (text/html) + Header X-Framework: Ark + Body { "result": { "ok": 1 } }
API Blueprintはちょっと癖があったり未整備な所もあるのですが、現時点での要求としては十分かなと思っています。
api-mockを入れる
nodeで書かれているのでnpmを使ってインストールします
npm install -g api-mock
実行
では早速実行してみましょう
$ api-mock sample.md --port 3001 Listening on port 3001
コマンドラインから叩いて確認してみます
$ curl http://localhost:3001/api/nopaste/1234 { "result": { "title": "Hello Nopaste", "body": "Text" } }
$ curl -I http://localhost:3001/api/nopaste/1234 HTTP/1.1 200 OK X-Powered-By: Express Content-Type: application/json X-Framework: Ark Content-Length: 83 Date: Fri, 11 Apr 2014 04:05:05 GMT Connection: keep-alive
Headerに記述した"X-Framework: Ark"もちゃんと返ってきてますね
ドキュメントに記述した固定正常系のResponseしか返してくれませんが、それでもクライアントが サーバサイドの実装を待たずに疎通確認が出来るのはうれしいんじゃないかなと思っています
(このサンプルをApiary — Homeに持っていくとエラーになるんですが、統一感があるのでこちらの方がいいかなぁと…思っています)
手軽に多言語対応したい
YAPC::Asiaも終わったことですし(?)久々に
時間と工数が少ない中で、多言語対応する必要に迫られました。
Locale::Maketext::Lexiconあたりを使ってテンプレート側でフィルタかけて差し替えるってのが正攻法ではある
- http://blog.64p.org/entry/20111103/1320282725
- http://tech.kayac.com/ark-advent-calendar-2011/20.html
ただ、これだと
- テンプレートを直さないとならないので、作業現場のユースケースに合っていない
- PMやマークアップエンジニアに仕組みを周知させる時間が厳しい
- アプリケーションの機能開発が絶賛継続中なので、余計な事はしたくない
とか諸々問題があって、考え悩んでたのですが、天啓をえました
Plack::MiddleWareを利用してみる
天啓というほどではないのですが、出口の所で全部差し替えればいいんじゃねと思いたって、 こんなモジュールを用意しました
https://gist.github.com/takihito/27d6fca91cb24be5e396
このモジュールをbuilderで以下のように読み込んで上げれば表示される HTMLタグ内の日本語が差し替わるようになる算段
builder { enable "Plack::Middleware::Ja2Ko";
今回は一部特定のページなので、パフォーマンスを気にしなくて良いのもあります。 Project::Ja2Ko内のTRANSLATION_LISTを別ファイル(CSV)で定義して読み込めば運用としても理解しやすいレベルになるんじゃないかと思っています
アプリケーション本体はガンガン開発してもらって、それとは関係なしに実装したほうが作業が被らない。
Plackで呼び出せるなら他のアプリケーションにも多言語フィルタかけれるんじゃないかと思った次第
追記
Plack::Middleware::Static::I18N( Plack::Middleware::I18N ? ) ってのがあるみたいですが、(放置されてるのかな) I18N宣言するモチベーションも時間ないので今回はここまで。
YAPC::Asia 2013 行ってきました
1日目は諸事情で、ほとんどのセッションを逃してしまったのですが、2日目はLTまで参加することができました。
追えていなかった技術的の話をまとめて聞けて、遅ればせながらも 最近の動向についていけるようになったかなぁと思っています。 非常に学習効率がいいですね、それだけでも価値がありました。
開発自体よりテストやDevOpsといった周辺技術の話が多かったように思います Programming AWS with Perl」「What's new in Carton & cpanm」をたてつづけに見た事もあり インフラよりの技術がプログラマーの手に届きやすい所に来ているなと実感したところです
あと、懇親会で表には出てこない各社の色々な話を聞けたのが収穫で、大変楽しかったですね。 どんなに忙しくても懇親会だけは、毎年参加するようにはしてしています
関係者の皆様、お疲れ様でした。 来年も楽しみにしております。
Monoを使ってOSXでC#
Unityを触っています
言語はJSとC#に対応しているワンソースで色々なプロットフォームに対応してくれるすぐれもので、手元ではC#で書いています
Unity上でプロジェクトをビルドして再生ってのが正当な開発方法のようですが、一旦ターミナルから手が離れてしまうこともあって少々辛いことになっています。
ターミナル上でシンタックスチェックやコンパイルした方が非常に捗るなぁと思っていたわけです。
Mono
Windows以外でも.Net Framework環境を実現するためのMonoプロジェクトがあります。 C#コンパイラが含まれていて、これを使うとターミナルからコンパイルが行えるようです。
Hello World
Hello Worldをやってみましょう
using System; namespace HelloWorld { class Hello { static void Main() { System.Console.WriteLine("Hello World!"); } } }
C#のコンパイラはバージョンごとに幾つか(mcs,gmcs,dmcs)用意されています。 dmcsのバージョン4.0を使います
$ dmcs hello_world.cs
hello_world.exe ができている事を確認しmonoで実行してみましょう
$ mono hello_world.exe Hello World!
郵便番号住所検索
これだけだとつまらないので郵便番号から住所を検索できるプログラムを書いてみました 初心者の勉強がてらの遠回りなコードになっていますが、そこは勘弁
やっていることは
- 郵便番号住所CSVを読み込む( http://www.post.japanpost.jp/zipcode/dl/roman.html )
- ハッシュテーブル(Dictionary)に郵便番号をキーにして、値に住所を入れる
- 第一引数に渡された郵便番号をキーにしてハッシュテーブルから住所を検索
これだけです。
さっそく実行してみましょう
// 複数ファイルのコンパイルは列挙すれば良い模様 $ dmcs main.cs Zipcode.cs -out:zipcode.exe // 郵便番号 4200838 を渡して実行 $ mono zipcode.exe 4200838 Read.search Hit !! zipcode:4200838 local:AIOICHOAOI-KU SHIZUOKA-SHI
Unityでは使えるライブラリに制限があるようですが、UIと絡まないビジネスロジックや サーバとの連携を作る際にはMonoを使って作成していくのがいいのではないかと思っています。