とらきす の ぐだログ

とらきすのぐだログ

ぐだぐだとなんかするブログ。

梅田プラザモータープールに行こうと思い中津駅で降りたものの実は最寄駅は阪急中津駅ではなくて御堂筋線中津駅であったことに気づいたときのためのメモ

梅田プラザモータープールといえば、JAMJAMライナーなどの高速バスターミナルだ。最寄駅は 大阪メトロ御堂筋線 中津駅とされている。

私を含めたおっちょこちょいの方々は、御堂筋線中津駅ではなく 阪急 中津駅に降りてしまったのではないだろうか。
その場合、どれだけググっても阪急中津駅からプラザモータープールまでの行き方が出てこないので、ちょっと困ることになるというか、不安になる。

なので、メモしておく。所要時間は5分ほど。
こんなもの読まずともGoogleマップ使えという話ではあるが、100%信用できるものでもないし、確実に行けるという記録があるだけでも安心材料にはなる。面倒なので写真は撮っていない。


まず改札を出て、右手側の西出口へ向かう。
方向的には東口の方が正しそうだが、それは罠である。西出口側の案内板にもちゃんと「プラザモータープール方面」と書いてある。

西出口の階段を登ると高架上の大通りに出る。向かいには「がんこ寿司」の看板が見えるはず。
そうしたら、階段を登ってきた向きとは逆、つまり「がんこ寿司」の看板に背を向け、南東へ向かって高架を下っていく。

そのまままっすぐ進むと、大きな交差点に出る。
まっすぐ横断歩道を渡り、大通り沿いを数十m進むと、左手に梅田プラザモータープールが出てくる。到着。


終わり。みじか。

ワクチン3回目、しんどい

3回目の COVID-19 ワクチンを接種してからおよそ36時間が経過したが、ちょっと自分でもびっくりするくらいグロッキーになっている。が、それなりに良い経験ではあるので文字として残しておくことにする。

今までにあまり大きな病気をしたことがなかったため、気づくのになかなか時間がかかってしまったが、ワクチン接種3回目の副反応はかなりきつい。

1、2、3回目のいずれもファイザー社製のワクチンで、1回目の時はほぼ全く副反応はなく、2回目の時は注射した腕が痛かったのと発熱があっただけで、たいした自覚症状はなかった。こんな結果であったから、今回もせいぜい腕が痛くなるくらいだろうとタカをくくっていた。
既に3回目のワクチン接種を終えた周りの人からは「丸2日ずっと寝込んでいた」みたいなのをよく聞いていたので、事前に食料品・消耗品を買い込んだりとそれなりに対策はしていたのだが、まさかここまでとは思っていなかった。

ワクチンを接種してすぐは何の症状も出なかった。2回目の時は注射してからすぐ腕が痛くなり始めたので、やはり今回は2回目よりも軽症状なのではないかと安堵した。ワクチン接種の帰りに油そばを美味しくいただいた。

それから半日くらいの間は、腕が痛くなり始めたくらいで、これといって無症状だった。ワクチンを接種する前の日はあまり満足に睡眠を取れていなかったので、昼寝をした。

唐突に目が覚めた。なぜかはわからないが、寒くもないのに全身が震えていた。これはこれで面白かったので身を委ねていたら、また眠りに入った。

次に目が覚めたのは、眠りについてから6時間後ぐらいだった。とにかく頭が痛かった。睡眠を取りすぎて偏頭痛になるというのはよくあることだったので、今回もその類だと思った。
とりあえず様子見にマツモトキヨシの安い頭痛鎮痛剤を飲もうとしたが、異様に寒気がすることに気づいた。室温を見るとだいたい25℃前後で、むしろ暖かいとさえ言えるのに、やたらと肌寒く感じた。身体を動かすのも非常にだるかった。

体温計が見当たらなかったので、Apple Watch で脈拍を測って計算してみると、少なくとも39℃以上の熱が出ているようだった。明らかに身体が熱くなっていることがわかった。
鎮痛解熱剤を飲んで30分を経過しても頭痛は収まらない。バファリンを引っ張り出してきて飲んでみたが、やはりこれも効果はなかった。

汗をかいていたのでシャワーを浴びたが、なんとなく感覚が鋭敏化していることに気づいた。シャワーを背中に当てると少しだが痛みを感じる。指先もピリピリと痺れているような感覚があった。ただ、これは寝起きで血管が拡張しているせいかもしれない。

さっきまで寝ていたので何かしようと思ったが、身体が動いてくれない。頭がズキズキと痛み、身体中 強い倦怠感に襲われていた。結局 寝る以外に何もすることができなかった。このあたりで、ようやく「これはしんどいぞ」と思い始めた。

先ほども書いたが、これまでに大きな病気をした経験があまりないので、「しんどい」というのがどういう状態なのかわかっていなかったのだ。身体的にもわりと病気に強い方ではあるし、ほかに類を見ないほどの楽天家であるので、精神的にも辛いという経験をしたことがなかった。
これで、だいたいどういう症状が出てきたらしんどいのかというボーダーラインが引けた気がして、良い経験にはなったと思う。

カロナールよりもロキソニンの方が効くと親が言っていたので、足元もおぼつかない状態でひぃひぃ言いながらマツモトキヨシに行ってみたが、それなりに遅い時間帯だったので薬剤師がおらず、ロキソプロフェン系の鎮痛解熱剤は買うことができなかった。代わりにラックルを買って飲んでみたが、やはり効果なし。アセトアミノフェン系は効かないのだろうか。

食欲がないというのもはじめての経験だった。そのことに気づいたのは、最後に物を口にしてから24時間ほど経過してからだった。どれだけ体調が悪かろうとお腹が空かないことなんてないだろうと思っていたのだが、それは事実ではなかった。飲み物しか口にしていないまま24時間が経っても空腹感はまるでなかった。
何か食べなくてはと思い事前にコンビニで買っておいたうどんを食べてみたが、数口で「もう要らない」と感じた。胃が食事を受け付けないとはこういうことかと納得した。

