sd-senkoさんのブログ -2ページ目
Apache Camelの紹介はこちら から。
解説動画:るみちゃあああああああああああああああああああああああああ


■Apache Camelコンテキストをシンプルに書くことで、
GAE/jのスピンアップ時間を減らすことができます。


Apache Camel本体に付属のサンプル、camel-example-gaeは、
GAE/j本番環境におけるスピンアップ時間が考慮されておらず、
スピンアップに30秒前後かかってしまいます。(CPUのグレードで一応短縮可能)
しかしこれはspringフレームワークの挙動によるものなので、
spring周りの記述をごっそり取り除くことで、スピンアップ時間を1/5程度に短縮できます。


springを抜くので、マッピングやインスタンスの起動時にやってくれる設定関係が弱くなりますが、
CamelContextを手動で立ち上げ、ProducerTemplateを使うことで全く同じことが行えます。
(逆にこちらの方がわかりやすい方も多いのでは…)


では、サンプルをご覧ください。


public class SampleServlet extends HttpServlet {

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException {
    try {
      CamelContext context =
        new DefaultCamelContext(new SimpleRegistry());
      context.addRoutes(new Route());
      context.disableJMX(); // 必須
      context.start();
      ProducerTemplate pt = context.createProducerTemplate();
      Exchange e = new DefaultExchange(context);
      pt.send("direct:start", e);
      resp.setContentType("text/html;charset=UTF-8");
      resp.getWriter().println(e.getIn().getBody(String.class));
    } catch (Exception ex) {
      Logger.getLogger(SampleServlet.class.getName())
        .log(Level.SEVERE, null, ex);
    }
  }
}


class Route extends RouteBuilder {

  @Override
  public void configure() throws Exception {
    from("direct:start")
        .process(new SampleProcessor());
  }
}


class SampleProcessor implements Processor {

  public void process(Exchange e) throws Exception {
    e.getIn().setBody("オアシス君無限増殖法");
  }
}


ルーティングルールとして、directコンポーネントではじまるルートを用意しておき、
そこへProducerTemplateを使ってExchangeを投げる格好になります。
投げる前に、Exchangeのヘッダーやボディに細工をしておくこともできますし、
投げた後は、Exchangeがまた返ってきます。それをさらに違うルートへ投げても良いです。


consumerサイドでしか使えないコンポーネント(ローカルだとfileとか)の場合は、
ConsumerTemplate#receive("endpointUri") が使えます。こちらもExchangeを生成します。


RestfulなWebサービスでは、サービスへリクエストされたURIを元にページを返します。その場合は

    exchange.getIn().setHeader(Exchange.HTTP_URI,req.getRequestURI());

のようにしてやれば、ルーティングルールの方でもリクエストURIを受け取ることができます。
クエリパラメータやPOSTメソッドについても同上です。


DefaultCamelContext のコンストラクタに、なぜSimpleRegistryを渡すのかは、
こちらのトピックが参考になると思います。(自分は読めてないですが…)
http://stackoverflow.com/questions/14644570/do-camel-routes-not-run-on-google-app-engine



最後に、GAE/jでApache Camelを動かすメリットについてですが、


1.ルーティングルールとプロセッサーによりモジュール化が進むので、読みやすく書きやすい

2.httpコンポーネントが勝手にやってくれるコネクション管理が優秀、高速なのでウェブスクレイピングに向く

3.全体的なパフォーマンスの良さ


(どれもGAE/j上の話に限りませんでした。)


Datastore読み出し一回、外部サイトへアクセスしてXML取得一回、
からの差分演算…で300msec(内、CPUは50msec以下)とかです。
レスポンスが良くてコードの見通しも良いと、機能をどんどん盛りたくなりますよね。


ASF : Apache Camel
http://camel.apache.org/


日本Apache Camelユーザ会(JACUG)
http://sourceforge.jp/projects/cameluserjp/

https://sites.google.com/site/jaacug/home
備忘録ですー


public class POIProcessor implements Processor {

  @Overide
   public void process(Exchange e) throws Exception {
    // read
    InputStream is = new ByteArrayInputStream(e.getIn().getBody(byte[].class));
    Workbook wb = WorkbookFactory.create(is);

    // main
    Sheet sheet = wb.getSheetAt(0);
    sheet.getRow(1).getCell(1).setCellValue("owaaaaa");

    // write
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    wb.write(baos);
    e.getIn().setHeader(Exchange.FILE_NAME, "yay.xlsx");
    e.getIn().setBody(baos.toByteArray());
  }
}



