卜部昌平のあまりreblogしないtumblr RSS

Archive

Jan
27th
Fri
permalink

Vaio Xを偲んで

  • よかった

    • 薄い。マジ薄い。MacBook Air買ってドヤ顔してる輩の前で取り出して作業するだけで一発で完膚なきまでに黙らせられるので非常に気味がよい。
    • 軽い。のにちゃんと使える。軽いだけのお遊びマシンなら他にもある。これはちゃんと仕事に使える。のに軽い。
    • あと安い。買って半年の時点ですでにじゅうぶん元はとれたと思った。
    • バッテリー。この薄い本体にバッテリー入れる余地なんかないと思ってただけに、じゅうぶんな起動時間が得られて満足。Lバッテリーで足りなかったのは結局、日米間の飛行機だけ。
    • ACアダプタも小さくて持ち運び邪魔にならなかった。
    • 正直ノートPCの液晶にさして期待してなかったがいい意味で裏切られた。きれい。
    • ポート類の取捨選択は神懸ってる。すべてのポートの利用を経験し、かつ足りなくて困ったポートはない。……まあメモリースティックの穴だけは別になくてもとは思うが。
    • 内蔵WWANデバイス。Linuxからも普通にponできて大活躍。「あれ卜部さんなんでネット繋がってんの」は少々答えるのに飽きてきたくらい。昔、本田エレクトロンが本体からはみださないエアエッジカード出してたけど、あの感じ。
    • Windows7そんなに悪くないじゃん。
    • ファンがついてるけどそんなにうるさくない。そういえばそんな部品もありましたね、程度の音。
  • よくなかった

    • クソPoulsbo。Intelのくせに変なチップセット付けんなよ。なぜ素直にGMA950を載せずにわざわざ他社からOEMしてきたのか理解に苦しみすぎる。Linux版のドライバの出来が悪い程度の話なら笑って流せるが、実際には一時期Windowsに提供されているドライバよりもLinuxのほうがポテンシャルを発揮していた時期もあったくらいで、ようするにIntelすらもまともに制御できてたとは言い難い。
    • ソニータイマー神話を完全に覆す、保証期間内で都合3回の修理対応。華奢すぎる。「極限まで薄くするためにマザボ片面実装にしました」とか、いやそりゃ凄いことではあるんだけど、努力する前に少々方向を考えるべきだったんじゃないかというか、まあ、ぶっちゃけ攻めの姿勢は評価したい。でもそれ以上じゃないな。結果残さんとな。
    • 上で「半年の時点で元はとれた」って書いたけど、その後の有償修理でコストパフォーマンスが悪化。すでにもう1台買えるだけの金額は投下した。だらだらとお金が出て行く感じ。
    • バッテリーはやはり無理して詰め込んでいるので、その余波でトラックパッドの位置がおかしい。きちんとホームポジションに手を置いて作業する人ほどミスタッチが多いはず。
    • 微妙にフルピッチじゃないキーボード。これがVaio Pくらいがっつり小さければ別物として扱えるのだが。
    • たぶんもうチップ貼る場所がないんだろうけど、メモリもうちょっとあるとありがたかった。これはまあ無いものねだりなんだろうけどね。
  • もとから期待してなかった

    • Atom。あるいみ前評判通り。
    • SSD。これがはじめて使うSSDだったらひょっとして感動してたのかもね。でもSSDとして見ればさほどどうというレベルではないというか。
    • スピーカーとかマイクはおまけ以上の何者でもないがまあ他のPCでもたいがいこんなもん。
  • 総合して

    • ある種の突き抜けた製品だったのは間違いない。
    • 逆にいうと良くも悪くもコンサバティブな構成ではなかった。
    • とはいえべつに一部のマニア向けといったわけではなく、「CPUとかGPUとかいらんから薄くて軽くてネットに繋がる端末」としてちゃんと誰が見ても良さが分かる形になっていたのでさすが。そして色々問題がありつつも、そのアピールポイントに関してはじゅうぶん以上に役に立った。
    • 後継機種が出てないけど、まあそうだろ。無難に倒しだすと良さが削がれるだろうし、かといってこれ以上攻めるともはや別コンセプトになるだろうし。
    • というわけで個人的にはスペック見直しとかせずにそのまま生産続けてくれてれば買いなおしも選択肢のうちだったんだけど、生産中止じゃあしょうがないよね。惜しいマシンをなくしました。
Jan
4th
Wed
permalink

「新宿駅攻略本」は間違ってるんじゃないかという気がする

新宿駅攻略本 ver. DEC. 2011 なる 薄い本 を入手したので興味深く読んでいるわけだが。さすがに新宿駅ユーザー歴10年の俺くらいになるともう攻略本に知らないことなんて載ってな……あれ?

上図の中央西口(京王口)の化粧室を撮影しようとしたが、見当たらなかった

って書いてあるけど、俺このトイレ知ってるよ? 使ったことあるもん。


問題の図(俺撮影)と問題のトイレアイコン(白丸)

このトイレってこれでしょ:

違うのかなあ。俺はこのトイレだと思うんだけど。たしかにこの問題の図は混乱を招く書き方をしてある。がそれは図の作者が悪いというよりは、駅の構造自体が悪いんじゃないかなあ。

過去の関連エントリ:

Dec
20th
Tue
permalink

http://rubyamqp.info/articles/error_handling/ の和訳。脚注は訳者による。


エラーの取扱いと復旧

このガイドについて

送信側であれ受信側であれ、多岐に渡る異常系をどうエレガントに扱うかが、AMQPと関わりのあるアプリケーションを頑健にしていくうえでは不可避と言えましょう。プロトコルの誤り、ネットワークの不調、ブローカー1の異常などが思い浮かぶことでしょう。これらを正しく処理して上手に正常状態に回復することは、容易ではないでしょう。以下では、amqp gemを使うことでアプリケーションが

  • ブローカーとの接続ができなかったとき
  • ネットワークが切断されたとき
  • AMQPコネクションに例外2が発生したとき
  • AMQPチャンネル3に例外が発生したとき
  • ブローカーの異常に遭遇したとき
  • TLS(SSL)関連の障害があったとき

のような状況をどのように切り抜けることができるか、のみならず

  • ネットワーク切断からの復旧をどうするか
  • 自動回復モードとは何か、それはいつ使うべきで、いつ使うべきでないか

を解説いたしましょう。

この 作品 は クリエイティブ・コモンズ 表示 3.0 非移植 ライセンスの下に提供されています4。原文のソースはGithubから入手可能でございます。

対象とするバージョン

このガイドは Ruby amqp gem のバージョン v0.8.0RC14 以降が対象でございます。

サンプルプログラムについて

私達の git レポジトリには、この件に関連したサンプルプログラムがいくつかございます。もしも新しいサンプルをお書きになった方がおられましたら、この一覧に加えたく思いますので、ご連絡いただけますでしょうか。

ブローカーとの接続失敗について

アプリケーションは当然にブローカーと接続するわけですが、このときの接続失敗をどうにかして取り回すことが必要でございましょう。信頼性のあるネットワークなどというものは幻想でございましょう。ChefやPuppetといった現代的なシステム設定ツールを用いても設定ファイルの書き間違いは防げませんでしょうし、ブローカーのプロセスは何かの弾みで落ちることもございましょう。これらの状況はできるだけ速やかに検知される必要がございましょう。

私達はTCP層の接続障害を検知するための方法を二種類ご用意さしあげております。ひとつめは、Rubyレベル例外を捕捉することです:


begin
  AMQP.start(connection_settings) do |connection, open_ok|
    raise "This should not be reachable"
  end