飲み物は普通に飲めていたので、inゼリーを買ってきて食べるようにした。それまでは緑茶ばかり飲んでいたのでわからなかったが、inゼリーを食べてみて、あまり味がしないことに気づいた。
味覚には甘味、酸味、塩味、苦味、うま味の5つがあるも言われているが、特に酸味、塩味、うま味はほぼ感じられない。甘味はやや感じるが、苦味だけそれまで通り感じるため、何を食べても苦く感じる。

嗅覚にはたぶん影響はない。と思う。

と、この文章を書いているうちに熱はだいぶ下がってきた気がする。それなのにやたら汗をかくのが奇妙だ。
倦怠感はだいぶ薄れてきたが、頭痛はまだ止まない。

明日までに頭痛が治まっていることと、味覚が戻ることを祈りながら眠りにつくことにする。


経過。

寝起きはわりと良好。ただし頭痛あり。脈拍は昨日とあまり変わらず。
味覚はあいかわらずぶっ壊れていて、塩を舐めてみてもしょっぱいと感じない。 どちらかと言うと「にがり」っぽい味に感じた。

体調はまだあまり優れてはいなかったので、お仕事を休むことに。

ただ、頑張れば出かけられるぐらいの元気はあったため、ロキソニンを買いにマツモトキヨシへ。ついでに体温計も買っておく。

熱を測ってみると、38℃前後。
ロキソニンを飲んだが、頭痛は収まらない。効かないときは効かないものだ。

そのまま安静にして、夕方頃にはだいぶ身体が軽くなった。熱を測ってみると既に平熱に戻っていた。

驚くことに味覚は多少戻っていて、塩味はだいぶ感じられるようになっていた。
ただ、うま味は依然としてまるで感じられない。シンプルな麺つゆ味のぶっかけうどんを食べてみても、やはり苦味が勝つ。おそらく和食や魚介類はこんな調子だろう。
ただでさえコーヒーや酒が飲めず辛いものや酸っぱいものが食べられないという子供舌ぶりが、よけい悪化したようである。

そういうわけで、食欲もあまりない。美味しいものを美味しいと感じられないと分かった途端、食べたいという意欲がストンとなくなるというのも興味深い話である。
幸いなことに甘味はほぼ元の状態にまで回復しているようで、しばらくはinゼリーにお世話になるかもしれない。


そういうわけで、およそ接種から60時間くらいで副反応は収まった。味覚はまだなんかおかしいけど。
21年という人生の中で最も体調が悪い時間だったと自信を持って言える。

もし次の機会があるのなら、もちろん接種はするが、今までのように快くというわけにはいかないだろうと思った。

半年が経った

社会人になって半年と1ヶ月が経ちました。

ざっくりと振り返ってみると...
岐阜高専に入学し、留年して2回目の2年生を終えたあとに退学して、高卒認定を受験して、名古屋の専門学校に行き、その途中で Chatwork のサマーインターンシップに参加して、そのまま新卒で入社させていただいて...

こうして見てみると、面白い経歴してるなーと思います。

まぁ、留年したとか退学したとか、そのへんは何かと話のネタになりますし、わりとどうでもいいんですね。
それよりも、高校課程をちゃんと修了できていないこととか、大学に行っていないってことのほうが、個人的には気にしているところです。

なんか、階段を飛ばしてきてしまった感覚と言いますか、多くの人が経験するフェーズをすっ飛ばしてきたというのは、それなりに不安になるものです。
だって、高卒認定+専門学校卒ですからね。専門学校卒というだけでもそこそこめずらしいのに、高校を卒業していないとなると、なかなかレアだと思います。

少なくとも大学を出ているのがあたりまえになってきている中で、こういった特殊な経歴を持っていても何の隔たりもなく入社させてもらえたことはすごくありがたいですし、自分としてもよくやったなぁ とは思いつつも、はたして自分は人並みの仕事ができるのだろうか、置いていかれないだろうか... という不安は少しあったわけですよ。

...とまぁ、入社前後はそんなことを考えていたりしていましたが、今のところはそのあたり全然気にすることなく働けているので、思っていたよりもポジティブに捉えていけている今日この頃でございます。

今は Scala を書くお仕事をしているわけですが、これがまぁ楽しいの何のって。
自分の好きなことを仕事にできるのはいいもんです。好きなことをしてたらお金がもらえてしまう夢のシステム... やはり仕事はモチベが出るかどうかで選ぶべきですね。

同時に一人暮らしも始めて... 正直、専門学校卒というラインから考えるとかなり良い方だと思われる待遇で入社させてもらえていて、まぁ、一切の不自由なく、楽しく生活しています。そういや、入社してからまだオフィスに一度も行ってないや。

しいて言えば、実家にいた頃と違って猫がいないのがさみしいところですね。サカナクションの「壁」が刺さりまくる...

サカナクションのライブ、行きたいなぁ。


えー、そんな仕事に就いてから半年が経過して、つい先日22卒内定者の内定式がありました。

いやいやいやいや早すぎるって。
まだ気持ちは新卒社員なんですけど、というか実際 新卒社員なんですけど、もう半年したら次の新卒社員が入ってくるんです。こえー。だいたいが年上だし...

てなわけで、また不安が再燃しつつありますね。精進しなきゃ。

おわり

持ってる古い音源のやつ

2021/10/02: Virtual Guitarist Electric Edition の存在を完全に忘れていたので追記。


ども。

最近はお仕事が楽しくてしかたがない日々を過ごしているのですが、逆にそれ以外の時間は YouTube とニコニコ観てるか寝てるかくらいしかしてなくてですね。
仕事が趣味みたいになってしまうと良くないなと思い、最近また DTM を少しずつやりはじめています。

それで、ついに MIDI キーボードを買いました。Nektar Technology の GXP 49 ってやつ。
今までずっとマウスぽちぽちだけでノート置いてたんですが、なにせ音感がまるっきりないもので、頭の中に出てきたフレーズをピアノロールに描くのがすっごく時間かかるんです。なので、そのインターフェースとして MIDI キーボードがほしかった。
今はがんばってピアノのお勉強中。両手を別に動かすのに慣れていなくてヒィヒィ言いながら練習してます。一時的にミギー寄生してくんないかな。

