perlとjavaでwebアプリケーション その2

  • 投稿日:
  • by
  • カテゴリ:

WAF

perl

海外だとCatalystとかDancerとかMojoliciousとか。 日本ならAmon2で。

java

Spring Boot 2で。

テンプレートエンジン

perl

昭和では Template Toolkit いわゆるttと呼ばれるものを使っていたが現在は Text::Xslate を使えばよい。syntaxもttとほぼ同じにできる。

java

thymeleafはSpringがサポートしているものなので何かと安心。ブラウザでそのまま表示できるのでマークアッパーにも優しい。

freemarkerは前述のttと近い感じで使える。しかし変数とかの表示はサーバでのレンダリングなのでブラウザでそのまま表示はできない。

perlとjavaでwebアプリケーション

  • 投稿日:
  • by
  • カテゴリ:

モジュール

perl

最近はCartonを使う。cpanfileはこんな。

# cpanfile
requires 'Amon2', '== 6.13';

java

最近はgradleを使う。石器時代にはmavenとかantとかいうものを使っていたらしいが現代において目にする見る機会はない。 バージョンによって色々書き方があるらしい。 あとjavaではモジュールと呼ぶのかライブラリと呼ぶのか分からない。

# build.gradle
plugins {
    id 'org.springframework.boot' version '2.0.5.RELEASE' apply false
    id "org.jetbrains.kotlin.jvm" version '1.2.61' apply false
    id 'org.jetbrains.kotlin.plugin.spring' version '1.2.61' apply false
}

めっちゃ古いPlackで動いてるアプリケーションがあったのでアップデートしたのだが json encode された文字列のpostを受け取ったときに

$c->req->param("hoge")

で受け取れなくなっていたので調べたら最初はそれで受け取れるのだが途中で http://blog.nomadscafe.jp/2014/02/httpentityparser.html の変更が入って取れなくなっていた。
取りたいならば


$parser->register('application/json','HTTP::Entity::Parser::JSON');

すればいい、はずなのだが受け取れなくて、調べていたらリクエスト時に Content-Length も Content-Type も送っていなかった。
それぞれここで問題になる。
https://metacpan.org/source/KAZEBURO/HTTP-Entity-Parser-0.24/lib/HTTP/Entity/Parser.pm#L81
https://metacpan.org/source/KAZEBURO/HTTP-Entity-Parser-0.24/lib/HTTP/Entity/Parser.pm#L55
なのでpostするときにそれぞれのヘッダを入れてもらうようにして解決した。

リモートワーク環境構築

  • 投稿日:
  • by

リモートワーク環境なメモ。会社は割と早く全社的なリモートワークになって、出社したい人も別に好きにしていい感じだった。自分は自宅で集中して仕事できる気がしなかったのと、長くは続かないだろうと思ってたので出社を続けていたが、なんとなくリモワ半々くらいになっていった。が、椅子やら机やらの準備を怠けていた。結果、腰を痛めたので本気入れて用意した。

椅子

会社ではアーロンチェアを使っていた。高い椅子だとは知ってはいたが、普段から「こんな高い椅子じゃなくても別にいいのにな」と思っていた。在宅で粗末な椅子を使い続けてからありがたみに気づいた。いい椅子は人権だ。大事なものはいつもそばにあって、無くしてから大事さに気づく。気付くのが遅れた代償として今はコルセットを着けている。
椅子に詳しくなかったので、中古オフィス用品店に行って何点か座ってみた。アーロンチェア、バロンチェア、その辺は名前は知っていたが、他にもたくさんあった。最終的にシルフィーという椅子を買った。
あとチェアマットも買った。滑りいい。

会社の机は自動昇降機能つきだった。気分で立って仕事したり、座ったりしていた。これを買うと高いだろうなと思ってはいたが、やはり高かったのでやめた。椅子を買ったのとは違う店で椅子と机をセットして座ってみて、合った高さを覚えて通販でよさげなサイズのを買った。

会社は人が働きやすいように色々考えられていた。エアコンやトイレにしてもそうだ。高性能なのが使い放題で掃除などのメンテもすることはない。自宅ではこうはいかない。勝っているのはベッドがあるくらいでは。

で色々買った結果、会社と変わらない程度の環境は整ったが、元々仕事をあまり真面目におっと