rescue AMQP::TCPConnectionFailed => e
  puts "Caught AMQP::TCPConnectionFailed => TCP connection failed, as expected."
end

上記を含んだプログラム一式だとこうなります:

AMQP.connect (及び AMQP.start) においては、接続に失敗すると AMQP::TCPConnectionFailed 例外を raise いたします。これを rescue していただきますと、アプリケーションは例えばログを吐いたりとか、再接続を試みたりといったことが可能になりますことでしょう。

ところでブローカーへの接続に失敗した時というのは、ようするにネットワーク障害だとか、設定ファイルの書き間違いだとか、そういった理由であることが大半と思われます。このような状況下におきまして、安易に再接続を試みるというのは、いかがなものでしょうか? 同じエンドポイントに対して再接続を試みても同じエラーが何度も起きるだけである蓋然性が高うございましょう。(フェイルオーバーとクラスタ構成にかんして後で書く5)

障害検知のその他の方法としてはエラーバック(特定のエラーを処理するためのコールバック)によるものがございます:


handler             = Proc.new { |settings| puts "Failed to connect, as expected"; EventMachine.stop }
connection_settings = {
  :port     => 9689,
  :vhost    => "/amq_client_testbed",
  :user     => "amq_client_gem",
  :password => "amq_client_gem_password",
  :timeout        => 0.3,
  :on_tcp_connection_failure => handler
}

上記を含んだプログラム一式だとこうなります:

:on_tcp_connection_failure には #call メッセージに反応する任意のオブジェクトを指定していただけます。

もしも、サンプルプログラムのようにトップレベルから接続を張るのではなくて、クラスの中から接続しにいくことを選択された場合、 Object#method でインスタンスメソッドをオブジェクト化して渡していただけるようになってございます(例をあとで書く)。

認証失敗について

接続に失敗するその他の理由としては認証に失敗することがあげられましょう。認証の失敗に関しましては接続の失敗とおおむね同様に処理していただけます:

デフォルトハンドラ

このエラーバックが省略された場合には、認証に失敗すると AMQP::PossibleAuthenticationFailureErrorraiseいたします。

この例外名に含まれる “possible” に一抹の不安がよぎる方もおられましょう。これには理由がございます。AMQP 0.9.1 プロトコル仕様によりますと、ブローカーの実装は、AMQPコネクションが確立する以前に発生した例外的状況(認証の失敗もこれに含まれましょう)においては、なんらの応答を返すことなく、単にTCPのセッションをシャットダウンせよと規定されているのです。

ただ、実のところ、TCPセッション・ハンドシェイクが終了してから、AMQPコネクションが確立するまでに、どのような状況が起こりうるかを考えますと、認証の失敗以外にないのではと存じております。

ネットワーク切断のとりまわし

小規模なプロダクト、小規模なプロジェクトであっても、こんにちにあっては複数のアプリケーションで構成されているのはあたりまえでございますし、それらが複数のマシンにまたがっているのも、日常的に見かける景色と言えましょう。現代のソフトウエア・システムにおいては、ネットワークに発生する問題は悪夢と言わざるを得ません。Ruby amqp gemでは、それらのTCPコネクションの問題を AMQP::Session#on_tcp_connection_loss で登録したブロックで処理していただくことができるようになっております。このブロックはTCPコネクションに問題が発生した時に、コネクションのオブジェクトと、それまでのコネクションの接続設定を引数にとりながら呼ばれます。


connection.on_tcp_connection_loss do |connection, settings|
  # reconnect in 10 seconds, without enforcement
  connection.reconnect(false, 10)
end

アプリケーションの作りによってはAMQP::Session以外の構成要素にてネットワーク切断への対処をしたい場合もございましょう。かような要求をかんがみまして、amqp gem 0.8.0以降では他にも多数のハンドラを用意しております。これらのハンドラを総称して私達は「シャットダウン・プロトコル」と呼んでおります(ここでいうプロトコルは日本語でいえば「約束」くらいの意味でございます。ネットワーク・プロトコルではございません)。

シャットダウン・プロトコルに対応しているのはAMQP::Session, AMQP::Channel, AMQP::Exchange, AMQP::Queue, AMQP::Consumerですのでこれらはすべて同様に取り扱っていただくことができます。また AMQP::SessionAMQP::Channelに関しましては追加でいくつかのハンドラがございます。

シャットダウン・プロトコルはおおむね以下の二つの事象を扱います:

  • ネットワークの切断
  • ブローカーからのコネクションの切断

前者に関して注目してご説明致しましょう。ネットワークが切断した際には、まず下位層がそれを検知して AMQP::Sessionのコードを起動します。その結果、ネットワーク切断の事象は上位の AMQP::Channelへ伝播します。AMQP::Channelは事象をさらにAMQP::ExchangeAMQP::Queueに伝播させて、AMQP::Queueは(あれば)AMQP::Consumerに伝播させます。このようにして、セッションに参加しているすべてのオブジェクトはネットワークの切断を知ることができ、アプリケーションが指定したコールバックを実行することができるようになっております。

AMQP::Session6 のシャットダウン・プロトコル

  • AMQP::Session#on_tcp_connection_loss
  • AMQP::Session#on_connection_interruption

これらの何が違うかというお話でございますが、AMQP::Session#on_tcp_connection_lossはTCPコネクションが切断された 初回 にて実行されます。ところが、再接続の要求は必ずしも初回にて達成されるとも限りませんものですから、何回かは失敗する事が想定されましょう。それらに毎回反応したいニーズがございましたら、AMQP::Session#on_connection_interruptionをお使いいただけるということになってございます7

先述の通りこれらのメソッドにはブロックをつけて呼んでいただいております。ブロックが呼ばれる際にはコネクションオブジェクト自身が引数として渡ってまいりますので、Procではなくメソッドオブジェクトを渡していただく場合であっても、インスタンス変数に余計な状態変数のようなものを保存していただく必要はございません:


connection.on_connection_interruption do |conn|
  puts "Connection detected connection interruption"
end

# or

class ConnectionInterruptionHandler

  #
  # API
  #

  def handle(connection)
    # handling logic
  end

end

handler = ConnectionInterruptionHandler.new
connection.on_connection_interruption(&handler.method(:handle))

もし余所でもハンドラを定義しているのであれば、AMQP::Session#on_connection_interruptionにて登録されたコールバックは他のチャンネルやキューへ事象が伝搬するよりも に呼ばれるという点にご注意くださいませ。

コネクションの切断にどう対処すべきかは、アプリケーションによるとしか申し上げられません。しかしながらよくある戦略としましては、AMQP::Session#reconnectを用いて同じホストに再接続するか、あるいはAMQP::Session#reconnect_toを用いて別のホストを試すといったものがございましょう。

アプリケーションによってはそのようなことをせず、単にプロセスを終了してしまって、外部のたとえばNagiosであるとかMonitといった監視システムに再起動させるので充分かもしれません。

AMQP::Channel8 のシャットダウン・プロトコル

AMQP::ChannelにはAMQP::Channel#on_connection_interruptionのみがございます。このメソッドは前の章のメソッドとだいたい同じで、渡されたブロックを登録するものでございます:


channel.on_connection_interruption do |ch|
  puts "Channel #{ch.id} detected connection interruption"
end

しかしながらご注意いただきたいのは、AMQP::Channel#on_connection_interruptionにて登録されたコールバックはエクスチェンジやキューに事象を伝播した だということでございます9。チャンネルの状態がリセットされた直後からこれらのエラーハンドリングが開始されるとお考えください。

なお多くのアプリケーションではチャンネル単位でのネットワークエラーの取り回しは不要かと存じます。