あとオーディオインターフェースもほしい。ずっと Roland UA-M10 を使っていたんですが、なんか定期的にブツブツ音が切れるようになってしまいました。
Windows 11 に上げたのが悪かったのかな... Mac だと普通に使えてるんですけど、もうサポート切れてますし。この製品は Roland にしてはめずらしくサポート期間がやけに短命で困ったものです。

さて、なんとなく気が向いたので、所持している古い音源をいくつか紹介してみます。

Roland / EDIROL Super Quartet

2001年に RolandEDIROL ブランドより発売されたマルチティンバー音源。兄弟分の GM2 音源である Hyper Canvas、ならびにそのスーパーセットである音源モジュール SD-90 と同時に発売されました。

ピアノ、ギター、ベース、ドラムの4構成マルチティンバー音源で、今は亡き Cakewalk Music Creator 2002 がバンドルされています。

f:id:trackiss:20210925053350j:plain
これがパッケージ。ロット番号的なものがディスクに書いてあったので念のため消してあります

わたしが持っているのは英語版で、日本版のものとパッケージがやや異なっています。ただ、ディスクおよびソフトウェアは日本版のものと共通のようです。
なぜ英語版なのかというと、海外から購入したから。イタリアのとある楽器店のオンラインストアでたまたま売っているのを見かけたのです。まだ在庫残ってたりして。

ここに書き連ねている中では最上級のレア音源。同じビンテージものでも、Virtual Guitarist みたいなよく売れた音源とは違って出荷数が少ないせいでしょうか。ともかく、日本ではもうなかなか手に入らないもののうちのひとつです。

シリアル番号によるライセンス認証 (オフラインなので単に番号のバリデーションしてるだけだと思います) を導入していますが、それとは別に、およそ2週間に1度の頻度でディスク挿入を要求してくるという悪名高い不正防止策を導入しています。
加えて、リングプロテクト、いわゆる SafeDisc というプロテクトがディスクにかかっていて、吸い出しておくという手段をとることができない。SafeDisc とは、不正なセクターをディスクに仕込むことで違法コピーを防ぐ (苦しまぎれの) 技術ですね。

こう考えると、USB-eLicenser はなんとも優秀なライセンス認証方法だったということがわかりますね。これをあんな初期から導入していた Steinberg、すごい。
ま、あれはあれで、USB-eLicenser 壊れたら云々みたいな話はありますけども。

この Super Quartet という名前ですが、実は Roland の歴史にこの名が出てくるのはこれが2度目のことだったりします。
1度目は、1985年にリリースされた最初期の音源モジュール MKS-7 Super Quartet。これまたメロディ、コード、ベース、ドラムの4構成からなるマルチティンバー構成となっています。
いかにも80年代らしいパワーのある音で、特にドラムの音が個人的には好き。というか、ほぼ完全に TR-707 の音ですが。

UVI が MKS-7 を Super-7 としてソフトシンセ化しているので、気になる人はどうぞ。

Steinberg Hypersonic 2

2005年に Steinberg より発売されたマルチティンバー音源。今でいう HALion Sonic 的な立ち位置の製品、いわゆるロムプラーってやつですね。

f:id:trackiss:20210925053418j:plain
USB-eLicenser つき。なぜかディスクのパッケージがめっちゃ安っぽい

たまにサンプルを読み取ってくれなかったりして、現在の環境ではちょっと完動は厳しいかもしれないです。独自のフォーマットでサウンドコンテンツを管理してるので、HALion に読ませたりして使うこともできません。カナシヒ

Hypersonic 2 は、泣く子も黙る Wizoo がまだ Steinberg と仲がよかった頃の製品で、わずか 1.7GB のサンプル数 (これでも当時としてはかなりビッグサイズではある) にしてかなり高品質なサウンドを奏でてくれると評判だった。らしいです。

今は、この Hypersonic の直系の子孫 (腹違いの子とも言える) である Xpand! 2 が Air Music Technology からリリースされていますね。

Air Music Technology がかつての Wizoo であることは、この記事を読んでいるような人ならすでに知っていることと思いますが。
伝説のサウンドチーム Wizoo Sound Design は、Air Music Technology と UJAM へと姿を変え、今なお DTM 界で猛威をふるっているんですねぇ。

Steinberg HALion 2

2003年に Steinberg より発売されたサンプラー

f:id:trackiss:20210925050803j:plain
HALion 1.1 と HALion 2 のインストーラーディスク、そして4枚組のコンテンツディスク。外箱は持っていない

コンテンツディスクは4枚組で、Wizoo と eLab のロゴが入っています。
ただ、この写真に写っているものは HALion 2 のものではなくて初代 HALion のコンテンツディスクです。
HALion 2 のメインのサウンドコンテンツは初代 HALion のものと変わらないため、アップグレード版を購入したユーザーの場合は HALion 2 のインストーラーディスク (この中に少し追加サウンドも収録されている) のみが送られてきていたんですよね。

HALion 2 はそれなりに古い VST なので、Windows 11 が動いてる今の PC ではあまりマトモに動いてくれません。かなしいね。jBridge をかましてもだめ。

数日前に Absolute 5 を買ったので HALion 6 に読ませてみたら、HALion 3 Contents という扱いになりました。バリバリ使える。

Steinberg Virtual Guitarist Electric Edition

2002年に Steinberg より発売されたエレクトリックギター音源。実際のギタリストが演奏したギターの音を収録している超リアル (というか、実際リアルですし) な音源です。

f:id:trackiss:20211002171544j:plain
インストールディスクは3枚組。ディスクパッケージの気合いの入れようがすごい

Virtual Guitarist が発売されてからわずか半年ちょっとしか経っていないのに発売されたというのがすごいですね。当時の Steinberg はかなりハイペースで新製品を出していたという感じを受けます。

