【Ubuntu Linux】 自宅サーバで健康維持

テレワーク時代の健康維持

私のようなITエンジニアの強みとして「どこでも仕事ができる」というものがあります。これは他の業種の人からすると、非常に大きなメリットなのですが、一方で気をつけなくてはいけなくなるのが「健康」です。ITエンジニアは長時間の座り仕事になりますし、しかもパソコンの画面を注視するものですから、どう考えても健康に良いわけがありません。

私のように中年も半ばに差し掛かると、どうしても皮下脂肪も付きやすくなりますし、筋肉量もどんどん目減りしていきます。さらに身体がしなやかさを失いますから、腰痛や偏頭痛、慢性的な疲労感に苛まれていくことになります。

そこで、ITエンジニアらしい方法を使い、毎日決まった時間に「アレ」をすることにしました。

国民の健康維持の為に開発された「アレ」を自宅サーバで

さて、「アレ」についてそろそろ説明しておきます。「アレ」とは国民の体力向上と健康の保持や増進を目的とした体操、つまり「ラジオ体操」です。

このラジオ体操を、自宅サーバとして稼働しているASUS EeePC 1015PEMカスタム(SSD化&RAM増設→4GB / OS: lubuntu-18.04 LTS [bionic])で毎日11:00に再生することで、強制的にラジオ体操の時間を作ってしまおうという目論見です。

Ubuntu Linuxをコマンドラインで操作できる程度の知識と、余ったノートPCがあればできる内容となっていますので、ぜひ健康維持の参考にしてみてください。

必要なパッケージのインストール

強制ラジオ体操タイムに必要なパッケージは以下のものとなります。すべてapt installで導入可能です。

  • mplayer
  • ffmpeg
  • youtube-dl
  • alsa-base
  • alsa-utils

導入のためのコマンドは以下の通りです。

$ sudo apt update &&
sudo apt install \
mplayer \
ffmpeg \
youtube-dl \
alsa-base \
alsa-utils

YouTubeからラジオ体操の動画をDLする

導入したyoutube-dlコマンドを使い、ラジオ体操の動画を自宅サーバにダウンロードします。

$ youtube-dl "$MOVIE_URL"

上記のコマンドを実行すると、動画タイトルと同じ名前のwebm形式のファイルが出来上がっていると思います。($MOVIE_URLは任意のYouTube動画のURLに置き換えてください。)

ただ、このままのファイル名ではかなり取り扱いが面倒ですから、以下のような感じで半角英数のファイル名に変更しましょう。

$ mv 'ラジオ体操 第1 ・第2、首の体操-jXXXXXXXXXX.webm' Radio-Taisou.webm

これで動画ファイルRadio-Taisou.webmが出来上がりました。

動画をmp3に変換する

実際に動画のまま取り扱っても問題はないのですが、動画のままではどうしても若干面倒ごとが増えてしまいます。しかも今回は映像部分は不要で、音声だけが欲しいので、動画をmp3に変換します。

動画からmp3音声を抜き出すのにffmpegを使います。以下のような感じで変換可能です。

$ ffmpeg \
-i Radio-Taisou.webm \
-vn \
-acodec mp3 \
-af "volume=1.3" \
Radio-Taisou-audio.mp3

上記コマンドの各オプションはそれぞれ以下のような意味となります。

  • -i Radio-Taisou.webm 変換元となるファイルを指定
  • -vn 映像(ビデオ)オフ
  • -acodec mp3 出力音声の形式をmp3にする
  • -af "volume=1.3" 出力音声のボリュームを1.3倍にする
  • Radio-Taisou-audio.mp3 出力先となるファイルを指定

このようにすると、Radio-Taisou-audio.mp3が作成されます。

再生デバイス(スピーカーなど)を確認する

次に、どの再生デバイスから音を出すのかを確認します。コマンドは以下の通りとなります(sudo権限が必要)。

$ sudo aplay --list-devices

私の環境では、出力先に利用できるデバイスが一つ(EeePCに標準付属のスピーカー)しかありませんでした。

[email protected]:~$ sudo aplay --list-devices
[sudo] ytnobody のパスワード:
**** ハードウェアデバイス PLAYBACK のリスト ****
Home directory not accessible: 許可がありません
カード 0: Intel [HDA Intel], デバイス 0: ALC269VB Analog [ALC269VB Analog]
サブデバイス: 1/1
サブデバイス #0: subdevice #0

ここで重要となるのが、カード 0デバイス 0のところです。このあと音声を再生するときにこの番号を使いますから、しっかりと覚えておきましょう。

再生してみる

それでは実際に再生してみましょう。コマンドラインからmp3を再生するにはmplayerを使います。コマンドは以下の通りです。