AMQP::Exchange10 のシャットダウン・プロトコル

AMQP::ExchangeにはAMQP::Exchange#on_connection_interruptionのみがございます。このメソッドは前の章のメソッドとだいたい同じで、渡されたブロックを登録するものでございます:


exchange.on_connection_interruption do |ex|
  puts "Exchange #{ex.name} detected connection interruption"
end

なお多くのアプリケーションではエクスチェンジ単位でのネットワークエラーの取り回しは不要かと存じます。

AMQP::Queue11 のシャットダウン・プロトコル

AMQP::QueueにはAMQP::Queue#on_connection_interruptionのみがございます。このメソッドは前の章のメソッドとだいたい同じで、渡されたブロックを登録するものでございます:


queue.on_connection_interruption do |q|
  puts "Queue #{q.name} detected connection interruption"
end

AMQP::Queue#on_connection_interruptionで登録されたコールバックはこの事象がコンシューマに伝播された から動き出すことにご注意ください。

なお多くのアプリケーションではキュー単位でのネットワークエラーの取り回しは不要かと存じます。

AMQP::Consumer12 のシャットダウン・プロトコル

AMQP::ConsumerにはAMQP::Consumer#on_connection_interruptionのみがございます。このメソッドは前の章のメソッドとだいたい同じで、渡されたブロックを登録するものでございます:


consumer.on_connection_interruption do |c|
  puts "Consumer with consumer tag #{c.consumer_tag} detected connection interruption"
end

なお多くのアプリケーションではコンシューマ単位でのネットワークエラーの取り回しは不要かと存じます。

ネットワーク切断からの復旧

ネットワーク障害を検知しただけで復旧できないのであれば、検知した意味はほとんどないと言えましょう。復旧は「エラーの取り回しと復旧」のなかでも困難な部類に属する話題ではございますが、幸いにしてだいたいのアプリケーションにおいて同じ戦略が有効ですので、Ruby amqp gemでは自動でそれを行うことも可能になっております。

自動であれ手動であれ、障害からの復旧はまずAMQPのコネクションを再接続して、チャンネルを開き直すところから始まります。

手動復旧13

シャットダウン・プロトコルと同様に、復旧する側にもリカバリ・プロトコルを提供してございます。コネクション、チャンネル、キュー、コンシューマ、エクスチェンジのすべてで、以下の3メソッドがご利用いただけます:

  • AMQP::Session#before_recovery
  • AMQP::Session#auto_recover
  • AMQP::Session#after_recovery

これらもやはりコールバックを登録するのでございますが、たとえばAMQP::Session#before_recoveryの場合におきましてはTCP層のセッションが再確立したでかつAMQPのコネクションを再構成するに呼ばれ、あるいはAMQP::Session#after_recoveryですとAMQPコネクションが再構成されたに呼ばれるというふうになっております。

AMQP::Channel, AMQP::Queue, AMQP::Consumer, AMQP::Exchangeのすべてにおきましてこれらのメソッドの挙動は同様でございます。

大抵の場合、コネクション切断からの復旧手順は以下のようになることでしょう。

  1. AMQPコネクションを再確立します
  2. そのコネクションを使ってチャンネルを再構成します
  3. それぞれの復活したチャンネルにおいて、エクスチェンジを宣言しなおします
  4. それぞれの復活したチャンネルにおいて、キューを宣言しなおします
  5. キューの宣言が終わったら、バインディング14を作成しなおします
  6. キューの宣言が終わったら、それぞれの復活したキューにおいて、コンシューマを作成しなおします

自動復旧

大多数のアプリケーションでは:

  • チャンネルを開きなおして、
  • 各チャンネルでエクスチェンジを宣言しなおして
  • 各チャンネルでキューを宣言しなおして
  • 各キューでバインディングを作成しなおして
  • 各キューでコンシューマを作成しなおす

という、同じ戦略の復旧が行われますことから、amqp gemではこの戦略を行う自動復旧の機能がオプトイン(明示的に指定した場合のみ)で提供してございます。AMQP::Channelにて以下の属性をご指定ください:


ch = AMQP::Channel.new(connection)
ch.auto_recovery = true

より冗長には以下のようにしていしていただくこともできます:


ch = AMQP::Channel.new(connection, AMQP::Channel.next_channel_id, :auto_recovery => true)

この場合には第二引数が明示してございますが、これは本来省略可能でございますので、オプションを指定しない限りは明示する必要はございません(AMQP::Channel.next_channel_idは省略時のデフォルトでございます)

あるチャンネルが自動復旧モードかどうかはAMQP::Channel#auto_recovering?でご確認いただけます。

自動復旧モードは任意の回数だけ有効/無効を切り替えてお使いいただけますが、実際にそのように使われる用途はほとんどないかと存じます。ごく常識的に考えまして、自動復旧モードを使われるかどうかはアプリケーションの設計上の問題でございましょう。

プログラム一式だとこうなります(スクリプトが起動したら、既に裏で動いているはずのAMQPブローカーをシャットダウンして、もう一回立ち上げなおしてください。rabbitmqctlのようなブローカーの側のツールでキュー、エクスチェンジ、バインディング、コンシューマが復旧している事をご確認ください):

なおキューの名前空間の衝突を防ぐため、サーバが勝手に名前をつける(ようにこちらからブローカに依頼した)キューが自動復旧すると 名前が変わります ことにご注意くださいませ。

よく分からないときは、まず自動復旧をお試しください。それでアプリケーションのニーズに沿わないとご判断された場合には、手動復旧の節でご紹介したコールバックをお使いいただけます。

ブローカー側障害の検出

AMQPを用いるアプリケーションにおきましてはブローカーの障害はTCPコネクションの切断として観測されます。ネットワークの障害とブローカーの障害を切り分ける信頼性のある方法はございません。

AMQPコネクション例外15

コネクション例外の取扱い

コネクション例外は稀ではございますが、発生の暁にはクライアント側のライブラリに重大な問題が発生しているか、さもなくばネットワーク上でデータが化けているなどの状況が想定されます。かような状況下におきましては、もはやこのコネクションは使用できませんので、切断する必要がございましょう。この種のシチュエーションは、いずれにせよなんらかの対処が必要な状況であるといえましょう。AMQP::Session#on_errorにてハンドラをご登録ください。このブロックには、二つのオブジェクトが渡ってまいります:


connection.on_error do |conn, connection_close|
  puts "Handling a connection-level exception."
  puts
  puts "AMQP class id : #{connection_close.class_id}"
  puts "AMQP method id: #{connection_close.method_id}"
  puts "Status code   : #{connection_close.reply_code}"
  puts "Error message : #{connection_close.reply_text}"
end

上記でステータスコードと呼んでいるものはHTTPに類似しております。網羅的な一覧が必要な方はAMQP 0.9.1 constants referenceをご参照ください。

なおコネクション例外ハンドラは一つしか登録できませんのでご注意ください。最後に登録したものが勝ちます。

上記を含んだプログラム一式だとこうなります:

グレースフル・シャットダウン

AMQPブローカーが正常に終了するときには、コネクションを終了するための正規の手順というものが規定されてございます。ブローカーはAMQPメソッドconnection.closeを発行してまいりますので、クライアント側ではそのステータスコードが320 CONNECTION_FORCEDであるかどうかでグレースフルなシャットダウンかどうかを判定していただけます。たとえばRabbitMQの場合、サーバが

rabbitmqctl stop

にて終了した場合は、ステータスラインは

CONNECTION_FORCED - broker forced connection closure with reason 'shutdown'

となります。