Virtual Guitarist Electric Edition はその名のとおりエレクトリックギターに特化した音源で (無印の Virtual Guitarist はアコースティックもエレクトリックもまんべんなく収録してました)、マルチエフェクターもついてきます。
このエフェクターVSTe としても使用できるんですが、こいつがかなり優秀で、普段使いにも適しています。

わたしは今は無印 Virtual Guitarist は持っていないんですが、Virtual Guitarist と Virtual Guitarist Electric Edition のサウンドがすべて収録されている Virtual Guitarist 2 は持ってるんです。ただ、Virtual Guitarist Electric Edition とはエフェクターの互換性がなく、ちょっと出音が変わってしまうため継続して持っているという感じ。

Steinberg Studio Case

2003年に Steinberg より発売されたスタジオバンドル。Cubase の廉価版である Cubase SE に加え、Steinberg 謹製 VSTi の廉価版が5つもバンドルされたお得製品!

f:id:trackiss:20210925053546j:plain
ジェラルミンケースをモチーフにした特大パッケージ。届いたときに「デカすぎんだろ...」と素で口に出してしまった

f:id:trackiss:20210925054105j:plain
中身。日本語版 PDF マニュアル、Cubase SE のインストーラー、プラグインインストーラー2枚、ストーム・ハウス・スタジオのインストーラーといった計5枚のディスク、USB-eLicenser、説明書など

とにかくケースがでかいのなんの。それでいて中身は CD-ROM 数枚、USB-eLicenser、説明書のみなので、がら空きです。
Hypersonic 2 とか、大きめの箱はこの中にいっしょにしまってあります。

付属するプラグインは次の5つ:

  • D'cota SE
  • Groove Agent SE
  • HALion SE
  • Virtual Guitarist Electric Editon SE
  • The Grand SE

いずれもライセンス認証が必要ないタイプの VSTi で、ほかの DAW でも普通に使うことができます。今の環境では、HALion SE と The Grand SE は動いてくれませんでしたが。

また、これは日本語版だけかもしれないですが、ストーム・ハウス・スタジオという見慣れないディスクがついてきています。これは、かの Arturia がかつて開発していた STORM という音楽作成ツールの日本向けラインナップのようです。

2005年には、新バージョンである Studio Case II が発売されています。変わったことは、無印 Cubase SE が Cubase SE 3 になったこと、そして Virtual Bassist SE が新たにバンドルプラグインに仲間入りしたということ。
Virtual Bassist SE のみライセンス認証が必要なようで、これもやはりほかの DAW でも使うことができると思います。知らんけど。

今となっては微妙かもしれないですが、音ネタとしてはそれなりに有用。特に D'cota と Groove Agent SE は使えますね。オークション等で安く売っていれば買うのもアリだとは思いますよ。安ければね。

Steinberg Groove Agent 3

2008年に Steinberg より発売されたドラム音源。

f:id:trackiss:20210925054548j:plain
相変わらず箱がでかい。そのかわり説明書もかなり分厚い

前は Groove Agent 2 を持っていて、でもあれは友人に売ってしまっていたんですね。
で、数日前にたまたま Groove Agent 3 を購入できる機会に恵まれたので、せっかくだし新品で購入。新品とはいえ、それなりに古い音源だからか €99 という破格で買えました。

今の Groove Agent にも引き継がれていますが、いわゆるバーチャルドラマーとしての役割が強いのが特徴。年代やスタイルごとにたくさんのプリセットが用意されていて、それぞれ実際のドラマーが演奏した演奏パターンが大量に収録されています。

Groove Agent 3 では Groove Agent 2 に比べてプリセットがいくつか増えているのと、Special Agent、Percussion Agent というモジュールが追加されてます。
前者はいわゆるドラムリプレイサー的な技術を活用したもので、実際のプロによる演奏をうまい具合にリズムに合わせて再構成してくれるとのこと。後者は今の Groove Agent にもあるようなパーカッションのサウンドセットですね。

ただ、なんかファーストインプレッションとしては Groove Agent 2 のほうが使いやすかった... 気がする... まだ慣れてないだけだと思いますが。

余談。
Groove Agent 4、5 は 3 みたいな即戦力みたいな感じではあまりないですが、音作りがとてもやりやすいんですよね。エフェクトもたくさんそろってるし。
あと拡張ライブラリが非常に優秀。唯一残念なのは、TR-808 とか Simons とか、ビンテージドラムマシンの拡張ライブラリがいまだに存在していないことですね。出したら絶対売れるのに。
いちおう標準ライブラリにもそれっぽい音は入ってるんですけどね、Retrospective とかモロ Linn Drum ですし。


ここに書いてないのは写真撮るのが面倒だったやつです。LM4 MKII は実家に置いてきてしまったし、Virtual Guitarist 2 のディスクは... どこやっちゃったっけかな、外箱持ってなくてディスクだけなので、あまり目立たないんですよね。

以上。

Akka を触ってみる 2 - Akka Actor 編 その2

前回は こちら


今回は、子アクターの生成について軽く見ていこう。要件は、こう:

  • 親となる ParentActor、子となる ChildActor を用意する。
  • ParentActor は、生成と同時に ChildActor を子アクターとして生成し、そこへ Request を送信する。Response を受信したら、自らを停止する。
  • ChildActor は、Request を受信したらその中にある文字列を標準出力し、送信元に Response を送信する。

コードはこちら:

Request.scala
import akka.actor.typed.ActorRef

case class Request(message: String, reptyTo: ActorRef[Response])
Response.scala
case class Response()
ParentActor.scala
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors

object ParentActor {
  def apply(): Behavior[Response] =
    Behaviors.setup { context =>
      val child = context.spawn(ChildActor(), "print-worker")
      child ! Request("Hello, World!", context.self)

      Behaviors.receiveMessage { _ =>
        println("received response.")

        Behaviors.stopped
      }
    }
}
ChildActor.scala
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors

object ChildActor {
  def apply(): Behavior[Request] =
    Behaviors.receiveMessage { request =>
      println(request.message)
      request.replyTo ! Response()

      Behaviors.same
    }
}
Main.scala
import akka.actor.typed.ActorSystem

