オブジェクトをそのままで送受信するPipe
IPCの中でもPipeはTCPとかのネットワーク系の基礎になったもので、結構使いやすくて個人的に好きな機能です。
特にスレッドを使うと、スレッド間通信用に多用します。
自分でリングバッファとか作るのも1つの手なのですが、自前でこういうの作るとブロッキングが出来なくsleepとかいれざるを得ないのでちょっと厄介なので特別な理由がない場合使いません。
さて、これを今回Rubyで使おうと思ったのですがRubyの場合IO#pipeで作りwrite/readを使うので文字列でしか通信できないのがネック。
送受信したいのはあくまでもRubyのオブジェクト。Cだと、どうせ同一プロセス内なので型を統一してポインタをwrite、readしたらキャストすればOKなのですがこの技が使えない。
http://docs.ruby-lang.org/ja/2.1.0/class/IO.html#S_PIPE
http://docs.ruby-lang.org/ja/2.1.0/class/IO.html#I_WRITE
http://docs.ruby-lang.org/ja/2.1.0/class/IO.html#I_READ
諦めるのも嫌だし仕方がないので、悩んだのですがMarshalを使うことにして動作するのを確認しました。
http://docs.ruby-lang.org/ja/2.1.0/class/Marshal.html
class ObjctPipe def initialize pipe = IO.pipe @rp = pipe[0] @wp = pipe[1] end def write(obj) objs = Marshal.dump(obj) len = objs.length lens = [len].pack('L!') @wp.syswrite(lens) @wp.syswrite(objs) end def read lens = @rp.sysread(8) len = lens.unpack('L!')[0] objs = @rp.sysread(len) obj = Marshal.load(objs) return obj end end # 使い方はこうなります pipe = ObjctPipe.new # read側はスレッドで行う Thread.new do while true obj = pipe.read end end # write側 while true # データを作成しておく pipe.write("なにかobject") end
いくつかポイント
- write側スレッドとread側スレッドで同じ'pipe'オブジェクトを使いますが、Mutexは使っていない
- これは、実質同じデータにアクセスしないのでスレッド特有の問題は発生しないからです
- 送信するobjectをMarshalしておく
- 当然Marshalの制限がかかります
- objectを送信する前にオブジェクトサイズを送る
- サイズはpackで'unsigned long'にしておき、'オブジェクトサイズ'自体の大きさを固定しておく
- これはread時のバッファやブロッキング動作が絡むからです
- write/readではなくsyswrite/sysreadを使う
- これは文字コードが絡んできてデータによってはwriteでエラーになるから
Rubyってobj.__id__でオブジェクトIDは作れるのですが、IDからオブジェクトの復活方法が分からないのでこの方法を取りました。
Marshalやpack/unpackが入るのでCに比べて無駄が多いのですが、まあ許容範囲内でしょう。
意外と便利に使えています。
会社での開発体制改善中
ここ5年程はWeb業界で働いていてWeb業界で現在2社目。
前職の最後の方ではそこそこ業界で有名になった企業。現職は上場している企業なわけですが、両方とも開発体制、手法がひどい。
端的に言えばいきあたりばったり開発です。
ディレクタに当たる人たちが、まともに仕様書を作れないから仕様書を作らない or 作っても要望書というか夢リストになるだけの書類しか作れない、でも自主的に勉強もしない。
そしてそういう人たちだけが出世する会社。
でもエンジニアはそれなりにスキルがある人たちが多いという現場なので、エンジニアが空気を読まされて、なんとか物をつくってリリースするという最悪な状況。
当然エンジニアの仕事もドキュメントは少なくというかほぼ存在しない、テストコードもほとんど書いていない。
最近はDevOpsとかも取り入れていますが、それはエンジニアだけの改善策であってディレクタが変わらない。
マジで最悪。
とはいっても、現在の職場の人たちはそれでも知りたいという気持ちはあって、エンジニアが勉強会を開くと参加もしてくれる。
最近だと会社のサービスを例に1からサーバ構成とか、Rails(うちはRailsが基本です)の仕組みを教える勉強会を開催すると参加はするし、質問ももらえる。
つまり、少なくとも現職勉強しないのではなくて、勉強方法が分からないのだと思う。意欲はあるのだから。
さて、最近自分は完全に新規のプロジェクトを担当している。しかも会社としては初のチャレンジ部分だ。
当然ながら仕様はきちんと決める必要があるし、テストも大事だ。エンジニアよりもディレクタの人数が多く、相変わらず夢物語も多い。
ここいらで何とかしたいし、何とかして良い効果がでれば開発手法も横展開したい。
で、どうするかだが、悩んだ結果大まかな部分はウォーターフォール型で開発すると宣言して、実際の開発ではスクラム開発を採用するという、かなり変則的な方法をとった。
ウォーターフォールとはいっても話は簡単で、はじめにきちんと仕様書をつくる。仕様書を作る段階では何回もチェックをいれて修正を行ってもらう。その次に開発を進めて、最後に一斉にテストだ。ウォーターフォールっぽい。
もちろんこれがきちんとしたウォーターフォールだとは思っていないが、目的はきちんと仕様書を書かせることにあってそのための方便として'ウォーターフォール'という言葉を使わせてもらった。
ここをきっちりしないと、開発が進まないので彼らからしたらかなり厳しい要求をした。仕様書はダメ出ししまくり上司だろうが関係なし。
結果出来たのは仕様書とは言えないが、仕様書になりかけの要望書と言ったところ。
前職合わせても、ここ数年のWeb業界で見たなかでは確実に良い出来でしょう。
でもこのままウォーターフォールで開発を行うとテスト段階でバグが出まくるし、そもそも開発時間が少ない。そこでスクラム開発の出番だ。
今回入ってもらうスクラムマスタに当たる人と相談して、時間がないので出来るだけスクラムそのもので余計な時間を取らないように相談した。また、がっちりスクラム開発の枠にはめてもいない。
結果、今回はこうなった。
- 基本エンジニアのみにスクラム開発を適応させる
- スプリントは1週間
- ディリースクラム
- 日報、これは少しから導入しているので継続中
- KPT
- 週末の振り返りなどのMTG
- これだけはディレクタも参加する
- ホワイトボードでタスク管理
- 反対が多いのでPivotal Trackerなどのツールは使わない
- エンジニア側では別途仕様書を作成する
- 古い言い方だと内部仕様書
- Rdoc/YARD等で細かい部分のドキュメントを作成する
- Rspec等でのテストコード作成
- Jenkinsでの自動テストを実施する
まだまだ走りだしたプロジェクトだが、そこそこ前には進んでいると思う。
すでにいくつか良い意見ももらったり、効果も出てきていると思う。
個人的にはアジャイルやスクラム開発は両手を上げて賛成はしていない。
だって、OSSとかだとこんなことしなくても開発できているプロジェクトもあるし。そもそもこの業界にいてエンジニアではないにしろ勉強しない奴がいる事自体がおかしい。
もちろんテストコードを書いたり、Jenkinsでの自動テストとか好きな部分もあるのは確かだ。TDDは精神力を多大に浪費するのでしんどいけどw
良い結果が出始めている事なのは確かなので、開発の管理が出来ていないと悩んでいる方たちはこういうフレームワークをうまく取り入れれば良いとおもう。
謹賀新年
さて、年が明けました。
昨年はWebサービスを1つ作りましたが、結局先日中止しました。
http://khondalit.hatenablog.com/entry/2013/07/07/024922
仕事で忙しくなり結局停止。
時間がない中での複数人での開発は厳しいなぁというのが今の素直な気持ち。
ただ、仕事ではいくつもWebサイトを作って来ましたが、個人でも作るのは問題ないのを実感できたのが大きい。
ということで、今年の目標は真面目にWebサービスを1つは作ります。
あと、どこかで http://linuxc.info/ の更新も少しずつします。
ただ、仕事で新規プロジェクト(しかも結構無茶なの)を担当することになったので、今年前半は厳しいかもです。
バッチのテストの難しさ
さてかなり久しぶりの投稿です。
自分はかなり詰めが甘いほうで良く下らないバグをだします。ですので最近はテストコードの信者になりつつあります。
おそらく、RailsというかRubyがテストが良く書かれる文化だとは感じていますが、バッチが一番の曲者。
View側も最近はCapybaraをはじめとして受け入れテストも可能になり、またJavaScriptのテストツールも整いつつあります。
これにより以前ではかなりテストし辛い部分までテストコードを書くことが可能になっています。またJenkinsにより自動テストの環境が整い、さらにはVagrantなどでDevOpsも可能になり、私がエンジニアになった約10年ほど前とは根本的に異なる時代になって来ました。
ところが、個人的に難しいと考えているのがバッチです。
このバッチのテストが非常に難しい。自動テストを正しく行おうとすれば、現実の全データでテストを行うのが理屈上正しいのですが、バッチの実行を行うと、数日から1週間は必要という開発としてはまずありえない時間が必要になります。
Factorygirlを使ってダミーデータを用意すれば良い? それはそうなのですが、ダミーデータと言えども正常パターン、異常パターンを作成するのはまず無理。用意出来るならばすでに用意してテストもしています。
また、バッチは長年の経験を集めた実装で、また実装がテストしやすいようにはなっていない。必要な環境変数が多々必要だったり、特定の順番で複数のバッチを動作させることが前提だったり。また、リファクタリングも難しくテストコードも非常に書きづらい。
言語に限らずバッチはどこの環境でもこのような難しさを秘めている場合がほとんどな気がします。
ここ最近始めた方法として、バッチの中にtestというメソッドを用意して、最低限の動作を行う処理を書いておきテストを行う、という非常にいい加減な事をしてお茶を濁しています。
良い方法がないかこれからも探していきますが、私程度では解決方法は見つからず...。
どうしたものでしょうかね。
新規サービス公開
最終更新から1年ほど。
ここ最近色々ありまして更新できていませんでしたが、またちょっとづつ更新していこうかと思います。
最近の出来事。
色々あって、転職をしました。
今回もWeb系の会社。前職と違うのは今回のほうがユーザの生活に役に立ている点だと思います。
前職は会社としては利益がありましたが、目の前の稼ぎに対してしか見れずユーザを満足させていたかというとかなり疑問が残りました。
ここもそれなりに忙しいですが、堅実ですし良い雰囲気の会社だと思います。
さて、プライベートで開発する時間が取れるかは不安ですが、会社にだけ頼るのもちょっと問題かと思いますし頑張って行きたいです。
新サービス "2chまとめストリーム"公開!
もうすぐ1ヶ月ほど立ちますが、Railsの練習で前職の中の良い方と2人で作成しました。
http://www.2chstream.com/
よくある2ch記事のまとめサイトのまとめです。
勉強するにあたって、まずは簡単なサービスが良いと判断しました。
このサイトのようなタイプの良い所は、データを集めてそれを公開するだけです。
ユーザ管理や大量のデータを扱う必要は無く、デザインもシンプルに出来ます。
LinuxCの更新
LinuxCの更新。
忙しく手付かずになっていたLinuxCをまた少しづつですが、記事を増やしています。
その効果があったのか多少ではありますがPVが増えているようです。有難い話ですね。
IPを見るとユーザは大学や企業が多いようで、平日のアクセスが多く土日になるとガクッとPVが下がるようです。
今後
LinuxCはまだまだ書く内容はあるので少しづつ更新はしていきます。
また、個人で何か新しい開発をしていきたいですね。
HTML5メモ
最近気になるのがHTML5。
そこで色々情報をメモしてみます。
JavaScriptもHTML5と必須の知識ですがそれは次回ということで。
本
- 作者: Mark Pilgrim,矢倉眞隆(監訳),水原文
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/04/23
- メディア: 大型本
- 購入: 6人 クリック: 134回
- この商品を含むブログ (13件) を見る
最近中古で入手した本です。
HTML5までのHTMLの流れから、文章の構造や意味に焦点を置いた点、videoやcanvasをはじめとした目新しい機能の紹介等、広く浅く紹介といった内容です。
リンク
入門用
http://html5.imedia-web.net/
http://w3g.jp/blog/studies/html5report
色々情報がまとまっています。
http://hyper-text.org/archives/2009/11/html5_resources.shtml
ブラウザの対応状況など最新の情報が公開されています。
http://html5please.us/
http://caniuse.com/
http://mobilehtml5.org/
SlideShare
SlideShareでHTML5で検索して目についたのをメモ
HTML5について基礎から色々情報がまとまっています
http://www.slideshare.net/shumpei/what-is-html5-at-css-nite-osaka
こっちも同じように基礎の説明です。
http://www.slideshare.net/myakura/html5-2480964
これも基礎系
http://www.slideshare.net/futomihatano/html5-9066829
Web Intentsについて。Webのパイプのようなイメージです。
http://www.slideshare.net/shumpei/web-intents
HTML5について最新の仕様についてまとまっています。
http://www.slideshare.net/shumpei/html5api-10703643
nanocを使って静的サイトを作ろう2
前回の続きになります。
今回は新しいページの作成に挑戦します。
ディレクトリとファイルの解説
まずは前回と少し被りますが、ディレクトリの構成です。
$ ls -F Rakefile Rules config.yaml content/ layouts/ lib/ output/ tmp/ $ ls -F layouts/ default.html $ ls -F content/ index.html stylesheet.css
まず、layouts/default.htmlが全体で使われるテンプレートになります。
次に、content/index.htmlがトップページです。
処理としては、layouts/default.htmlにcontent/index.htmlが埋め込まれます。結果はoutput/に作成されます。
layouts/default.htmlの中身を見てみます。
$ cat layouts/default.html <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <title>A Brand New nanoc Site - <%= @item[:title] %></title> <link rel="stylesheet" type="text/css" href="/style.css" media="screen"> <meta name="generator" content="nanoc 3.2.3"> </head> <body> <div id="main"> <%= yield %> </div> <div id="sidebar"> <h2>Documentation</h2> <ul> <li><a href="http://nanoc.stoneship.org/docs/">Documentation</a></li> <li><a href="http://nanoc.stoneship.org/docs/3-getting-started/">Getting Started</a></li> </ul> <h2>Community</h2> <ul> <li><a href="http://groups.google.com/group/nanoc/">Discussion Group</a></li> <li><a href="irc://chat.freenode.net/#nanoc">IRC Channel</a></li> <li><a href="http://projects.stoneship.org/trac/nanoc/">Wiki</a></li> </ul> </div> </body> </html>
"<%= yield %>" という部分があります。ここにcontent/index.htmlが埋め込まれます。
この記法はERBというRubyのデフォルトのライブラリとして実装されていて、任意のテキストファイルにRubyスクリプトを埋め込む書式です。
新規ページの作成
簡単な動作を理解したところで実際に新規ページを作成します。
手っ取り早く行うためにindex.htmlをコピーして使います
$ cp content/index.html content/test.html
ちなみにページを1から作成したい場合は"create_item"オプションがあります。
$ nanoc create_item test create content/test.html An item has been created at /test/.
これが修正した内容です。
$ cat content/test.html --- title: Test <!-- 修正部分 --> --- <h1>Test Page</h1> <!-- 修正部分 --> <p>You've just created a new nanoc site. The page you are looking at right now is the home page for your site. To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:</p> <ul> <li><p><strong>Change this page's content</strong> by editing the "index.html" file in the "content" directory. This is the actual page content, and therefore doesn't include the header, sidebar or style information (those are part of the layout).</p></li> <li><p><strong>Change the layout</strong>, which is the "default.html" file in the "layouts" directory, and create something unique (and hopefully less bland).</p></li> </ul> <p>If you need any help with customizing your nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!</p>
修正部分をコメントで示しています。"Home"を"Test"に、"A Brand New nanoc Site"を"Test Page"に変更しました。
この修正を表示するために"compile"オプションを使用してhtmlを作成します。
$ nanoc compile Loading site data... Compiling site... identical [0.02s] output/index.html identical [0.00s] output/style.css create [0.00s] output/test/index.html Site compiled in 0.10s.
output/test/index.htmlが作成されているのが分かります。
新しいファイルが作成されたので表示をしてみます。
この状態でブラウザから"http://localhost:3000/test/"にアクセスしてください。修正した内容が表示されれば成功です。
$ nanoc view [2012-01-24 23:16:22] INFO WEBrick 1.3.1 [2012-01-24 23:16:22] INFO ruby 1.9.3 (2011-10-30) [x86_64-linux] [2012-01-24 23:16:22] INFO WEBrick::HTTPServer#start: pid=25689 port=3000
HTML上の階層
content/test.htmlを作成しましたが、これがHTML上の位置でどのようになるかを説明します。
これを理解していないと、サイト内リンクが作成出来ない状態のままになります。
単体ファイル
"content/hoge.html"の場合、"output/hoge/index.html"として作成されます。
このようになっている理由を想像すると、2つ理由があります。
1つ目の理由は、"content/hoge.html"にアクセスするために、"http://localhost:3000/content/hoge/"だけでアクセスできるようにという配慮だと思われます。
2つ目の理由は、複数ファイルへの対処です。これは次で説明します。
複数ファイル
"http://localhost:3000/hoge/*.html"という形で、サブディレクトリを作り複数のファイルをまとめて管理する場合の方法です。
この場合、content/hoge/というディレクトリを作成しその下にファイルを作っていく流れになります。
当初、"content/hoge.html"を作成していたが、ページが増えてきて1つのページを複数に分けたいという欲求が出てきた場合、"content/hoge/"を作成し、次に"content/hoge.html"を"content/hoge/index.html"にするだけで対応ができます。
最初からこのようにサブディレクトリを作成したい場合は"create_item"オプションで一度に作成できるようになっています。
$ nanoc create_item hoge/index create content/hoge/index.html An item has been created at /hoge/index/.
あとはhoge/index.htmlを修正し、新しいファイルが欲しければ"create_item"オプションを使えば良いのです。
URLはどうなるか?
"content/test.html"の場合、"http://localhost:3000/test/index.html"というリンクになります。
これを確かめるために"content/index.html"にこのように"test/"へのリンクを作成してみます。
$ cat content/index.html --- title: Home --- <h1>A Brand New nanoc Site</h1> <a href="test/">test page<a> <!-- 追加 --> <p>You've just created a new nanoc site. The page you are looking at right now is the home page for your site. To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:</p> <ul> <li><p><strong>Change this page's content</strong> by editing the "index.html" file in the "content" directory. This is the actual page content, and therefore doesn't include the header, sidebar or style information (those are part of the layout).</p></li> <li><p><strong>Change the layout</strong>, which is the "default.html" file in the "layouts" directory, and create something unique (and hopefully less bland).</p></li> </ul> <p>If you need any help with customizing your nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!</p>
compileを行うとリンクが作成されてリンクをクリックすると正しく移動する事が分かります。
いかがだったでしょうか? nanocを使うと空ページのテンプレートの作成やディレクトリ構成を深く考える必要が無く、簡単にHTMLを作成できる事ができました。
次回は、コンパイル時のルール修正について解説します。