グレースフル・シャットダウンに対してアプリケーション側がどのように振る舞うべきかにはこれといった普遍的な方針はございません。したがいましてamqp gemの自動復旧モードではグレースフル・シャットダウンに対しては再接続を行わないようにしてございます。そのような場合にも再接続を望まれる場合はAMQP::Session#periodically_reconnect16をお使いいただけます:


connection.on_error do |conn, connection_close|
  puts "[connection.close] Reply code = #{connection_close.reply_code}, reply text = #{connection_close.reply_text}"
  if connection_close.reply_code == 320
    puts "[connection.close] Setting up a periodic reconnection timer..."
    # every 30 seconds
    conn.periodically_reconnect(30)
  end
end

コネクションが再開した後には自動復旧の手順はネットワーク切断からの復旧と同様に行われます。

コネクション例外をRubyのオブジェクト指向プログラミングに統合する

エラーの取り回しはRubyのオブジェクト指向プログラミングに素直に統合していただけます。むしろ推奨されている、とここでは申し上げておきましょう。よく使うのはObject#methodMethod#to_procを組み合わせてエラーハンドラにメソッドを登録する方式です:


class ConnectionManager

  #
  # API
  #

  def connect(*args, &block)
    @connection = AMQP.connect(*args, &block)

    # combines Object#method and Method#to_proc to use object
    # method as a callback
    @connection.on_error(&method(:on_error))
  end # connect(*args, &block)


  def on_error(connection, connection_close)
    puts "Handling a connection-level exception."
    puts
    puts "AMQP class id : #{connection_close.class_id}"
    puts "AMQP method id: #{connection_close.method_id}"
    puts "Status code   : #{connection_close.reply_code}"
    puts "Error message : #{connection_close.reply_text}"
  end # on_error(connection, connection_close)
end

上記を含んだプログラム一式だとこうなります:

詳細はあとで書く。

AMQP チャンネル例外

チャンネル例外の取り扱い

チャンネル例外はコネクション例外よりはまだありがちと言えましょう。ただ、どのみち同じようにAMQP::Channel#on_errorを使ってコールバックを登録していただくことで対処可能です。このブロックはチャンネル例外発生時に二つの引数とともに呼ばれます:


channel.on_error do |ch, channel_close|
  puts "Handling a channel-level exception."
  puts
  puts "AMQP class id : #{channel_close.class_id}"
  puts "AMQP method id: #{channel_close.method_id}"
  puts "Status code   : #{channel_close.reply_code}"
  puts "Error message : #{channel_close.reply_text}"
end

上でstatus codeと呼んでいるものはHTTPと同様でございます。網羅的な一覧とその解説がAMQP 0.9.1 constants referenceにございます。

なおチャンネル例外ハンドラは一つしか登録できませんのでご注意ください。最後に登録したものが勝ちます。

上記を含んだプログラム一式だとこうなります:

コネクション例外をRubyのオブジェクト指向プログラミングに統合する

エラーの取り回しはRubyのオブジェクト指向プログラミングに素直に統合していただけます。むしろ推奨されている、とここでは申し上げておきましょう。よく使うのはObject#methodMethod#to_procを組み合わせてエラーハンドラにメソッドを登録する方式です。コネクション例外の章にあります例もご参照ください。

チャンネル例外は様々に無関係な理由により上がってまいりますうえに、おおむねの場合は設定ミスが根本的な原因でございましょう。したがいまして、これをどう対処するべきかと申しますのは一概に申し上げるのは大変に困難でごさいましょう。ログでも吐いて別のチャンネルを開いて使う、程度のことしか申し上げられません。

よく起こるチャンネル例外とその意味

いくつかのチャンネル例外はよく起こりますと同時に、若干の注意を要します。

406 Precondition Failed
概論
クライアントの要求は拒否されましたが、それは何らかの事前条件を満たさなかったためです。
考えられる原因
  • AMQPエンティティ(キューとかエクスチェンジ)が指定した設定とは異なる設定で既に存在している場合。接続しているアプリケーションが2つあって、互いに違った設定で動いている、などが考えられましょう。またAMQPクライアントライブラリのデフォルトがバージョン間で違うために起こる可能性もございましょう。
  • `AMQP::Channel#tx_commit`か`AMQP::Channel#tx_rollback`を呼んだが、そのチャンネルではまだ`AMQP::Channel#tx_select`を宣言することでトランザクションモードに遷移する前だった場合。
たとえばRabbitMQだとこんなエラーが
  • PRECONDITION_FAILED - parameters for queue ‘amqpgem.examples.channel_exception’ in vhost ‘/’ not equivalent
  • PRECONDITION_FAILED - channel is not transactional
405 Resource Locked
概論
クライアントはAMQPエンティティを操作しようとしましたが、それは他のクライアントが現在操作中でした
考えられる原因
  • キューにはexclusiveという設定が可能です。複数のアプリケーション(あるいは同じアプリケーションでも別のスレッドとかプロセス)が同時にそのようなキューを宣言しようとすると、そのうちの一つのみが成功してあとはこの例外になります。
  • コンシューマにもexclusiveという設定が可能です。コンシューマのexclusiveはキュー単位です。ひとつのキューに複数のコンシューマがexclusive登録しようとした場合に発生します。
たとえばRabbitMQだとこんなエラーが
RESOURCE_LOCKED - cannot obtain exclusive access to locked queue ‘amqpgem.examples.queue’ in vhost ‘/’
403 Access Refused
概論
セキュリティ上の理由によりクライアントの要求は拒否されました
考えられる原因
アプリケーションが認証に用いたユーザーでは、キューやエクスチェンジにアクセスする権限がない、あるいは全くないってわけじゃないんだけど書き込み権限がないなど、不適切であることが考えられましょう。
たとえばRabbitMQだとこんなエラーが
ACCESS_REFUSED - access to queue ‘amqpgem.examples.channel_exception’ in vhost ‘amqp_gem_testbed’ refused for user ‘amqp_gem_reader’

TLS (SSL) 関連

あとで書く。17

まとめ

プログラマ諸賢におかれましては分散アプリケーションのエラー状況はそうじゃない場合と比べてまったく異質であることをご認識いただく必要がございましょう。それらの多くが、ネットワークの信頼性(のなさ)に起因するものでございましょう。この分野で有名な分散コンピューティングの落とし穴という、 ソフトウエアエンジニアが陥りがちな誤った認識のリストがございます:

  • ネットワークには信頼性がある
  • ネットワークにはレイテンシが存在しない
  • ネットワークの帯域幅は無制限である
  • ネットワークはセキュアである
  • ネットワークのトポロジーは変化しない
  • ネットワーク管理者は、必ず存在するし、たかだか一人である
  • ネットワークに転送コストはない
  • ネットワークはホモジニアスな構成である

この一覧は90年代に作られましたが、こんにちいささかも色褪せてはいないでしょう。残念ながらRubyやAMQPを使ったところでこれらの問題から逃れられるわけではございませんでしょう。開発者はこの事実を心に留めておく必要がございましょう。

0.8.x以降のruby amqp gemではアプリケーション側からハンドラを登録することで、コネクション例外、チャンネル例外や、TCP層での接続の問題を取り回していただけます。セッションが復旧したあとのAMQPエンティティの再宣言が複雑なのでして、AMQPの例外やネットワーク切断は、比較的容易な部類と言えましょう。rubyのオブジェクトをエラーハンドラとして用いると、AMQPエンティティの宣言を一ヶ所にまとめることができるでしょう。これは理解も容易になりますし、保守の観点からも好ましいでしょう。

amqp gemのエラーハンドラはJava版RabbitMQクライアントのShutdown Protocolのコピペではこざいませんが、結果的にネットワーク切断やコネクション例外に関しては似たような感じに収斂進化したようです。