object Main extends App {
  val system = ActorSystem(ParentActor(), "parent-actor")
}


ちょっと前回よりも長くなっているが、最も注意を向けるべきは ParentActor だ:

ParentActor.scala
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors

object ParentActor {
  def apply(): Behavior[Response] =
    Behaviors.setup { context =>
      val child = context.spawn(ChildActor(), "print-worker")
      child ! Request("Hello, World!", context.self)

      Behaviors.receiveMessage { _ =>
        println("Response received.")

        Behaviors.stopped
      }
    }
}

前回は Behaviors.receiveMessage(...) しかなかったのが、それをさらに Behaviors.setup(...) で包んでいる。
Behaviors.setup(...) は、アクターを生成してからメッセージを受け取るまでの間にやっておきたい 前処理 を書いておけるメソッドである。ここで指定した処理は、(基本的に) アクター生成時の一度だけ実行される。

...わざわざ “基本的に” と強調して書いたのは、ここに状態遷移が組み合わさってくると少し事情が異なってくるからだ。といっても、よく考えれば当たり前のことではあるし、対処も非常に簡単ではあるのだが... これは次回説明する。

Behaviors.setup(context => ???)Behaviors.receiveMessage(message => ???) をまとめてしまいたいときは、Behaviors.receive((context, message) => ???) なんてメソッドも用意されている。これが必要になるような場面はあまり思い浮かばないが。

Behaviors.setup(...) の中では、そのインスタンス固有の操作をすることができる ActorContext が使えるようになるので、いろいろうれしい。 まず、ActorContext.spawn(...) で子アクターを生成できる。このメソッドは子アクターを生成したあと ActorRef (アクターインスタンスへの参照) を返すので、変数に入れておくと便利。
名前を指定するのが面倒なら、ActorContext.spawnAnonymous(...) を使えばランダムな名前を割り当ててくれる。
なお、Classic Actor では ActorRef.actorOf(...) で子アクターを生成できていたが、Typed Actor では廃止されている。

ほかにも、ActorContext.self で自分の ActorRef を取得したり、ActorContext.system で自分が所属する ActorSystem の ActorRef を取得したり、子アクターを取得したり停止させたり... いわゆる “ask” メソッドも用意されている (などと格好つけているが、正直 Ask パターンのことはなにも知らない。また後日調べて書く)。

そしてメッセージを受信したら、(前回のように Behaviors.same ではなく) Behaviors.stopped を返すようにしている。これは名のごとく、このアクターを停止させることを表している。このとき、子アクターである print-worker も一緒に停止する。


また、Request.scala の中身を見てみるとわかるが:

Request.scala
import akka.actor.typed.ActorRef

case class Request(message: String, replyTo: ActorRef[Response])

返信先の ActorRef を添付するようにしている。Classic Actor ではこんなことをせずとも sender というオブジェクトが暗黙的に定義されていたが、Typed Actor ではこのように明示的に作ってやる必要がある。
なぜ sender ではなく replyTo という名称にしてあるのかと言えば、まぁ Akka Actor のドキュメントがそうしていたからというのもあるが、もし返信先を送信元と別のところに変えたいケースが出てきたときに sender という名称では不自然だからという理由がある。


今回はここまで。ちょっと詰めが甘いかもですね。まぁいいか。

Akka を触ってみる 1 - Akka Actor 編 その1

N 予備校である程度は触ってみたものの、そのしくみをきちんと理解できたとは言いがたい状況なので、そのおさらいもかねて。


Akka?

リアクティブシステムJava / Scala で構築するためのライブラリ・ツール群。Scala の開発を主導している Lightbend 社が開発している。

リアクティブシステムの概念については、Lightbend 社 CEO の Jonas Bonér 氏を中心とするコミュニティによって発表された リアクティブ宣言 (Reactive Manifesto) を参照。
いくつかの名だたる大企業がリアクティブシステムの採用を発表したり、Linux Foundation が Reactive Foundation を立ち上げたり... 近年いろいろと注目されつつある要出典

今回はこの Akka のうち、Akka Actor という アクターモデル を実装するためのライブラリを触ってみる。

アクターモデル

f:id:trackiss:20210612194342p:plain

このへんは詳しくは各自ググってほしい。

アクターモデルは、メッセージ によって情報をやりとりする アクター というものを中心にロジックを組み上げていくパターン。
アクターはそれぞれメッセージキューを持っており、そこにメッセージが格納されていれば、それを順に取り出して淡々と処理を進めていくだけ。アクターそのものは逐次処理しかできないが、それを複数同時に走らせることで分散処理を実現する。

基本的にアクターはアクターによって生成され、ツリー状に配置される。すなわち、最上位に位置するアクター (ActorSystem) を除くすべてのアクターは親アクターを持つ。
Akka では、親アクターが子アクターを監督 (supervise) する役割を持っている。 子アクターになんらかの障害が発生したとき、親アクターはその対処をおこなう。
障害が発生した子アクターのみを再起動するのか、あるいは自身のすべての子アクターを再起動するのか、はたまた無視して再トライさせるのか... さらに親のアクターに判断を仰ぐことも可能だ。

アクターモデルのなにがうれしいのか。

まず並行処理ができる。
基本的には、従来であればクラスに分けていたものをアクターに置き換えることになるわけだが... もし従来の方式であれば、複数のスレッドから呼び出したいときにそのメソッドがスレッドセーフであるか否かが重要になってくる。スレッドセーフでないのなら、Java でいう synchronized のような排他制御のしくみが必要となる (もっとも、それでもデッドロックを引き起こす可能性はある)。
アクターでは、同期的なメソッド呼び出しではなく非同期的なメッセージパッシングがトリガーとなるうえ、個々のアクターは逐次処理をおこなうので排他制御が必要なくなる。