Apache POIで編集後のExcelワークブックを保存しようとすると基本
wb.write(new FileOutputStream("foo.xlsx")) になります。
これだと確かに即ディレクトリに書き出しがされるのですが
ルーティング処理と書き出しが切り分けできなくて、Apache Camel的にはいやんな感じなので、
ByteArrayOutputStreamを使ってみました。
ボディにセットされたバイト配列は、任意のタイミングで任意の場所に、
fileコンポーネントで書き出すことができます。


Excel処理がメインになるのなら、read部とwrite部を別プロセッサにして、
普段はWorkbookで取り回す方が全然いいと思います。


ASF : Apache Camel
http://camel.apache.org/


日本Apache Camelユーザ会(JACUG)
http://sourceforge.jp/projects/cameluserjp/

https://sites.google.com/site/jaacug/home
アニメを見ている時に


「このアニメおもしろーい」


と思う感覚と、


好きな声優さんが出ているアニメを見て、思わず


「がんばれ…!」


と応援してしまう感覚とは、
割と遠いものだと思います。


自分自身、「応援」「贔屓目」「声優目当て」っていうのは、
アニメを見る上で、本質ではないと思ってました。
アニメを見る上では、「見たままを面白いと感じるか、そうでないか」が全てだと。


なので、優れた声優さんというのは、アニメを面白くしてくれる声優さんであり。
優れた声優さんを起用することが、アニメ全体にとって、
ひいてはアニメというジャンル全体にとってのメリットであり。


その文脈において新人声優さんとは、次の世代を担うための「優れた声優さん」の候補生であり。
ですから、アニメを制作する人たちにおかれましては、限られたリソース(アニメの配役)を
最大限有効に(有望な新人さんに)割り当ててほしいよね。


くらいのことを思ってました。投資と回収、ですか。


この考えで行くと、
「新人声優をアニメに出演させるのはあくまで投資であって、
また、新陳代謝のために、必要にかられてであって、
作品としては(優れた声優を起用するよりも)メリットが薄い」


ってことになります。
感覚的には間違いなんだけど、これまでそれを突き崩す論理が思い浮かばなかった。





最近思い至ったのが


「『新人声優の頑張ってる感』こそが新人声優を起用するメリットなんだよ!」
「『新人声優の頑張ってる感』こそがエンタメなんだよ。」


ってことでした。
(もう結論言ったのでいいかな。)


思い至って見れば、「『頑張ってる感』を楽しむ」というスタイルは割とありふれていて。
高校野球や箱根駅伝に代表されるアマチュアスポーツとか。同人作家さんとか。歌い手とか。


「応援すると元気をもらえる」というのは確かにそうですが、
ちょっとひねた言い方をすると、我々は「頑張ってる感を楽しみ、消費している」のですね。
それは「物語を楽しみ、消費する」行為と、きっとそんなに遠くないはずで。
「その種のエンタテインメント」としてとらえることができるのです。


その考えに立つと、「優れた新人声優」なるものが定義できて、それは


「『頑張ってるなぁ~』と思わせる声優」


ってことになります。何をすれば「頑張ってるなぁ~」と思えるのかまでは、
今回書きたいことではないので、触れませんが。


なので、投資と回収(つまり、デメリットのあとにメリットがきて、全体でプラスになればよい)
というモデルはちょっと修正が必要で、


「新人声優のうちは『頑張ってる感』で視聴者を楽しませ、
声優として成熟したらアニメを面白くすることで視聴者を楽しませれば、
最初から最後までウハウハ」


ということになりますね。


「この新人声優下手だな」
「上手い声優だったらもっと面白くなったのに」


って感想は確かにそのとおりですけど


他の見方をすれば、「本人から醸し出される『頑張ってる感』が足りなかった」
ってことも言えるんじゃないでしょうか。
頑張ってるなぁ~って思えたら、たとえ下手に感じても、それを楽しめると思うんですよね。
何を持って「頑張ってる」とするかは、やっぱり横へ置いておきますけど。


というわけで、本日の謎理論でした。