まだあとで書く。

著者について

このガイドはMichael Klishinによって書かれ、Chris Duncanの手が入っています18

ご感想をお待ちしています

このガイドに関するご感想をTwitter上Ruby AMQPメーリングリストでお聞かせください。分からないことはございましたか? 書き漏れている点はございませんでしょうか? スペルミス、文法の誤り、お前の口調が気にくわない等ございませんか? 読者の声がドキュメントをよくする一番の方法です。よろしくおねがいします。

何らかの理由でMLでは連絡をとりたくない場合は、ガイド作者にじかにご連絡いただくこともできます


  1. 一般的な感覚で言えばAMQPサーバーのこと。RabbitMQなど。メッセージキューの側から見ればどちらがサーバーでどちらがクライアントかは必ずしも明確ではないので、AMQPではブローカーという用語を好む模様。 

  2. ここでいう例外はRubyレベルの例外ではなくて、HTTPで言えば 404 Not Found みたいなやつのこと。 

  3. AMQPでは一本のTCPセッションに複数の互いに異なる通信路を相乗りさせることができる(sshのそれと似ている)。この論理的な通信路をチャンネルという。 

  4. もちろん和訳もCC BY 3.0に従う。 

  5. これは本当に原文に後で書く(TBD)と書いてある。 

  6. セッションはTCP層の直上に位置し、OSI参照モデルでいうところのセッション層に相当すると思われる概念。 

  7. が、本当にそうなのか? というのは、俺の手元ではよく分からん。なんかどっちも毎回出てないか? 

  8. チャンネルについては前述の通り。一個のセッションは複数のチャンネルを持ちうる。 

  9. なぜ実装を直そうとせずにわざわざドキュメントに注記するのかが理解できないが…… 

  10. エクスチェンジはErlangでいうところのメールボックスに近い。ここにめがけてメッセージを送信する。当然、このオブジェクトの本体はブローカーの側に存在する。Rubyの側で見えているのはプロキシオブジェクト。 

  11. キューはキューであって、ここにメッセージがたまってくるわけで、これも本体はブローカーの側にある。のでRubyの側で見えているのはプロキシオブジェクト。 

  12. コンシューマはキューのこちら側でキューからメッセージを引っこ抜いてくる用途のオブジェクト。 

  13. 手動といってもホモサピエンスの前脚が関与するわけではないが、”Manual Recovery”を他にどう訳せというのだ? 

  14. バインディングはエクスチェンジに投げられたメッセージがどのキューに届くべきかを決めるための関連付け。これもブローカーの中にある。 

  15. 繰り返しになるがここでいう例外はRubyのそれではない。別の言い方をすると、AMQPにおいては例外的状況になっても、Rubyの例外としては上がってこない。注意を要する。 

  16. このメソッドはruby-amqpのyardには記載がないけど、呼んでみると動く。隠しメソッドか。 

  17. これはひどい… 

  18. 日本語訳は卜部昌平による 

Oct
22nd
Sat
permalink

深夜の秋葉原ごはん

ここでは主に日が変わってからやってる店をピックアップ。

  • コンビニチェーン系

    その昔秋葉原といえばコンビニ不毛地帯という時期も短くなかったわけだけれども、最近では一通りは揃っているといえるだろう。件数的にはファミマがなぜか多め。

    ただまあ店内では食べれないよね。

  • 牛丼チェーン系

    豊富な方だろう。すき家吉野家松屋なか卯神戸らんぷ亭全部あるなそう言えば。吉野家は夜やってない店があるので注意。

  • マック

    たくさんあるけどどこで食べてもメニューが同じという意味では深夜の秋葉原においては少々過剰ぎみ。

  • ファミレス

    ワシントンホテルのなかにデニーズ、神田明神下にココス、妻恋坂にジョナサン。中央通りのロイヤルホストは5時まで、サイゼリヤは(あるけど)夜中は閉まる。ファミレスは単価高いけど仕事が終わった後にゆったりするときに重宝する。

  • 中華

    いつのまにか24時間営業になっていた日高屋、前から24時間だった幸楽苑がある。

  • 和食

    富士そばが駅の東西に各一店。あとヨドバシの下にすしざんまい。

  • カレー

    中央通りシディークは5時まで。昭和通りに珍しい24時間営業のココイチがある。

  • ラーメン

    意外にない。威風が4時まで、風龍が3時までで、他はだいたい0時には閉まる?

その他

  • 曜日によっては遅くまで営業しているところもある。たとえば富士ソフトの下のHubは金曜だけ3時まで。

  • ドンキ下のクレープ屋は営業時間がいまいちよく分からない。やってることもある。

  • ご飯目的で行く所じゃないが、ディアステージも(開いてれば)一応飲食可ではある。

  • まあこれもご飯目的で行く所じゃないが、パセラとカラオケ館がそれぞれ複数ある。

  • 南側は神田の、北側は上野の徒歩圏なので、それらのほうに向かってみるのも選択肢の一つだろう。

Oct
16th
Sun
permalink

RubyConf2011終了しました

おかげさまで無事でした。各方面、認識している以外にも様々にご迷惑をお掛けしたと思います。この場を借りてお礼申し上げます。

まだ収支をちゃんと計算しておりませんが、今回は初めてだったので様々なものがどんぶり勘定だったという点と、勝手が分からなかったので 金で解決できることは金に任せる 方針も手伝って、例年の一人旅とくらべてわりとゴージャスな感じになりました。とはいえ現状の概算ではこれでも嫁さんを養うことを思えば全然何倍も安いので、一応、独身の間は続けてもいいかなあという気にはなってきております。

よかった点

  • 無事。
  • 参加者から好評を得た。
  • 種は蒔いたので次は継続的に育むことかと。

よくなかった点

  • 募集要項は改善の余地がある。
  • 事務手続きがごたごたしてしまった。
  • 各種法人さんに相談せずに一人でやったのは、今回は既成事実を作るための確信犯だけど、次回はそうもいかんだろう。
Aug
5th
Fri
permalink

【第四報】RubyConf2011旅費出しますから行ってきて

たくさんのご応募ありがとうございました。厳正なる抽選の結果採択率100%の狭き門を突破されたのは以下のお二方です:

おめでとうございます。当選した方々には私からは特には課題を出したりしませんが、Rubyist MagazineというWeb雑誌がRubyConf特派員として徴募しにくる可能性をあまり否定しないので、もし本当に来たらその時は各自で対応してください。

今回のアナウンスは以上です。

Jul
22nd
Fri
permalink
[Flash 10 is required to watch video]

RubyKaigi来て英語勉強しなきゃと思ったでしょ? まさか思わなかったの?

  • 副題: RubyKaigiのビデオを翻訳しましょう
  • 副題: 日本語話者のおまえらにもよくわかるファンサブ(ハードサブ)の作り方
  1. (オプション)Windowsを窓から投げ捨ててGentooをインストールします
  2. emerge aegisub
  3. emerge avidemux
  4. (オプション)aegisubでぐぐってaegisubについて学びます
  5. (オプション)avidemuxでぐぐってavidemuxについて学びます
  6. VimeoのアカウントをとってVimeoからkaigiのビデオを落としてきます
  7. aegisubでVimeoから落としてきたビデオを開きます
    • しばらくかかる(マシンパワーによる)
  8. メニューの「音声」 -> 「映像ファイルから音声を読み込む」
  9. 波形が表示されると思うので再生ボタンと選択範囲等を弄りつつ、訳したい音の部分を探します。とりあえず映像の方は無視してOK
    • 最初これが面倒に思うが慣れると結構連続してできるようになる
  10. 「選択範囲をすぐに字幕行に反映する」のボタン(ツールチップを見よ)を押します
  11. テキストボックス(一個しかない)に翻訳を入力して「commit」ボタンを押します
  12. この繰り返しにより、必要なだけの字幕を入れます
    • 再度言いますが慣れると速くなる
  13. 時々、映像を眺めて、字幕ののりぐあいを確認します。
  14. 気が向いたら保存します。
    • このとき .ass という拡張子のファイルが生成されるが、これは字幕のタイミングとか内容とかをテキストファイルで書いてある。
    • バージョン管理するならこのファイルを突っ込め
    • 複数人で分担作業のときもこのファイルをやりとりすること
  15. この字幕ファイルを「焼く」。まずavidemuxでビデオを開きます。
  16. 次に(今度は音はどうでもいいので)映像をXvidとかに変更して、すかさず有効になった「フィルタ」をクリックします。
  17. 「字幕」->「ASS」が選べるはずなので、選んで、ファイル選択ダイアログからaegisubで作った.assファイルを選択します。
  18. 保存すると字幕つきになってる。