次に、スケーラビリティにすぐれている。
もしボトルネックとなる部分があるのなら、その部分のアクターをかんたんに増やすことができる。スレッド等でも似たようなことは実現できるが、アクターなら前述の厄介ごとがクリアできるし、より高度に抽象化されていて理解もたやすい。いわばソフトウェアのマイクロサービス化... のようなものだろうか。

そして、耐障害性にもすぐれている。
アクターモデルにしたがって適切に設計されたシステムは、なにか障害が発生したとしても、多くの場合 人為的な手を加えずとも自然に復帰する。

余談。アクターモデルは、Erlang という言語で取り入れられたことで一躍有名になったパターンである。
もともとエリクソン社 (現在では日本国内のモバイル通信網基地局のベンダーとしてトップシェアを誇っている) が開発した言語で、同社の AXD 301 というスイッチに採用され 99.9999999% もの信頼性を実現したことで知られる (もっとも、この数字は統計的なものでありかならずしも信頼できるものではないが、それでも驚くべき数字だ)。

Typed Actor?

従来の Akka Actor ではメッセージの型を宣言することができず、動的に型を振り分ける必要があった。

Akka 2.6.0 から、型安全な Akka Actor の API が正式に追加された。これは一般に Typed Actor と呼ばれる (2.5.x の段階ではまだ実験的機能であり、Akka Typed と呼ばれていた)。
対照的に、従来の APIClassic Actor と呼ばれる。

無論、この記事では Typed Actor を触ってみる。

セットアップ

とりあえず手を動かしてみよう。
build.sbt を適当に書く (よいこはきちんとかきましょうね):

name := "typed-actor-test"
version := "0.1"

scalaVersion := "2.13.6"

lazy val akkaV = "2.6.14"
lazy val logbackV = "1.2.3"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor-typed" % akkaV,
  "ch.qos.logback" % "logback-classic" % logbackV)

Akka はログの出力に slf4j を使っているので、とりあえず logback-classic を入れておく。

Hello, World!

今回のコードは、Message を受け取ってその中身を標準出力するだけの非常にシンプルなアクターを書いてみる。

百聞は一見にしかず。まずはコードから:

Message.scala
case class Message(value: String)
PrintActor.scala
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors

object PrintActor {
  def apply(): Behavior[Message] =
    Behaviors.receiveMessage { message =>
      println(message.value)

      Behaviors.same
    }
}
Main.scala
import akka.actor.typed.ActorSystem

object Main extends App {
  val system = ActorSystem(PrintActor(), "print-actor")

  system ! Message("Hello, World!")
}

アクターの終了処理などはいったん抜きにしておく。

Typed Actor では、従来の object-oriented style に加えて、functional style というアクターの宣言方法が導入されている。
前者では一般的なクラス指向のスタイルを重んじているのに対して、後者ではふるまいによってのみアクターを宣言するという より関数型プログラミングに近いスタイルに重きを置いている。

object-oriented style では、Actor トレイトを継承したクラスを使い、メソッドによってふるまいを、プロパティによって状態をそれぞれ表現していた。
functional style では、Behavior[T] 型の関数 (メソッドでもいいし、関数でもいい) によってふるまいを、その引数によって状態を表現する。

アクター内という局所的なものであるとはいえ、あまりミュータブルなものは扱いたくないので、今回は functional style を触ってみることにした。

先ほどの例をもう一度見てみよう:

PrintActor.scala
import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors

object PrintActor {
  def apply(): Behavior[Message] =
    Behaviors.receiveMessage { message =>
      println(message.value)

      Behaviors.same
    }
}

Behavior[Message] 型を返す PrintActor.apply() を定義している。最もシンプルかつわかりやすい例として apply メソッドを使っているだけで、Behavior[T] さえ返すのであればでなんでもいい。もちろん、PrintActor オブジェクトの中にある必要すらない。
今さら書くほどのことでもないが、この T こそがアクターが受け取るメッセージの型である。

さて、例にある PrintActor.apply() の中身を見てみると、実質的に Behaviors.receiveMessage(...) という関数に完全に乗っ取られている状況であることがわかる。この関数を使って、メッセージを受け取ったときのふるまいを指定することができる。
より複雑な使い方をする際にはもっと別の関数を使う必要があるが、今回の用途ではこれで十分。

Behaviors.receiveMessage(...) に渡しているラムダ式は、最終的に Behaviors.same という謎の値を返している。これは、このアクターの状態は一切変更されなかったよ というサインである。

なお、この Behaviors.same は、PrintActor() (もとい PrintActor.apply()) に置き換えることでも同じ動作を実現できる。むしろこのほうがよりわかりやすくなるのだが、要するに関数の再帰呼び出しを使ってアクターの状態遷移を表現しているのである。勘の良い人はここでなにか違和感を覚えるかもしれないが、そのへんはマジック (トランポリンとか) でうまく調整されている。詳しくはおいおい説明予定。
ただ、余計な初期化処理等をスキップしてくれるので、特別な理由がないかぎりはおとなしく Behaviors.same を使おう。


今回はここまで。

紙ブログ

しばらくブログ放置してたので、なんか適当に書いた。

もともとは「ここ1年で学んだこと」みたいな趣旨で書き始めたはずなんですけど、言いたいことを言う記事になりました。久米田先生の紙ブログみたい。そうでもないかな。

まぁたまにはそういうのも良いかなと。


TOC


Scala すき...

Scala を触りはじめたのはちょうど1年前くらい。

なんで Scala なのかというと、単純明快、周りに書いてる人がいなかったからですね。

マイナー言語... 逆にメジャー言語ってなんなんですかね。
C、C++C#JavaJavaScriptPythonRuby あたりはメジャーといえるでしょうが、その線引きはひどく曖昧です。まぁ、しかし Scala がメジャーということはないと思うので、とりあえずマイナー言語ということで。

高専にいたころは、これとまったく同じ理由で Haxe というもっとマイナーな言語を触っていました。といっても、それは当時の観測範囲がせまかったのが問題で、Scala 詳しい界隈の人たちは普通に Haxe を知っていて、書けたりするんですよね。すごいや。
えー、まぁそれと少し方向性の似ている言語ということで Scala をチョイスしたんです。