$ sudo mplayer \
-ao alsa:device=plughw=0.0 \
Radio-Taisou-audio.mp3

このコマンドでは、-ao alsa:device=plughw=0.0 の箇所で再生デバイスを指定しています。例えば再生デバイスがカード 0デバイス 1の場合はplughw=0.0の代わりにplughw=0.1とする必要があります。ご自身の環境に合わせて変更してください。

うまく再生できた場合、スピーカーなどからラジオ体操のピアノ伴奏が聞き取れるはずです。音声の再生を終了する場合はCrtl-CかEscでmplayerを終了させます。

定期実行させる

再生までできたら、あとは任意の時間に自動再生されるよう、cronで定期実行させるだけです。

私の場合、昔からの手癖で直接/etc/crontabに定期実行の設定を書いちゃったのですが、その内容は以下の通りです。

00 11 * * * root mplayer -ao alsa:device=plughw=0.0 /home/ytnobody/Radio-Taisou-audio.mp3 > /dev/null 2>&1

最後に> /dev/null 2>&1を追加してありますが、これはcronジョブが実行される際に、mplayerのSTDOUTとSTDERRが邪魔だったので、両方とも/dev/nullに捨てるようにしたのです。

まとめ

テレワーク時代の健康維持の為に、自宅サーバでラジオ体操を毎朝11時に流すようにしました。

座り仕事が続き、腰痛などに悩まされることが多くなった人はぜひラジオ体操タイムを作って、健康維持に努めましょう。

Generating Kotlin code from Protocol Buffers (without JVN on your host)

Gradle? JVM? Looks as chainsaw in this case.

Protocol Buffers is famous IDL(Interface Description Language) in these days. And the uber/prototool is needful tool for generating interface codes in any languages.

However information about generating kotlin code is quiet few in today.

Basically I was knowledgeless about kotlin before generating kotlin codes. And the our project is written in golang.

Okay, then I found an entry that telling as “JVM and gradle are needed when generating kotlin code through protoc”.

Hmm, “place build.gradle will be in our project”? Sounds not so good. Because our project is written in golang. Don’t forget, I just want “generating kotlin codes from protocol buffers“. This method looks as cutting sashimi with chainsaw.

Conclusion: Docker solves as like sashimi knife

In this case, requirement to environment for solving the issue is so huge. “Huge requirement to environment… I’ve got it!” yes, it is the Docker Hub. So I found the container image that fits this case.

It is the moia/prototool-docker (codes on GitHub).

Usage is followings.

### prototool.dockerfile
FROM moia/prototool-docker

RUN mkdir /proj
WORKDIR /proj