ffmpegが使えるなら最初にffmpegでビデオから映像のストリームと音声のストリームを分割しておいてそれぞれで作業してからあとでffmpegで再結合するのが賢い。が、べつにその必要はない。

Jul
20th
Wed
permalink

終わることはよいことだという感覚について

三つ子の魂百までとはよく言ったもので、子供のころの強烈に印象に残ってる体験というか、まあテレビで見たわけだけども、その当時ヨーロッパのまんなかのへんで政権交代が局所的なブームだったのさ。んでまあカラフルな壁をツルハシで壊してるドイツの人たちの強烈な笑顔というのが、今でも忘れられなくてですね。もちろん、今から振り返って見れば、1989年をよいとか悪いとかいう単純な評価で切り捨てるのが大きな間違いなのは分かる。けど、当時は政治とかよくわかんない程度に子供だったから、みんな「なにかが終わって喜んでるんだ」ということしか、俺には理解できなかった。だってあの人ら喜んでたでしょ。そのくらいは俺にも分かったよ。

まあそういうわけで、たしかにそのあと色々あったし一面的な評価が誤りだということは理解していますと繰り返し申し上げたうえで、でもやっぱり、少なくともあの瞬間には、終わることはよいことだったんだよ。もっと言うと、あの日、みんなには未来があった。何かが終わると、何かが始まる。その瞬間には、終わったほうはしょうがないとして、まだ始まるほうの何かは、みんなの手でよりよくしていけるチャンスがある。そのようなことをテレビでは言っていたような気がしました。

他にも時々壊してみるほうがいいんじゃないの的なものはもう少し大きくなってから読んだ式年遷宮の解説記事とか、あるいはもっと卑近な体感としては校長先生が変わると学校の雰囲気が結構変わるとか、まあ色々あるわけですよ。学校人事みたいに定期的に壊す必要があるかはさておきね。なので何かが終わること(=何かが変わること)は、基本よいことなのではないか? という感覚が俺の中にはある。少なくとも悲しむ必要はない。そのように思います。

ここまでだと消極的な終了容認論でしかないので、なぜそれが「終わってみるべき」という積極的な話になるかは後で書く。

Jun
10th
Fri
permalink

Pythonでおk ─ 書評: C言語によるスーパーLinuxプログラミング

あのね、この本のAmazonの内容紹介が あまりにたわけていて ね。

Cライブラリで、効率的にプログラミング! Webアプリの世界ではPHPやJavaが格段とポピュラーだが、ハードウェアの操作や ユーザーインタフェース、画像処理などの分野ではC言語でしか扱えないものが多く、近年、現場でのニーズは高い。 本書は、プログラミングでの複雑な処理を短時間に組むために用意されたライブラリに焦点を当て、その使い方を解説しました。 データベース・プログラミングからネットワーク、科学技術計算、コンピュータグラフィクスまで、 ライブラリの活用術を身につけ、複雑なコーディングを簡素に実現する。 LinuxのディストリビューションにはUbuntuを採用。

あれですか句読点のところで毎回「なわけねーだろ」とかツッコミ入れる視聴者参加型インタラクティブ漫才か何かですか。SBCの編集会議はよくこれを通したよね。

まあそんで、どんだけひどい本なのか興味あったので一応読んでみたわけですけど。これねえ、内容自体はそんなにひどくない。もちろんCによるという時点でどうころんでも 前提がおかしい のはどうしようもないわけだけども、そこはさておくとすれば、各章の記述は真摯です。第1章「なぜいまCなのか」に至ってはCにもよくないところはあるし適材適所で、みたいな、おいおいそれ最初に言っちゃうのかよ?っていう筆致になっていて、まあ、おそらく著者はそういうところで嘘がつけない奴なんだろうなあというのはにじみ出ている。あるいはたとえばコラム32の「CやUnixの基礎に関する、おすすめの参考図書」に挙げられているのが

といったラインナップで、間違ってもK&RとかC:ARM5とかじゃないというあたりに、著者の趣味というか方向性は如実に出ているといえるし、あまり悪い印象は受けない。

したがってかえすがえすも惜しいのは本書はCである必要とLinuxである必要がないという 根本的問題 をまったく解決していないという仏作って魂入れずな著作であるという点で、各論はそんなにひどくないのに全体としてみたときに誰が得するのかよく分からないというか、とくに7章でGLibが出てきて12章でGTK+を紹介してからは概ねGTKの枠内でプログラミングしていくわけだけれども、「それPyGTKでよくね?」「それCだとライブラリ使うけどPythonなら楽勝じゃね?」という、とくにUbuntuはわりとPythonよりの環境であるために余計に、Cでないといかん理由がなすぎて非常に清々しい気分になる一冊と言えますね。

まあそういうわけでこの本はむしろPythonに翻訳する修行をすることによりPython力を高めるPython本として使うのが正しい使い方というふうに思うわけです。あるいはMonoも悪くないね、GTK#を使ってみるよい機会になるでしょう。そういった練習問題集として見れば(各章はよく書けているだけに)結構使えるんじゃないかという気がしてきました。C言語によらないスーパーLinuxプログラミングのための本だったんだね。

Jun
7th
Tue
permalink

【第三報】RubyConf2011旅費出しますから行ってきて

追記: 締め切りました

二点、変更点があります。

  • RubyConf本体チケット取得もこちらでできるようになりました

    RubyCentralに相談してみたところ、一人で複数のチケットを(atomicに)確保するのは可能ということでしたので、人数さえ決まればあとはこっちで処理できそうな雰囲気。

    今まで「まだチケット持ってない人は応募してこないでね」ということになっていましたが、この条件は撤廃されてほとんどの人に応募資格が生じそう。

  • そろそろ航空券を手配したい件

    気が早いだろ! と思うかもしれませんが、意外にそうでもない。航空券に限らず何でもそうなのですが、前売券は早くに買うほど安いのです。ちなみに今この瞬間に買うのだとすると、 HND(NRTではなく)->DFW->MSY往復のアメリカン航空(JALコードシェア)が探した中では一番安くて、一人頭87,000円+燃油費等です。どうよ。まあ普通に考えて今後値下がりすることはないはず1

というわけで、皆さんに関わる大きな変更点としては、このアナウンスを持って実質的に募集開始となるというのと、航空券の都合で締切りが発生したという二点をおさえてください。

以下、新しくなった募集要項を書いておきますね。