いや、いい言語ですよ Scala は。だいいち書いていて楽しい。これ大事です。

関数型プログラミング

先の話のつづきになりますが、やはり関数型プログラミングの考え方はいいものです。

Haskell の美しさはようやく理解できるようになってきましたが、やはり実用的かと言われると素直に首を縦にふるわけにはいかないもので、その点に関して Scala はよく考えられていると思います。

Haxe を触っていたころから、強力な型推論や if / switch 式、パターンマッチなど、なぜこの機能がほかの言語にないんだ? と思うような数々の機能に魅力を感じていました。

最近はいろいろな言語に関数型プログラミング由来の要素が取りこまれつつありますが、やはり知らなければみずから使おうとは思わない (というか気づけない) ので、一度自分から大海に飛びこむ勇気が必要ですね。

Scala では、さらに Option や Either、map に flatten といったモナド周りであったり、カリー化や部分適用、高カインド型、そしてそれまでボンヤリとしていた型システム全般に関する理解を改めました。

デザイン パターンとアーキテクチャ

Chatwork のインターンではじめて設計手法云々を勉強しました。それまでは完全に個人で開発してたので、そういった類のものはあまり触れてこなかったんです。

もっとも、DDD はそこまで違和感なく受け入れられることができました。
私はもともとゲーム作りからプログラミングに入門しているので、オブジェクト指向的な DDD は、なんかこう、わりとスッと頭に入ってきました。

逆に、トランザクション スクリプトの話が出てきたときなんかは「そんな気持ち悪いデザイン パターンなんてあるのか...」と、むしろ違和感しかなかったです。

Clean Architecture は、いまだにベストプラクティスがわかりません。一応自分で書いてみたりはしましたが、やはり要件によって形は変わってくるものです。

先人の実装例を見てみても千差万別、Layered Architecture 派生の中では Clean Architecture は詳細がしっかり定められているほうだとは思うのですが、やはり必要なエッセンスをどれだけ抽象的に捉えられるかが大事なようです。

なので、あまり規模の大きなアプリケーションでないのなら、より抽象的な Leyered Architecture からスケールしていくのが良い気がしています。

CQRS は、データソースまで分けなければ、わりと気軽にプロジェクトに取り入れられそう。というか、取り入れるべきでしょう。Event Soucing しないからやめておこう、なんてことは言わずに、可能なら採用すべきだと思っています。

Event Soucing は、個人レベルのプロジェクトだとあまり触る機会がないのがつらいですね。Akka の勉強もかねて、一度組んでみようかしら...

Japanese traditional xxxxx

卒研やってます。専門学校とはいえ、そのへんは一応きちんとあるんです。
何人かでグループになり、各々すきなテーマに沿ってなにか作ります。

で、うちの学科はですね、10人もいない極小学科なので、全体で卒研することになったのですが。

なんと、「卒研として某企業のシステム開発をしないか」という先生からの提案が!


いや提案っていうか、半ば強制なんですけどね。事後報告。

まぁ滅多にない経験であるのは間違いないし、とりあえず要件を決めて作業にとりかk...


_人人人人人人人人_
> 突然のコロナ <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^ ̄


でました。

あちらさんの社員の方が出社できないので、当然なにも進みません。
先生は今のうちにできることをやっておいてなどとおっしゃってますが、いやいや、なにもできないですから。

とはいうものの、時間を無駄にするわけにもいかないので、とりあえず TypeScript + PWA でやってみるかー という話に。
私も TypeScript と NestJS の勉強してたんですよ、ここ最近は。

で、TypeScript の話はなくなりました (は?)。
社外秘なので、企業内の端末からしかアクセスできないようでなくてはダメだと。

いや、うん。それはまったくもってそのとおりなんですが、少し前に、この方向性でやるよっていうプレゼンやったじゃないですか。そのときに言えよ。

早いところ MTG の機会を設けてほしいものです。別にオンラインでだってできるでしょうに。
ですが、そもそもこのプロジェクトの調印式が終わってないんだそうです。これが噂に聞く調印ってやつか...! ジャパニーズ・トラディショナルは実在した!

結局、フロントエンドは C#、バックエンドは未定。

ま、個人的にはもちろん Scala で書きたいわけなんですが...
書き慣れているのだけでなく、私がこうして内定を頂けたのは完全に Scala のおかげですから、そういう意味でも思い入れがある言語だというだけで。かならずしもベストな言語とは言いきれないわけです。そんな銀の弾丸みたいな言語はないんですが。

Event Sourcing とかやるなら Akka が使える Scala がよさそうですけどね、今回はそこまでやらない予定ですしおすし。

Scala それ自体は実にすばらしい言語だし、もちろん必要であれば Scala を教えることもできますが、それでも、ほとんどの人にとっては書き慣れない言語であることには違いないわけで。
クリーンでスケーラブルな設計と習得難度はトレードオフの関係にあるのです。私自身も、まだ Scala をフルに使いこなせていないと自覚しています。

万が一、結果的に私がほとんど書いてしまうようなことになってしまっては元も子もありません。
ただでさえ今の設計段階でもかなりオレオレなデザインになってしまっていて、少し申し訳ないと思っているぐらいです。軽量 DDD + オリジナルの Layered Architecture + 軽量 CQRS、みたいな。

でも来年以降もこのプロジェクト引き継ぐらしいので、多少複雑になってでも合理的なアーキテクチャを導入したほうが、のちのち破綻するようなことにはなりにくいかなと。 一応そういう考えはあるのです。

そんなこんなで、どうしようかねー ってなってるとこです。

技術選定難しい

結局、プログラミング言語の違いなんて些細なもので、DB だとかコントローラーだとか、そういった外部的な部分を要件に合わせてまず選ばなければいけない。もしくは、使用するフレームワークアーキテクチャが、要件にマッチしているかどうか、とかですかね。

もっとも、今どきのたいていの言語にはどんな DB のドライバーでも用意されているでしょうし、結局のところはチームの合意が取れればいいわけです。
強いていうなら ORM。ORM はモノによって使いやすいか使いやすくないかの差がとても大きいので、慎重に吟味する必要があります。