URI::Escape のバージョン問題

  • 投稿日:
  • by
  • カテゴリ:

URI::Escape には escape_char という関数がある。
これはなんと同じバージョンでも実装が異なる。
というのも、これは URI::Escape 単体でリリースされているのではなく、 URI のパッケージに付属するもので、 URI:: 以下のモジュールのバージョン管理が URI と揃っていないから。
例えば URI@1.60 にも URI@1.76 にも URI::Escape@3.31 が付属している上に中身が違う。OMG
なので cpanfile で

requires 'URI::Escape'  => '==3.31';
と書いても、期待するものが得られるとは限らない。
現在の URI の最新版は 1.76 なので、最新の実装がほしいなら
requires 'URI'  => '==1.76';
と書かなければならない。

ということを今日は author の方から教わりました。
https://github.com/libwww-perl/URI/issues/73

redisのkeyの最大数

  • 投稿日:
  • by
  • カテゴリ:

redisにkeyは何個まで入るんだろうと思ったらfaqにありました

https://redis.io/topics/faq

What is the maximum number of keys a single Redis instance can hold? and what is the max number of elements in a Hash, List, Set, Sorted Set?

2^32個だそうです。異常なことをしない限り気にしなくてよさそう

redisでキューイング

  • 投稿日:
  • by
  • カテゴリ:

redisにはリスト型というものがあってkeyごとにリストを格納できる。left, rightで方向を表し、leftが先頭、rightが末尾。これを利用してredisでキューイングを実装する。

use strict;
use warnings;
use Redis::Fast;
use 5.10.0;
use Data::Dumper;

sub p { warn Dumper \@_ }

my $redis = Redis::Fast->new;
$redis->flushall;

my $key = "keyhoge";

{ # enqueue
    for my $i (1..5) {
        my $value = "data_$i";
        $redis->rpush($key, $value);
    }

    # 結果確認
    p "enqueue done. data", $redis->lrange($key, 0, -1);
}

{ # dequeue
    my $get_row_per = 2;

    my $loop = 0;
    while (1) {
        say "--------------- loop $loop";

        my @result;
        $redis->multi;

        eval {
            my $part = $redis->lrange($key, 0, ($get_row_per - 1));
            $redis->ltrim($key, $get_row_per, -1);

            if ($loop == 1) {
                die "some error";
            }
        };

        if ($@) {
            say "error. '$@' rollback";
            $redis->discard;
        } else {
            @result = $redis->exec;
            my $part_result = $result[0];
            if ($part_result and @$part_result) {
                p $part_result;
            } else {
                say "end";
                last;
            }
        }
        $loop++;
    }
}
% perl queue.pl
$VAR1 = [
          'enqueue done. data',
          'data_1',
          'data_2',
          'data_3',
          'data_4',
          'data_5'
        ];
--------------- loop 0
$VAR1 = [
          [
            'data_1',
            'data_2'
          ]
        ];
--------------- loop 1
error. 'some error at queue.pl line 39.
' rollback
--------------- loop 2
$VAR1 = [
          [
            'data_3',
            'data_4'
          ]
        ];
--------------- loop 3
$VAR1 = [
          [
            'data_5'
          ]
        ];
--------------- loop 4
end
  • rightからpushし、leftから取り出すことでFIFOにする
  • 逆は不可。pushにはlpush, rpushはあるが、rangeはlrangeしかなく、leftからしか取り出せない
  • データを取り出すコマンドにはpopがあるが、これもrpopしかなくrightからしか取り出せない。1個ずつ取り出すのはパフォーマンスが悪いため、複数取り出す
  • それにはrangeでデータを先頭から参照し、rangeは参照するだけでデータは変更しないため、取り出したのちにtrimでリストを切り詰める
  • rangeとtrimの間にエラーが起きたら(redis自体が落ちた、ネットワーク的に到達できなかったなど)整合性が取れなくなるため、トランザクションを貼る
  • トランザクションはexecでコミットする。execはトランザクション中に発行したコマンドの結果を配列で返す
  • redisはmysql等のDBMSより圧倒的に早いので大規模なキューイングを処理するときはTheSchwartzより効率がいい(信頼性などを考慮しケースバイケース)