CMD protoc --kotlin_out=./proto/kotlin ./proto/definition/*.proto

### In your terminal
$ docker build -f ./prototool.dockerfile -t prototool .
$ docker run --rm -v /path/to/myproj:/proj -t prototool

Finally I got succeed to generate kotlin code from protocol buffers, with moia/prototool-docker that is instead of JVM on my host.

plenvsetup v0.06 has been released

Let’s setup your own perl environment without system-perl

Today I released plenvsetup v0.06. plenvsetup is a quick setup tool for perl environment with plenv. In the latest version, plenvsetup uses Shoichi Kaji(skaji)‘s perl-install instead of Perl-Build. This allows, we can install perl without system-perl under plenv. Now we can use new plenvsetup with following one-liner.
$ curl -sL https://is.gd/plenvsetup | bash
You may zsh instead of bash.

Build on a Docker container

plenvsetup works on a Docker container it based on latest alpine linux image too. For example, following Dockerfile setups the perl-5.30.0 with plenvsetup on container.
FROM alpine
WORKDIR /root

### install required dependencies (perl not required!)
RUN apk add bash libc-dev gcc make patch git curl

### download plenvsetup
RUN curl -sL https://is.gd/plenvsetup > plenvsetup && chmod +x plenvsetup

### use plenvsetup on bash
ENV SHELL=/bin/bash
RUN bash plenvsetup

### install perl-5.30.0 with plenv
RUN .plenv/bin/plenv install 5.30.0
RUN .plenv/bin/plenv global 5.30.0
RUN .plenv/bin/plenv rehash

CMD /bin/bash
Then, you can build the Dockerfile, and run perl-5.30.0 within the container.
$ docker build -t ytnobody/plenvsetup .
Sending build context to Docker daemon 2.048kB
Step 1/10 : FROM alpine
---> cc0abc535e36
Step 2/10 : WORKDIR /root
---> Using cache
---> 5a63e9728352
Step 3/10 : RUN apk add bash libc-dev gcc make patch git curl
---> Using cache
---> 0fed43f11239
Step 4/10 : RUN curl -sL https://is.gd/plenvsetup > plenvsetup && chmod +x plenvsetup
---> Using cache
---> 2b8ce1c5f1fa
Step 5/10 : ENV SHELL=/bin/bash
---> Using cache
---> 6f661e8cf191
Step 6/10 : RUN bash plenvsetup
---> Using cache
---> 24f2c6c713f0
Step 7/10 : RUN .plenv/bin/plenv install 5.30.0
---> Running in 86f08ede1c38
---> Downloading https://cpan.metacpan.org/authors/id/X/XS/XSAWYERX/perl-5.30.0.tar.gz
---> Unpacking /root/.plenv/cache/perl-5.30.0.tar.gz
---> Applying Devel::PatchPerl 1.80 (patchperl-extracted 0.0.1)
---> Building perl 5.30.0
---> See /root/.plenv/build/1578556140.1/build.log for progress
---> ./Configure -des -Dprefix=/root/.plenv/versions/5.30.0 -Dscriptdir=/root/.plenv/versions/5.30.0/bin
---> make
---> make install
---> Successfully installed perl 5.30.0
Removing intermediate container 86f08ede1c38
---> 73c2b52fa025
Step 8/10 : RUN .plenv/bin/plenv global 5.30.0
---> Running in 439f41b196dd
Removing intermediate container 439f41b196dd
---> 8e819e1afd8c
Step 9/10 : RUN .plenv/bin/plenv rehash
---> Running in 31d3278595ce
Removing intermediate container 31d3278595ce
---> 28e28a126931
Step 10/10 : CMD /bin/bash
---> Running in c67a1e299db0
Removing intermediate container c67a1e299db0
---> 3ceac81cf2f4
Successfully built 3ceac81cf2f4
Successfully tagged ytnobody/plenvsetup:latest

$ docker run --rm -it ytnobody/plenvsetup
bash-5.0# perl -v
This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux
(with 1 registered patch, see perl -V for more detail)
Copyright 1987-2019, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
So easy.

Kichijoji.pm #20 に参加しました

2019-11-22、六本木はフリークアウト社にてKichijoji.pm #20が開催されました。大変楽しませていただきました。7年目に突入ということで非常にめでたい節目でもあったようです。

なお私は途中からの参加となったのですが、懇親会LTにて「昔作ったソシャゲーの裏側」というタイトルで発表させていただきました。資料はこちら(PDF)

当日の様子についてはHaskell入門の著者であり熟練YAPCレポーターでもある@hiratara氏がまとめてくれています。

個人的に印象に残ったものとして、@818uuuさんの発表を挙げておきます。「人間が検索結果をどのように見ているのか」という研究の引用に「検索結果の見方は6種類に大別できて、それを共通アルゴリズムで説明できるのでは?」という話を聞いて、目からウロコでした。

さて、私の発表に登場した技術たちについて、如何せん古い内容でしたので、よくわからなかったという方もいらっしゃるかと思います。そこで、雑な内容ではありますが、このエントリで少し補足をしておきます。

Catalyst

Catalystは、2005年後半~2008年ころにかけて流行したPerlのWeb App Frameworkです。

現在でもメンテナンスが継続されており、ルーティングに独自のルールがあることが特徴の一つと言えるでしょう。

gearman

gearmanはPerl製のジョブシステムです。job clientからgearmandと呼ばれるデーモンにキューを渡すと、perlのwhileループを軸に組まれたworkerプロセスに対して処理を委譲することができます。

動作が軽量なのですが、workerプロセスがダウンした際、処理途中の内容が全部揮発してしまうのが難点でした。

TheSchwartz

TheSchwartzもPerl製のジョブシステムですが、その構成にMySQLが必要となり、ジョブそのものの堅牢性をMySQLに委ねることで、gearmanのような途中処理の揮発という問題が起こりづらいとされていました。

現在は@akiym氏によってメンテナンスされているようです。

UltraMonkey L7

UltraMonkey L7は、Linuxなどにインストールして利用するタイプの、オープンソースのソフトウェアロードバランサーです。

名前に含まれている通り、OSI参照レイヤのレイヤ7プロトコル(HTTPなど)に対するルールを設定できる、大変貴重なソフトウェアロードバランサとなります。

heartbeat

heartbeatは、Linux/HAプロジェクトの成果物の一つで、IPアドレスの冗長化構成を行うソフトウェアです。

これのおかげでロードバランサーやルータを多重化することができました。

iptables

Linuxカーネルに組み込まれたパケットフィルターです。よくある用途としてはファイアウォールとしての利用でしょうけど、最近ですとdockerが内部的にexposeのために利用しているようです。

Perlメインだった人からみたElixir

最近Elixirにふれる機会が有りましたので、理解を深めるためにも、見識を書いていきたいと思います。

なお、このエントリを書いている時点でElixir歴だいたい3日ほどです。いろいろ間違えているかもしれませんが、もし間違いに気づいた方、Twitterで教えてくれると嬉しいです。

私のメイン言語変遷

ここでいうメイン言語というのは、「業務で主に触っている(触っていた)言語」という定義でよろしくお願いします(他にもたくさん触ってますけど、かくの面倒なのでいろいろ端折ったりしてます)。

  • 1998: batch(MS-DOSのアレ)
  • 1999-2000: bash, batch
  • 2001-2002: bash, PHP, たまにPerl
  • 2003-2015: bash, Perl, たまにRuby
  • 2016-2018: JavaScript(Node.js), Swift, PHP, たまにPerl
  • 2019: JavaScript??

タイトルにPerlメインだった人って書いてるのは、多分自分で一番慣れている言語がPerlだからそうしている、という感じです。このエントリもPerl使ってる向けに書いているところがあるので、ご了承ください。

ちなみに、とってもお恥ずかしい話なんですけど、Elixirに触るまではElixirが動的型付け言語だということすら知りませんでした。

個人的感想「これPerlでは?」

少し触ってみて思ったのは、「これはRubyというよりPerlにだいぶ酷似してるな」ということでした。

Perlについては、比較的歴史のある動的型付け言語ということでよく知られているかと思います。そしてPerl自体はマルチパラダイムな言語なのですが、実はPerlのご先祖様はLispということもあって、関数型パラダイムの要素を多分に包含しているのです。

一方でElixirもまたマルチパラダイムな言語であり、関数型パラダイムの要素がふんだんに盛り込まれています。その上動的型付け言語だということになると、この時点でだいぶPerlに似ている感じがしますね。

Perlで言うところの「あれ」が「これ」

さて、ここからは具体的な例を挙げて、ElixirとPerlの機能ごとのマッピングを少しだけしていきたいと思います(並列性云々の話は、そこまでたどり着けていないので書きません)。

Cartonだとかcpmみたいなやつは「mix」

RubyでいうところのBundler、Node.jsでいうところのnpm、そしてPerlでいうところのCartonに相当するものとして、Elixirではmixというツールがあります。

このmixは、Perlでいうところの「Minilla」でもあります(パッケージ作成ツールです)。

例えばmy_modというパッケージを作成する場合は、mix new my_modを実行すれば、パッケージのひな形がmy_modフォルダに生成されます。このとき、assertionベースな検証手法が用いられたテストコードも同時に生成される点なんかは、minil newしたときとそっくりですね。

依存パッケージの指定は以下のように、mix.exsdefp deps doendの間につらつらと記入していくようです。

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end

そして依存パッケージの導入はmix deps.getだけでOKとなります。

metacpanみたいなやつは hex.pm

ドメインがまさかの.pmなのでElixirはPerl!!!」というのは冗談ですが、Perlで言うところのmetacpan.orgに相当するのがhex.pmというサイトになります。

hex.pmはもともとErlangとElixirのパッケージ検索サイトなのですが、ElixirがErlangのラッパー言語だからか、Erlangで使われているエコシステムをそのまま使ってるようです。

例えばhttpクライアントが欲しい場合、hex.pmでhttp clientを検索すれば、いくつも該当します。

ただ、hex.pmにおける各パッケージのドキュメンテーションは、そのスタイルが統一されていない(CSSが全く違うというレベル)ので、読む側としては正直なんとかしてほしい気持ちはあります。きっとルールが定められていないからなんでしょうかね。。。

REPL(PerlでいうところのReply)は「iex」

標準でついてくるREPLはiexというものでして、必要十分かつ標準的な機能を持ちます。Perlで言うならばReplyが似たようなものかと思います(コチラは標準ではついてこないですが)。

Sigilは意味が違うけど、Perlにあるアレと似てる

Perlでは、Sigilというと変数の最初につく$@といった「変数の性質を決める記号」という事になっていますが、Elixirでは異なる意味の物となっています。それは、以下のような文字列リテラルや正規表現、文字のリストなどを表すためのものです。

// 文字列リテラル(エスケープ・式埋め込みあり)
strX = ~c/1 + 2 = #{1 + 2}/

// 文字列リテラル(エスケープ・式埋め込みなし)
strY = ~C/1 + 2 = #{1 + 2}/

// 正規表現
regex = ~r/(Perl|Elixir)/i

これらをiexで出力してみると、以下のような結果になります(IO.putsはperlで言うところのsayみたいなやつ)。

iex> strX |> IO.puts
1 + 2 = 3
:ok

iex> strY |> IO.puts
1 + 2 = #{1 + 2}
:ok

iex> "I like Elixir" =~ regex  
true

iex> "I like PHP" =~ regex   
false

iex> "I like Perl" =~ regex
true

正規表現の適用が=~なのもPerlと全く同じで、親しみすら感じます。

ところで、ElixirのSigilに相当するものが「演算子」という形でPerlにもあって、以下のように利用できます。

# 文字列リテラル(Elixirの~cに近いが、変数展開はするけど式展開はだいぶ特殊)
my $strX = qq/1 + 2 = @{[1 + 2]}/;

# 文字列リテラル(Elixirの~Cに同じ)
my $strY = q/1 + 2 = @{[1 + 2]}/;

# 正規表現
my $regex = qr/(Perl|Elixir)/i;

これらをsayしてみると、以下のような結果になります。

# 実行内容
use feature qw/say/;
my $strX = qq/1 + 2 = @{[1 + 2]}/;
my $strY = q/1 + 2 = @{[1 + 2]}/;
my $regex = qr/(Perl|Elixir)/i;
say $strX;
say $strY;
say 'I like Perl' =~ $regex;
say 'I like PHP' =~ $regex;
say 'I like Elixir' =~ $regex;
# 実行結果
1 + 2 = 3
1 + 2 = @{[1 + 2]}
Perl

Elixir

まとめ

ElixirとPerlの似たところをほんの少しだけ取り上げてみました。これをきっかけに、ElixirもPerlもちょっとでいいから利用者増えてほしいなぁ・・・

実は他にも似ている箇所が結構ある(構造体とパッケージの紐づけとか)のですが、このエントリはここまでにしたいと思います。この2つの言語、だいぶ似てませんか?私はかなり似ているなと思うんですが・・・。

フリーランスになりました

副業から本業に

もともと副業といいますか個人事業を一昨年からやっていて、これまでもいくつかチームマネジメントや技術相談などをご用命いただいていましたが、本日より完全にフリーランスとなりました。

ともあれ、これまで私を正社員として雇ってくださった会社とは、引き続き業務委託という形で(稼働日数を減らして)一緒にお仕事を続けることになっています。

動機

ちょっとした野望を内に秘めているのですが(いまはまだ明かせません・・・)、これを実現するためには、若干自分の時間が足りないな、と半年ほど前から実感していました。しかし、副業をしていたこともあり、稼ぎについて大きな不安なしにこの決断をすることができました。

この結果を得るまでにはそこそこの紆余曲折を経ましたが、とにかく、時間の使い方をもうすこし自分で選びたい、という小さな目標はこれで達成できるのかなと思っています。

どんなお仕事をやっていくのか

冒頭でリンクしたスイ・ソリューションズ(屋号)では、主に以下のようなお仕事を承っております。

  • 各種システムの現状調査
  • webシステム及びクラウドシステムに関するアドバイス・提案

ちなみに今年でITエンジニアとしてのキャリアは20年目に突入するのですが、私は下記の事項に実績があります。

  • Microsoft Azureにおける各種SaaS/PaaSを使ったシステム設計・構築・運用(特にAzure Functions)
  • 20年にわたるLinuxに関する知見
  • Perl, PHP, bash, JavaScript(Node.js), Swiftなど、10種以上の言語による開発実績(とくにAPI)
  • TDDの導入
  • MySQLにおけるクエリチューニング(あくまで開発者として。)
  • エンジニアチームの立ち上げ、マネジメント、メンタリング
  • プロジェクトのマネジメント
  • 事業におけるシステムのポジション定義と予算策定

もし興味がありましたら、メールやTwitterでご連絡ください。無論、対面でも構いません。

まとめ

装甲騎兵ボトムズ的にまとめるなら、以下のようになるところでしょうか。

変わる、変わる、変わる。この世の舞台をまわす巨獣が、クラウドの底でまた動きはじめた。

天が軋み、人々は呻く。舞台が回れば吹く風も変わる。
昨日も、今日も、明日も、時の流れに閉ざされて見えない。

だからこそ、時を操る術を求めて、褪せぬ技術を信じて求めて。

次回「急変」。

変わらぬ技術などあるのか。

WEB+DB PRESS Vol.109 に寄稿させていただきました

紹介

WEB+DB PRESSVol.109(技術評論社:gihyoより2月23日発売予定)のPerl Hackers HubコーナーにサーバレスでもPerlというテーマで寄稿させていただきました。

ぜひお買い求めください!

Perl Hackers Hub – Perl Hacker達による旬の技術の紹介

Perl Hackers HubとはWEB+DB PRESS誌内の連載のひとつであり、Perl Hacker自身が筆を執り旬の技術を紹介するというものです。

gihyoさんのPerl Hackers Hubのページには、Perl Hackers Hubについて以下のような説明がついています。

本連載は,第一線のPerlハッカーが回替わりで,Perlの旬な技術について解説していきます。

記事概要

Microsoft Azure Functionsを使ってPerlスクリプトを実行します。スクリプトの内容は、「画像URLを与えると、画像の顔認識結果(年齢と性別)をJSON形式で返すWeb API」です。

サンプルコードとして、Azure上に環境とプログラムを全自動でデプロイしてくれるスクリプトを収録してあります。Azureアカウントがあれば、最初の無料枠で試せる範囲の内容となりますので、ぜひともお試しください。

謝辞

この度機会を与えてくださった@songmuさん、Perl Hackers Hubコアメンバーの皆さん、そして一緒に原稿の仕上げをしていただいた@inaoさん、本当にありがとうございました。

特に@inaoさんには度々ご迷惑を掛けてしまったにもかかわらず、辛抱強く対応してくださいました。感謝しきりです。

また、Azureについて深く言及した内容の記事はWEB+DB PRESS誌上では初めてだそうです(本当ですか?)。私も驚きました。正直な話、流石にAzureについては過去に誰か書いているだろうと思っていたのですが…意外なところで「誌上初」だったんですね。

ともかく私としては、今回の記事がPerl Hackers Hubというコーナーを通じて、様々な技術に触れるきっかけを読者の皆様に作ることができたらいいな、と思っています。

YAPC::tokyo 2019で登壇しました

YAPC::Japan 2019にて「実演サーバレスPerl – 顔認識データを扱おう」というタイトルで登壇させていただきました。見に来てくれた方、本当にありがとうございます。

そして、結局ライブコーディングするための時間が足りず、見せ場を作れなかった点、本当にごめんなさい。あの後、見に来てくれていた同僚や@note103さんに励まされたのが本当にありがたかったです。

資料

敗因

20分で、受け手側に前知識が必要な内容をライブコーディングするのは、あまりにも無謀でした。

前知識のインストールが終わった時点で7分ほど経過しておりました。さらにクラウド側(Azure)の処理待ち時間が思った以上にかかる。

これではまずいということで、事前に用意しておいた出来上がり環境を使って説明していきましたが、それでも時間が足りず、コードを書くところをお見せできませんでした(コードそのものをお見せすることはできたのですが・・・)。

補足(というか宣伝)

今回のセッションをおさらいする内容で、Web+DB Press誌 2019年2月号のPerl Hackers Hubに寄稿させていただいております。まだ発売まで時間がありますが、より詳しく解説されているものとなりますので、興味のある方はぜひお買い求めください!

また、Web+DB Press誌ではサンプルコードも提供します。サンプルコードは、今回の顔認識システムを自動でAzure上に構築するスクリプトとなっておりますので、構築する手間が惜しいが試すだけ試してみたい、という方にもおすすめです。

前夜祭でもLTしました

本編のみ参加の方はご存じないかもしれませんが、前夜祭でもLTで発表しました。Webappにおける@INC Hooks絶対許せないマンとしてネタに振り切った内容です。

LT資料

Acme::AtIncPoliceのその後

実は昨日Acme::AtIncPoliceissueが立ちまして。なんだろうと思ってみてみると、「Testで使ってるTest::Exceptionが入ってないからTest失敗するんですが」という内容でした。

それを受け、今朝慌ててTest::Exceptionをdependencyとして登録し、shipit。なんと0.01をshipitしてから、たった2日で0.02をshipitすることとなってしまいました・・・

感想など

@songmuさんベストトークおめでとうございます!感極まって感情が溢れ出たときに、周りで何名かもらい泣きした人がいたんですが、songmuさんの情熱があるからこそなんだろうなと。

個人的には@risouさんのPerl6トークと@hitode909さんのWebVRトークがかなり良い話だと思いました。hitode909さんからは豆本の夢日記を頒布していただきました。家宝にします。

Azure Functions v1 + Node.jsなアプリケーションをAzure Functions v2に移行してみる話

このエントリはServerless2 Advent Calendar 2018の17日目のエントリとなります。

半月ほど前業務で、稼働中のAzure Functions v1 + Node.jsなアプリケーションをAzure Functions v2に移行する作業を行いました。

その際、今後も似たような移行作業があり得そうだと考え、この作業をざっくりこなしてくれるスクリプトを作りました。それがytnobody/azure-func-migrate-nodeです。ちなみにPerl製ではなくNode.js製です。

如何せんやっつけで作ったスクリプトですので、漏れ・抜けなどはあるかもしれませんが、お手すきの際にでもpull-reqしてくださると幸甚です。

移行のために最低限必要な処理

大きく分けて、以下の作業が必要となります

  • bindingsに対応したextensionsをインストールする
  • ランタイムバージョンを2.0に設定する

bindingsに対応したextensionsをインストールする

実際のextensionsインストール作業はfunc extensions installに委譲しているのですが、これまでv1で使っていたbindingsに相対するv2 extensionsを検出するロジックは作成しました。

なお、v1では"type": "documntDB"と指定していた箇所は"type": "cosmosDB"に変更する必要がありますので、その対応も行っています。

ランタイムバージョンを2.0に設定する

これもロジックを作りました。

まとめ

ざっくりと移行スクリプトを作りましたので、公開しました。が、だいぶやっつけで作ってありますので、適宜pull-reqをしてくださると幸甚です。

昔書いたGithub止まりのモジュールをほじくり返す – Test::Proc 篇

※このエントリはPerlアドベントカレンダー2018の5日目のエントリとなります。

CPAN(MetaCPAN)でモジュールを公開するということ

Perlでプログラムを書くことに慣れてくると、CPANモジュールを使うようになったり、もっと慣れてくると自分でPerlモジュールを作るようになり、最終的にはCPAN(今はMetaCPANですね)で公開するようになるかもしれません。私は過去にそのような道を歩んできました。

では私は過去にどんなモジュールを書いたのか。ひとまずMetaCPANに上がっているものを一部挙げると、 Otogiri(これはほとんど@tsucchiさんの力です), XML::Diver, Net::Azure::CognitiveService::Faceなどがあります。

PerlモジュールをMetaCPANで公開する前に

しかしながら、MetaCPANでモジュールを公開する前に気にかけておいて欲しいこととして、個人的には以下のような項目を挙げたいと思います。

  • そのモジュールを公開することで不快感を感じる人々が生じないか
  • そのモジュールはセキュリティ的に致命的な問題を抱えていないか
  • そのモジュールは新しい機能を提供してくれるか
  • そのモジュールはプログラミング体験をより幸せにしてくれるか
  • そのモジュールは従来の類似モジュールよりもパフォーマンスに優れるか
  • そのモジュールは従来の類似モジュールよりも依存性が削減されているか

もし上記について該当するかわからない場合は、ひとまずgithubに上げておきつつ、ブログやTwitter等で言及してみましょう。運が良ければ誰かが注目してくれて、レビューをしてくれるかもしれません。これらのことは、Perlモジュールの公開に及び腰になってしまわない程度に、気をつけるとよいのではないでしょうか。

CPANの歴史を少しだけ垣間見る

では、なぜこのように自律する必要があるのでしょうか。それを知るためには過去に目を向けることが重要です。

歴史を振り返ると、charsbarさんによるエントリでCPANは幼稚園児の砂場じゃないよねという、2008年当時、大変考えさせられたものがあります。若い方の中にはこのような歴史を知らない方もいると思いますが、是非とも同じ轍を踏まぬための知識として、知っておいていただければ幸いです。

また、まかまかさんによるPerl同人誌「Acme大全」には、「Acme大全2012」から毎回、巻末付録として「とあるAcmeモジュールの削除について」という章が設けられています(ブログにも同様のエントリがある)。

このように、MetaCPANへモジュールを公開する上では、ある程度その性質を律せられる側面があることは間違いないでしょうし、誰かがつらい思いをしないためにも必要なことであると私は思います。

それでも日の目を見ないモジュールもある

そんな事もあって、実際にはたくさんのPerlモジュールを作っていたとしても、実際にMetaCPANにて公開されるものはその一部でしかありません。ほかにもMetaCPANに公開するのが怖いとか、作者がそこまでの有用性を感じていないだとか、謙遜している、などの理由でMetaCPANで公開されていないPerlモジュールがGithubにはあります。

このようにあえてGithubでの公開にとどめられているPerlモジュールを、私は親しみを込めてGithub止まりモジュールと呼んでいます。

そして今回紹介するGithub止まりモジュールは、拙作のTest::Procです。

Test::Proc – プロセスを起動し、その起動状態をテストする

Test::Procは5年前にGithubにpushされています。今となっては当時の記憶を頼りに解説する他ないという点がいささか不安です。

さて、Test::Procが目指したところは、テストスクリプトでプロセスの起動状態をテストしたいというものでした。

使い方はSYNOPSISにある通りです。(done_testingが抜けていたので、補足してあります。)

use Test::More;
use Test::Proc;


my $proc = test_proc 'my_task' => sub {
    print 'test';
    warn 'dummy';
    sleep 20;
};


$proc->is_work;


$proc->stdout_like( qr/\Atest/ );
$proc->stderr_like( qr/\Adummy/ );


$proc->exit_ok;
done_testing;

あら捜し

レポジトリを見てみると、テストの少なさが気になります。github止まりモジュールにはよくある話かもしれないですが、だいぶ控えめなテストの数だなと感じますね。

そしてインターフェースが片手落ちです。というのも、このTest::Procはtest_procというDSLを提供しており、Test::Proc::Objectインスタンスを返しているのですが、test_proc側にはクロージャ以外でプログラムを起動する方法が提供されていません。Test::Proc::ObjectはProc::Simpleのサブクラスであり、24行目で引数の$codeを実行しているので、Proc::Simpleのインターフェースを見る限り、文字列で外部コマンドとオプションを渡すことができるはずです。

実験

実際に以下のようなテストを作って実験してみました。

$ cat hoge.sh 
sleep 3
echo "hoge"

$ cat t/12_shell.t 
use strict;
use Test::More;
use Test::Proc::Object;

my $proc = Test::Proc::Object->new('sleep 3 sec. Then print "done"', 'bash ./hoge.sh');

$proc->is_work;
$proc->exit_ok;
$proc->isnt_work;

$proc->stdout_like(qr/\Adone\z/);
$proc->stderr_like(qr/\A\z/);

done_testing;

これを実行すると、以下のようになり、テストは成功します。

$ perl -Ilib t/12_shell.t 
ok 1 - process sleep 3 sec. Then print "done" is work
ok 2 - process sleep 3 sec. Then print "done" exit code is 0
ok 3 - process sleep 3 sec. Then print "done" is not work
ok 4
ok 5 - process sleep 3 sec. Then print "done" STDERR like (?^:\A\z)
1..5

深掘りしていく

上記のことから、test_procにコマンドを文字列渡しして起動させることができそうですが、実際に以下のようなテストを試してみると、失敗してしまいます。

$ cat t/13_shell-with-test_proc.t 
use strict;
use Test::More;
use Test::Proc;

my $proc = test_proc 'my_work' => 'bash ./hoge.sh';

$proc->is_work;
$proc->exit_ok;
$proc->isnt_work;

$proc->stdout_like(qr/\Adone\z/);
$proc->stderr_like(qr/\A\z/);

done_testing;

$ perl -Ilib t/13_shell-with-test_proc.t 
Type of arg 2 to Test::Proc::test_proc must be sub {} (not constant item) at t/13_shell-with-test_proc.t line 5, near "'bash ./hoge.sh';"
Execution of t/13_shell-with-test_proc.t aborted due to compilation errors.

これはtest_procのインターフェースが($&)となっているために起こっている問題となります。ですのでこれを($$)としてあげると、以下のように成功します。

$ perl -Ilib t/13_shell-with-test_proc.t 
ok 1 - process my_work is work
ok 2 - process my_work exit code is 0
ok 3 - process my_work is not work
ok 4
ok 5 - process my_work STDERR like (?^:\A\z)
1..5

なぜgithub止まりなのか

このように、完成度の低さゆえにgithub止まりとなっているTest::Procですが、その他に大きな理由として、私個人が出くわす状況にそもそもテストスクリプトでプロセスの起動状態をテストしたいケースがあまりにも少ないという点が挙げられます。

そういうわけで、結局あまり洗練もされないまま5年もgithub止まりとして塩漬けになっていたというわけです。

Test::Procの今後

一応、ユースケース的に「いいじゃん?」って思ってくれる人がいらっしゃるのであれば、forkしてshipitするまでやってくだされば良いとおもいますが、今の所私自身がなにかをするということは無いでしょう。

コンセプトモデルということでここはひとつ、ご理解いただければ幸いです。

まとめ

ざっくりまとめると以下のようになります。

  • MetaCPANでPerlモジュールを公開する前に、いま一度そのモジュールの性質を見つめ直そう
  • Perlコミュニティの歴史から、誰かがつらい思いをしないための行いについて知ろう
  • Test::ProcというPerlモジュールを作ったけど、ユースケースに遭遇しなさすぎて結局Github止まりになった
  • Github止まりモジュールは「コンセプトモデル」として見ると良さそうかも

明日のPerlアドベントカレンダーは6日目。@yoku0825さんによる「マイエスキューエルにはPerl Mongerが必要かもしれないはなし」です。