提供するもの

  • RubyConf2011現地までの成田空港のいっこ前からのエコノミークラスの旅費(往復)
    • たとえば俺(東京都在住)のばあいスカイライナーの日暮里駅が起点、北海道にお住まいの方は成田空港行きに乗ってくれば新千歳空港が起点、羽田空港行きに乗っちゃったらスカイライナー経由なので日暮里駅が起点。セントレアも同じ。
  • RubyConf2011現地宿泊費(相部屋)
    • 宿泊費は相部屋のぶんしか出さないよ、というだけの話であって、差額出していただいて一人で泊まっていただくのは全然構いません。ただ、米国はどんな安宿でも基本二人部屋です。
  • RubyConf2011本体チケット (<- new!)
  • 航空券と宿泊場所の手配のとりまとめ
  • 成田空港から現地まで往復と現地でのガイドっぽいことは俺ががんばってやろうと思います。

その他逆に提供できないものは、

  • 現地でのご飯代とか。学生は上手に俺にたかる程度の戦略的愛嬌が求められる。

応募資格

  • RubyConf2011期間中に有効なパスポートを所有していること。なければ作ってください。
    • パスポート作るのって結構時間かかりますよ! 要注意
  • RubyConf2011期間中と前後含めて合計1週間くらい合衆国に滞在することに関して会社、学校、ご家族などとの調整・説得できる人。そのへん自力でおねがいします。
  • 入国審査官の入国審査を突破できる程度の英会話能力をお持ちの方。
  • これはお願いレベルですが、趣旨から言って過去のRubyConfに参加したことがある人は遠慮してほしいなー
  • その他、人種、性別、年齢、国籍、宗教、思想、学歴、職歴、病歴、犯罪歴不問。

募集要項

  • 定員: 若干名(俺の貯金がなくなるまで)。最小遂行人員俺一人。
  • 日程: 日本標準時2011年9月28日~2011年10月4日、4泊7日予定
    • 前後一日程度はずらせます。応相談。
  • 応募者多数の場合選考の参考にするのでgithubアカウントとtwitterアカウントと意気込みを明記の上、shyouhei at ruby hyphen lang dot org 宛に件名「RubyConf2011行きたい」でメールしてきてください。
    • こちらからは必ず返信を送ります。返信がない場合はこちらで見落としていますので、しつこく再送信したり、他の手段で問い詰めるなどしてください。おねがいします。
  • 応募締切: 日本標準時2011年7月末日必着。(<- new!)
  • 選考の結果当選された方には(手配に必要ですので)パスポートのコピーをFAXしてもらったり等の追加の作業が発生しますので、あらかじめご了承下さい。


  1. ANA派のみなさんならスーパーエコ割が使える日程なので出発前日までかなり安いがそれでもさすがにここまでは安くならない 

May
21st
Sat
permalink
sabino:


The Mississippi River has been flooding for a while now, and in order to fend it off, people have built levees around their homes as protection. Sometimes it works. 


おいこれ今年かよ。全然知らんかったわ。

sabino:

The Mississippi River has been flooding for a while now, and in order to fend it off, people have built levees around their homes as protection. Sometimes it works. 

おいこれ今年かよ。全然知らんかったわ。

(via k3c)

May
20th
Fri
permalink

【第二報】RubyConf2011旅費出しますから行ってきて

今年のRubyConfのサイトがオープンしたようですね。まだプログラムとか出てないけど日時が発表なったので旅行の計画は立てれるよ。

暫定線表

  1. 9/28 移動日
  2. 9/29 RubyConf参加
  3. 9/30 RubyConf参加
  4. 10/1 RubyConf参加
  5. 10/2 フリータイム
  6. 10/3 移動日
  7. 10/4 (日付変更線マジック)

の4泊7日と見た! 観光をカンファレンスの前にやるべきか後でするべきかは議論の別れるところだが、まあこの曜日の並びだと後じゃないですかね。カンファレンスより前でやるなら全体的に一日前側にずれる感じかと。

で、場所が去年と同じでニューオリンズらしいので、去年も参加したという人に色々聞けるのでわりと逆に今回初めてって人も安心かなと思われる。ラッキーですね。

参加したいよ!という人は今後どうするべきか

いまのところ

  • まず予定をあける
  • パスポートとESTAを入手する
  • Early birds registerationという早割みたいなチケットが売りに出されると思われるので、とりあえずその動きに注目する

くらいですかねえ。

その他の質問と答え

  • やっぱ英語できないと辛いですか

    これはYesでもありNoでもあるので、まず嬉しいニュースから申し上げると、英語が分からなくてもRubyが分かれば、なんとかなる。質問意味分かんないけどとりあえずコードで書いてよ、ってのは前回も見ました。まあ、心配すんな。

    ただ残念なニュースを申し上げるとわたしたちは国際カンファレンスに「参加」するのであって、物見遊山に行くのではないので、本当に全然英語がわかんないとしたら一日理解不能のスライドを眺めてるだけで終了する可能性が否定できないので、そりゃやっぱできるに越したことはない。という感じです。

    まあでも、みんな中高で英語やったでしょ?まだ高校生なってない人は小中で英語やったでしょ? 大丈夫なんじゃないの。

  • お金とか無料なのはなんか裏がある? お金以外の対価を払わされる?

    ないんじゃね。

    てかですね、今年どうなるかまだ不明だけど、何年か前まだブッシュが大統領だったころになんかものすごい格安チケットで往復7万円台後半でRubyConf行った記憶があるんだ。でね、このあいだちょっと身内に不幸があったものだから、その翌日あさいちのチケットとって羽田から島根に飛行機で帰ったんですけど、それで往復6万7千円くらいだったですよ。もちろんこの比較はフェアではない(島根さすがに割引運賃だともう少し安い)けども、まあ、いってしまえば、アメリカなんてそんなもん。国内旅行と比べて別段どうという金額じゃないのです。

    だから、今だとRubyConf行かない人というのは、おそらく金銭的理由で行かないんじゃないだろうという風に思っていますし、お金が無料なのはあくまで金銭の移動が様々めんどくさいからなんであって、つまりこっちの都合なので、結局なんかやっぱ払って、って事にはならないと。そのようにお考えください。

前回アナウンス

May
18th
Wed
permalink

