MojoliciousでMongoDB

TwitterのMojoliciousタイムラインに" [Mojoliciousでノンブロッキングしたいと思ったらぴったりの記事があった](https://twitter.com/Squelch_JP/status/445555842520055808) "というのが流れてきたのでやってみる

元記事はこれ [Writing Non-Blocking Applications with Mojolicious: Part 1](
http://blogs.perl.org/users/joel_berger/2013/10/writing-non-blocking-applications-with-mojolicious-part-1.html)

ソースファイルも公開されてますがここではちょっと改変。
[blocking_paste.pl](https://gist.github.com/jberger/6884022
) 


まず、MongoDBを入れる。

```
$ wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.9.tgz
$ tar xzf mongodb-linux-x86_64-2.4.9.tgz
```

DBを作成。デフォ設定だと3GB近くディスク容量を消費するのでsmallfiles指定しておきます。port27017で立ち上がります。

```
$ mkdir db
$ ./mongodb-linux-x86_64-2.4.9/bin/mongod --dbpath ./db --nojournal --smallfiles --nssize 4 -vvvv
Tue Mar 18 01:55:00.244 [initandlisten] waiting for connections on port 27017
```

モジュール追加

```
$ cpanm Mango
```

ようやくMojolisiousソースを書く[コピペ元](https://gist.githubusercontent.com/jberger/6884022/raw/78766b3e7f1a84b275f8f804b3c68075b7e2065d/nonblocking_paste.pl)

```pl:nonblocking_paste.pl
#!/usr/bin/env perl

use Mojolicious::Lite;
use Mango;
use Mango::BSON 'bson_oid';

#helper mango  => sub { state $mango = Mango->new($ENV{PASTEDB}) };
helper mango  => sub { state $mango = Mango->new("mongodb:127.0.0.1:27017") };
helper pastes => sub { shift->mango->db->collection('pastes') };

get '/' => 'submit';

post '/' => sub {
  my $self = shift;
  my $title = $self->param('title') || 'Untitled';
  my $content = $self->param('content')
    or return $self->redirect_to('/');
  my $doc = {
    title   => $title,
    content => $content,
  };
  $self->render_later;
  $self->pastes->save($doc, sub {
    my ($coll, $err, $oid) = @_;
    $self->redirect_to( show => id => "$oid" ); 
  });
};

get '/:id' => sub {
  my $self = shift;
  my $id = bson_oid $self->stash('id');
  $self->render_later;
  $self->pastes->find_one({ _id => $id }, sub {
    my ($coll, $err, $doc) = @_;
    return $self->redirect_to('/') if ( $err or not $doc );
    $self->render( show => doc => $doc );
  });
} => 'show';

app->start;

__DATA__

@@ layouts/basic.html.ep

<!DOCTYPE html>
<html>
  <head>
    <title><%= title =%></title>
    %= stylesheet '//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css'
  </head>
  <body>
    <div class="container">
      <%= content =%>
    </div>
  </body>
</html>

@@ show.html.ep

% title $doc->{title};
% layout 'basic';

%= stylesheet begin
pre.prettyprint {
  background-color:inherit;
  border:none;
}
% end
%= tag h1 => $doc->{title}
%= tag div => class => 'well' => begin
  %= tag pre => class => 'prettyprint' => begin
    <%= $doc->{content} =%>
  % end
% end
%= javascript 'https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js'

@@ submit.html.ep

% title 'Paste your content';
% layout 'basic';

%= form_for '/' => role => form => method => POST => begin
  %= tag div => class => 'form-group' => begin
    %= tag label => for => 'title' => 'Title'
    %= text_field 'title', class => 'form-control'
  % end
  %= tag div => class => 'form-group' => begin
    %= tag label => for => 'content' => 'Paste Content'
    %= text_area  'content', class => 'form-control'
  % end
  %= submit_button 'Paste' => class => 'btn btn-primary'
% end

```

TitleとPaste Contentを入力してPasteボタンを押すと
url/53272b74039ef44015020000 みたいなアドレスで保存される。（BSON）
DBを再起動しても保存されていることを確認。


## 参考
* [ケチケチMongoDB | しのぶら!!!](
http://shinobra.com/2012/05/sawanoboly/small_mongodb)