というか、今回のケースだとそもそも要件が不確定なので技術選定もなにもないんですけど。

Kotlin、お前 Scala でいいだろ

先の件にともなって、少し Kotlin を触ってみました。

ビックリするくらいそっくりですね。なので、これもう Scala で書けばいいやん... ってなる。精神的につらみが深いです。
Scala ユーザー的には、後発のくせにどんどんと市民権を得てきている Kotlin の存在を危惧しているわけなのですが (私だけじゃないよね?)、やはり言語としては Scala のほうがはるかに多機能です。

そもそも Kotlin の設計思想のひとつに「Scala よりも学習しやすい言語」というのがあるそうで、Android 開発なら Kotlin、バックエンドなら Scala というようにまずまず住み分けられているのかな、と思いきや、最近はサーバーサイド Kotlin が増えてきているんですよね。

JVM 以外の実装にしても、Scala.js と Kotlin/JS、Scala Native と Kotlin/Native... 完全に食いにきてますね。

Kotlin、Either がないのがしんどいですね。もし使うときがきたら、DB 周りのエラーの扱いとかに便利なので、絶対に Either を導入するライブラリを使うと思います。
Scala でいう Try.apply() がわりに使える Result なんてのがありますが、型としては使えないもよう。ゴミ

結局は、学習コストとのトレードオフScala のほうがややコスト高めなのは間違いないと思います。
もっとも、Kotlin -> Scala だともちろん追加で勉強は要りますけれど、Java -> Kotlin と Java -> Scala だったら、なんかそこまで差はないのではないかと。

Rust 難しいね

若者もすなる Rust といふものに、私も手を出してみました。

言語仕様をざっと見た感じ、いろんな言語のいいとこどりって感じですね。ただ、API Docs を眺めていると、これ欲しい! っていうのが experimental だったりして、少し物足りない感もありました。

標準でイミュータブルなのはとてもいいですね。
エラーが Result<T, E> なのもいい。Go も少し書いてみて、やはりこの言語は私には合わないとはっきり感じ取りましたが、ことエラー処理に関しては実に合理的にできていると思います。

Java は例外とエラーを区別しなかった、より厳密には、例外処理と大域脱出を融合させてしまった、というアレ。

あと検査例外。それ自体は、閉鎖/開放原則に違反しているとはいえ、堅牢性とのトレードオフということでなら全然許されてもいいのではないかと思います。
Rust の Result<T, E> だって、実質的な検査例外です。Go はエラーチェックを強制しないことで閉鎖/開放原則に違反しない道を選びましたが、それでも、Java における非検査例外とは違って、基本的にはチェックすべきものです。
Java の場合、やはり検査例外と大域脱出とを組み合わせてしまったのはよくないですよね。エフェクトが大きくなりすぎます。

いや、でも難しいですね。Rust。
まだ見よう見まねで書いてただけなので、IDE で書いたらもう少し感想が変わるかとは思いますが、うん、難しい。Scala よりだいぶ難しい気がします。

ドキュメントを読みあさることにします。

YouTube を観るようになった

遅くね?
はい、遅いですね。

流行りものが嫌いなめんどくさい性格なので、どうしてもニコニコから離れられないでいたのです。結果、Vtuber の波からも遅れてしまいましたが。

かといって、ニコニコを観ているかといえばそうでもない。
最近はめっきり観てないです。気に入っている数人の投稿者の動画を追っているくらい。

で、ちょっとひさびさにニコニコでゲーム実況を観てたんですよ。懐かしいな、こんな実況者いたなー、とか思いながら。

でも、もうニコニコで新作はアップロードされないんです。
みんな YouTube 行っちゃったもんね。

ということで、ようやく YouTube を観るようになりました。でも、まだニコニコ出身の実況者の動画しか観てないですね。キヨさん、ガッチマンさんの2人。

最近はホラー実況をよく観てます。普通のゲームなら、実況観るよりも自分でプレイしたいって思いますもん。
ホラーだと自分でプレイできないので、申し訳ないですが動画で終わらせることにしてます。

ゲームやりたい

もしかしたら自分はゲームがあまり好きじゃないのかも、と思うことはあります。
すごく飽きっぽいので、ひとつのゲームをプレイし続けられません。

もっと言うなら、オンラインの対人ゲームが苦手です。見ず知らずのオンラインの相手と接するのが怖くてしょうがない。

よく Twitter とかで、ネットで知り合った人と通話してる人を見かけるんですよ。ほんとすごいなと思います。

せっかくグラボはそこそこ良いの持ってる (Radeon RX Vega 64) のに、あまり活かしきれてないんですよね。2D ゲームが好きなので。
下手なインディーズ ゲームよりも、RPG ツクール製のゲームのほうがおもしろいって何度でも言います。

ツクール製のフリーゲームはだいたいやり尽くしてしまって、今後もあまりおもしろそうなものに出会える可能性は限りなく低いでしょう。ホラーゲームが多いのも、個人的にはあまり歓迎したくない傾向...

そういうのを求めているのなら、🔞のツクール製ゲーム、すごくいいですよ。かなり長時間遊べるものが多いです。特に RPG 系だと寄り道クエストがたくさん用意してあったり、めちゃくちゃマップが広かったり、無駄にやりこみ要素が充実してたりして、100時間とか遊べるものもザラにあります。
むしろアレなイベントやシーンとかは飛ばしちゃうことが多いですね、長いし、そこにあまり興味を持ってるわけではないんです。

まぁそんなことは置いておいて、TL を見てるとですね、つよつよな方たちは普通にゲームやってたりするんですよ。でも強い。
いっぽう私は、コードを触っていたり読んでいる時間はまぁまぁ長いのですが、強くはない。

だからなんだって話なんですが。要領の良さを見習いたいものです。


いつもどおり収集つかなくなってきたのでここらでいったんストップ。

でもなにも気にせず書けるので、書きたいことが出てきたらこういうの書くかもしれません。

bye