エゴサーチで見かけた反応とそれの感想など

  • 速さのためにはCでないと

    この誤解は典型的ですねえ。今、申し訳ないんだけど、普通に書いたCのコードと普通に書いたJavaのコード走らせると、普通に書いたJavaのコードの方が速くなるケース、全部とは言わんが案外と多いですよ。なんでかというと、Javaは普通に書いたらJVMが人類の持てるテクノロジの限りを尽くして勝手に高速化してくれる1が、Cはあなたの能力以上に速くはならない。Cは速いJavaは遅いってのは10年くらい前には正しかったんでしょうけどねえ。

    なお自分でベンチマークしてる暇なんかないよ!という人はshootout.alioth.debian.orgぐらいは読んでもいいんじゃないですかね。たとえばJavaとCの比較で見れば全体的にいって同じくらいのスピード、いくつかの項目でJavaのほうが速いのが分かる。

  • 組み込み屋はCでなければ何を使うか

    これがですねえ、少なくとも俺の半径1クリックではマジもんの組み込み屋は全員verilogとかに流れちゃっててですねえ、もうCなぞ書いてねえのですよ。

    まあつまりね、今日びだと携帯電話ですらIntel入ってるわけです。ってなったときに、じゃあうちの製品でもAtom載せますか、っていうと、わざわざx86のOS書いたりするくらいなら、ありもの持ってくるって事に当然なるわけです。だから、21世紀の現在においてはそもそも、組み込みでなければいけない状況というのがすごーく限られている。で、そんななか、安くて実績豊富なありもんのチップとOS買ってくるんじゃないくて、わざわざどうしても組み込みでやらないといかんね、という状況、これは相当なハードコアなわけですけども、そういう状況になってくると、もはやCやアセンブラですら所望の性能が出せない領域に突入してくるのです。FPGAで論理回路からカスタムの世界です。

    ですので、組み込みだからどうとかいうのは、少なくともCの文脈としては、ちょっともう当てはまりません。今後時代が逆転することはないと思います。

  • 言語の実装は何で書くか

    今から書き始められる大多数の言語は普通にJavaかML系ですよ2。過去にCで書かれてたやつもまだまだ現役だけどさ。ぶっちゃけ今から言語やりだすとしてCでやる必然性ってどこにあるの?

    今更新たにXSLTエンジンをCで書きます、とか言い出すやつおらんと思うのね。文字列処理ほど今Cでやっちゃいかん種類の処理もそうはないですよ。

  • 何で書いてもダメなやつはダメ

    そりゃそうなのかもしらんが、他のツールを使えば全然ダメじゃない人でもCではダメなコードを書いてしまう、これがポイントなのですよ。かくいう自分もCで書いちゃったらメンテナンスしやすい見通しの効いたコードになる自信はちょっとないです3。Cで綺麗なコードを書きましょうってのは道具というか、お膳立てが足りなすぎるのです。

    たしかにそれでも、Cで書かれた綺麗なコードというものは存在し、読むとジョルジュ・ペレックの「煙滅」のような、一種の感動を感じさせてくれます。が、残念ながら私にはIOCCCとかと同じ分類におきたくなる衝動が抑えられません。

  • 使いどころ次第なのでは?

    そう。ほんっとそう。まさにそう。上から下までCで書くのがどんなに狂った発想か。

    Cが本当に必要な領域がもしあるなら、そこはしょうがないからCで書くしかないんじゃないですか。背に腹は替えられないし。でもさあ、それってどこなんですかね。具体的に。まあどっかにはあるのかもしらんが(Kernelの中とかさ)、それの箇所って1970年代とかと比べて大幅減ってるはずなんですよ。計算機は何桁も速くなったし計算機言語は目をみはる発達を遂げたのです。

    ○○だからCでなきゃみたいな幻想は一回捨てたほうがいいです。冷静に、今あるテクノロジを吟味して、最適なものを選びましょう。したら九分九厘はCじゃない選択肢があるはずですよ。それでもどうしても残ったところは、残念だけど必要悪ってことでとりあえずCで書いといてください。たぶんちゃんと吟味すれば本当にちょっとしか残ってないから、被害も最小限でしょう。そこまでちゃんと考えて結果Cを選ぶのなら、まあ、しょうがない。好きにはなれないが納得できます。

    でも、多くのケースはそうじゃないんだよな。


  1. JITコンパイラはJITじゃないコンパイラよりも最適化に用いることができる情報が多いのでJavaとかC#はCよりも最適化が効きやすい。 

  2. 聖典”Modern Compiler Implementation in ML“のおかげ。日本語訳もある。読むべき。というか言語屋なら当然すでに読んでるべき。 

  3. 特にエラーの持ち回りがgotoに頼るかエラーの瞬間にreturnで関数抜けるかしかないのでどう転んでも見通しが悪くなる 

May
17th
Tue
permalink

どうも周知徹底が不足しているようなので再度のお願いとなりますが、C死ね。

  • 確かにCでしか書けない類のプログラムは存在する(例を挙げるならKernel)が、それはCの存在を赦す理由にはならない。
  • 確かにCに輪をかけてさらにダメな類のプログラミング言語は存在する(例を挙げるならC++)が、それはCの存在を赦す理由にはならない。
  • 確かにCでしか書けないダメプログラマは存在する(例を挙げてほしければここにおまえの名前を入れろ)が、それはCの存在を赦す理由にはならない。

結論:C死ね。

そもそも計算機にできて算盤にできないことなど存在しない。存在しないんだぞ。なのに何故人はプログラムを書くのか。それはオートメーションのためなのであり、奴隷的使役から人類の尊厳を開放して、この地上に楽園を築くためである。まあそこまで大上段に振りかぶって普段から書いてる輩はいないにせよ、プログラミングとは楽をするため、豊かな人生を実現するため、誰かの幸福のために行うものだ。違うか?じゃあなぜプログラムを書くんだ?

翻ってCでのプログラムはどうかといえば、これは不幸でしかない。Cの不幸はあげればキリがないから、構文がいかれてるとか、型システムが狂ってるとか、静的・動的セーフティー機構をほとんど全く欠如するとか、あるいは「Cしか書けないプログラマ」が一定数いてこれが老害になっているとか、まあその程度を列挙しておくに留めるが、ともかく様々な原因により、Cで書くことを選ぶとバグが出た際メンテナンスがとても困難になる。もちろんバグのないプログラムなど(少なくともCを使う以上)ありえず、たとえシステムがユーザーの負担を減らしたとしても、そのぶんプログラマが背負ってるだけに過ぎない場合が多々見受けられる。それは要するに搾取対象が移動しただけなわけで、全体の幸福の総和が上昇しないようなものの存在を、我々はけっして赦してはならないのだ。

すでにCで書いてある既存のプログラムを今すぐ根絶やしにするのは難しかろう。過去にそれらが果たしてきた歴史的役割まで否定するつもりもない。しかし今、この瞬間にも意味もなくCで書かれ続けているプログラム。なぜCで書く必要がある?ないはずだ。ないはずなんだよ。ちゃんと調査すればJavaとかC#とか、ひょっとしたらOcamlやScalaででも用は足りる場合がほとんどなんだ。Cは捨てろ。これ以上Cの業火を背負うな。未来に禍根を残すな。少なくともCのプログラムを人間が手で書く時代は、我々の世代で最後にするべきだ。体罰の伝統じゃないんだから。我等の子孫にCのない明るい未来を。そう願ってやまない。C死ね。

Apr
13th
Wed
permalink

RubyKaigi 2011 status for attendees overseas

Radioactive situations

In short, right now, you are safe to visit Tokyo.

You should really understand the basic simple fact that no scientists, no power companies or no governments can cover up radiations. In case of nuclear accidents, radiation increase must be observed by any monitoring system elsewhere. So you can detect your safeness from those systems. At the time I write this, environmental radioactivities in Tokyo are about 0.08 μSv / h = 700 μSv / yr, which is below alert level.

Earthquakes

Yes it sometimes quakes. So what?

Don’t be afraid. Luckily Tokyo was not that damaged by the big earthquake and has already been restored. Its public systems including connectivity to the Internet and Caffeine supply chains like the Starbucks, are all normally operated now. Programmers should have no problem. When you visit here, you can see how robust the city is made. Remember Japan has been a land of earthquakes since long before humans started living in the island. We get used to.

RubyKaigi itself

For RubyKaigi, it will be held as planned.

I heard from Masayoshi Takahashi of Ruby-no-kai that the Kaigi venue says it is OK to have the kaigi. He also told us that his Ruby-no-kai members are smoothly preparing to the Kaigi. If there can be any possibility of abortion, that would be due to power supply related(*1). But even on a blackout, I think the Kaigi itself can still be OK, because the venue is equipped with private power facilities.

Masayoshi says that when situation changes he will immediately notice us via any channels. It seems announcements in English are first posted to @rubykaigi twitter account. You would be better follwing it. I have not seen any announcements about their schedules so right now it seems everything is as planned.

Hope seeing you at the Kaigi.


(*1): As reactors stop after the quake, power supply in Tokyo area is a bit cranky. Unlike those frequent earthquakes, power shortages are really rare in Japan. People are not that used to them. There might perhaps be some pitfalls.