2023年年末有給消化3日目 流れついて三県境

2日目

3日目からは日帰りか1泊程度でどこかに行こうと考えていたのだが、考えるほどに特に行きたい場所が思いつかず、自分はなんて内向きでつまらない人間なんだろうと落ち込んでいた。

流れついて三県境

古河駅前

特に計画は立てられなかったが、なんとかなれーと思いながら電車で北へ。適当に乗り換えながら進んでいった結果、古河駅で一旦電車が途切れた。古河は茨城の西端の市だ。地図を見るとどうやら昨日一瞬調べた三県境が近いようなので、行ってみることにした。

古河駅から西へひたすら歩く。途中までは商店街で(謎にうなぎ屋が多い)、だんだん住宅や駐車場の割合が増えてくる。

三国橋

渡良瀬川を渡る三国橋が、素晴らしい絶景だった。巨大な渡良瀬川と整備されたゴルフ場、その手前の草地を橋の上から見渡すスケール感は普段の生活風景とは別世界で、写真では伝わらないが空も雄大で非常に気持ちが良かった。自然の豊かさや景観なんて全く意識しない適当な旅だったにもかかわらずこんな体験ができるとは思ってなかった。

渡良瀬川土手

橋を渡ったあとはしばらく土手を進むのだが、ここで運良く夕焼けを眺めることができた。これもまた格別に素晴らしい。空を遮る高層ビルがない広い平野に夕焼けが差し込み、空のグラデーションを背景に重層的な雲が複雑に彩られる。こんなに美しい空を見たのは何年ぶりだろう。

墓の頭頂部が反射光で輝く珍写真も撮ることができた(これいる?)

僕の祖父と高祖父は船乗りだったが、僕はこういう広大な平野に心惹かれる。遠くまで見渡せて、せいぜい2階建ての一軒家、農地、墓、線路、空に突き出すのは高圧電線だけで、遠くには山の稜線。美しいなあ。

三県境

三県境は農地の間にありちょっとした広場になっている。右側の箱にはスタンプと旅行者ノートが入っている。まあ、ただ県境という概念があるだけで特にすることはない。それがすごく良いなと思った。

旅の目的を事前にしっかりと決め込んでしまうと、それをクリアするチェックポイント通過型の意識になってしまいがちだ。だとすれば、発想を逆転させて、本当にチェックポイントとしての意味合いしかない場所を目的地にするのはいいアイデアかもしれない。そうすれば「どうせ着いたところで特に何もない」と思いながら歩くので、歩いている過程に集中して楽しめるようになる気がする。

この直後に日が暮れて真っ暗になってしまった。ここから最寄りの柳生駅までは農地の中の道で街灯が少なく、結構怖かった。

帰宅

柳生駅から東武日光線で栗橋駅へ。後はJRでどこへなりとも。実はここで再び北上して宇都宮で飛び込みの宿を取って翌日更に北上という攻めたプランもあったのだが、何も想定してなかったせいでスマホの電池が既にギリギリだったこと、南下する電車が先に来てしまったことなどからおとなしく帰宅した。足も痛かったしね。

古河は茨城で、三県境は群馬・栃木・埼玉なので今日一日で4県を制覇したことになる。1日目の上野を合わせれば5県だ。となると残りの休日でやるべきことは、千葉と神奈川を踏破して関東コンプリート…?

やるかどうかは未定です。

2023年年末有給消化1日目 上野動物園/Smart Stay SHIZUKU/送別会

特にそうしようと意図しているわけではないのだが、なんとなくで有給を余らせて、消滅寸前の3月になってまとめて使うというのがここ数年の恒例になっている。

上野動物園

大学時代上野は行動範囲だったにもかかわらず上野動物園に行ったことがなかったので、上野に詳しい友人を召喚して一緒に行った。生憎の雨だったが動物を見るという点ではそんなに関係なかったかな。寒かったし動物を見るために回避不可能な水たまりがあったりしたのは辛かった。

上野動物園と言えばパンダ。思い返すと本物を見たのは人生で初めてかもしれない。父親と母子は別で飼育されており、母子は60分待ちなのに父はフリーパスで謎の格差がかわいそうだったが、とりあえず父親の方だけ見た。岩にもたれかかって後傾姿勢ひたすら笹をちぎって食べていた。ただのおっさんじゃん。屋外の展示スペースの柵はそこまで高くなく、ちょっと本気でジャンプすれば脱出できそうな高さに見えた。パンダ語を話せない人間に囲まれて閉じ込められているのにパンダは脱出したくならないんだろうか。僕は人間語を話せない謎の生物に閉じ込められたら脱出を試みると思うけど…

ワニも見応えがあった。とにかく大きい。水槽に入っているので檻に入っている動物よりも近くでよく見えるという補正もありそうだが、この巨体で歯も顎も強力なんだから怖いなと思った。

爬虫類・両生類に比べると哺乳類はよく動く。使えるエネルギー量が違うのだろう。アルマジロがずっと走り回っていたのは面白かった(病的なのかもしれないが)。

トラは見れなかったのだが、トラの保護にまつわる展示物は面白かった。トラもその他の草食動物も現地の住民も企業も(密猟者等を除けば)悪いことをしているわけではないが、結果的には経済成長を追い求める人間による環境の変更によってトラが割を食っている、そうして作られた油は間接的に日本人も利用しているということが説明されていた。展示物には無邪気な子供のアイデアとして「現地民は豊かな生活を追い求めるのをやめて自然と共生せよ」などという強火な主張も述べられていたが、これは当然「そうはいかないでしょw」という反応まで予期して載せられたものだろう。お題目で腹は膨れない。

14時頃に入園して16時30分には閉園、それより早く展示終了する動物も多かったので回りきれてはいない。まあそのくらいが丁度いいだろう。子供の頃は動物園はシンプルに見て楽しい場所だったが、動物に関する研究・啓発活動、動物と人間の双方の安全のためのいろいろな工夫など、すごく考えられた施設なんだなあと感じた。

Smart Stay SHIZUKU

友人と別れてSmart Stay SHIZUKU 上野駅前店で一休みした。僕はサウナーではないのだがサウナーの友人がよく行っているらしい。風呂で体を温めて、新聞紙で濡れた靴下を乾燥させながらのんびり漫画を読んだ。映画だけ見たにわかなので『SLAM DUNK』は1巻と最終巻を、その後アニメ放送中の『もののがたり』1巻を読んでやっぱりこれ面白くないよなと確認。

送別会

就職で関東を離れる後輩の送別会が上野であり、そのまま参加。仲間うちでよく使う中華料理屋で、途中から人数が増えても柔軟に対応してもらえるのでありがたい。この日も5人スタートで結局9人になった。上野は大学時代の友人が集まりやすい土地であり、これが僕があまり遠くには引っ越したくない理由の一つだ。

一次会が終わったあと、僕は大抵あっさり帰宅するのだが、この日は公園立ち飲みの二次会にも参加した。許容量を超えた2本目のビールを飲んで激しく振動していた。

最寄り駅まで帰ってきたらストリートミュージシャンが歌っていたので聞いてきた。僕はストリートミュージシャンが好きだ。歌唱力や作曲センスはメジャー歌手には及ばないことが多いが、そこで歌っているというのが大事なことだ。街には音楽があったほうがいい。結構長く居座って聞いたのでお金を払った。

帰宅したらお腹が苦しくなった。最近よくあることだが、飲酒で酔っ払って吐くとかではなく胃に来るのだ。胃液が逆流するような気持ち悪さがしばらく続く。こうなると水を飲むのも苦しいのでおとなしく寝ているのだが、そのまま翌朝になってしまうと脱水で普通の二日酔いになる。幸い復活して少しずつ水を飲んでから寝ることができた。

Xiaomi Smart Band 7で水泳?/川口まちこうば芸術祭2023/GoでMySQLで文字列検索/dockerコンテナ内からホストにアクセスできない

Xiaomi Smart Band 7で水泳?

僕はXiaomi Smart Band 7を使っている。健康診断で心拍が多いと指摘を受けたときに病院でスマートウォッチを勧められて買った(なんでもなかった)。スマートウォッチ界の低予算部門のスターのような製品だ。心拍は一応そこそこ正しい値が取れる。歩数は実際の19%増しくらいの値になる(数えた)。

先日初めて水泳の測定に使ってみた。Workout > Swimmingで水泳モードに入れる。水泳モードでは水で画面が傷まないように(?)画面表示がデフォルトでオフになる。画面を操作するためには画面を↑↓と繰り返し撫でる必要があるが、水がノイズになってなかなか入力に成功しない。泳ぐプールの長さを入力することができ、休憩やターンを自動で検知して今何往復したのかを記録してくれる。泳いでいるとカウントがわからなくなるのでこれは助かる。そこそこ正確だ。ストローク数も取れる。

水泳モード中は心拍数の計測が止まる。水中では光学式心拍測定の信頼性が低いから取っても意味ないってことなのかな。水泳モードにしなければ心拍数は取れるらしい。

川口まちこうば芸術祭2023

こんなイベント。
https://www.kawaguchicci.or.jp/kawaguchifaf/

やってたので見てきた。金属加工を使った家具やおもちゃ、芸術品などが展示されていた。特に新光ステンレス研磨による時計は特殊研磨によって美しく妖しく光り輝いていて欲しくなっちゃったが(買える)、さすがに高かったので諦めた。

GoでMySQLで文字列検索

愚直に

db.Query("SELECT * FROM status WHERE text LIKE '%?%' ", includedText)

みたいに書いたんだけど?がplaceholderとして扱われずincludedTextが入らなかった。なんか調べてみたら
https://graff-it-i.com/2021/06/24/golang-mysql-like/
こういう話があって

db.Query("SELECT * FROM status WHERE text LIKE CONCAT('%', ?, '%') ", includedText)

CONCATでやるらしい。へぇ〜。

dockerコンテナ内からホストにアクセスできない

今作ってるアプリケーションのコンテナから、同じサーバーに乗っているmstdn.chao.tokyoにアクセスしようとしたらconnection refusedになってしばらく頭をひねっていた。コンテナ内でdig mstdn.chao.tokyoすると127.0.0.1に解決されていた。本来ならグローバルIPが引けるはずなのに、これはおかしい。

ホストの/etc/hostsに127.0.0.1 mstdn.chao.tokyoが書いてあるせいだった(たぶん以前動作確認のために書いた)。理屈はよくわからないがコンテナ内からの名前解決でもホストの/etc/hostsが読まれてしまうことがあるようで、コンテナ内から127.0.0.1に解決されるので、コンテナ自分自身にアクセスが戻ってくる。コンテナ自身の443ポートは開いてないのでconnection refusedになったわけだ。

https://qiita.com/tksugimoto/items/804e0051bf1b1ddab168
この記事によるとホストの/etc/hostsはコンテナ内の名前解決に影響を与えないとのことだが、僕のサーバーはnginx-proxyを活用するために結構変なdocker networkが立っているのでその影響があるのかもしれない。

gotosocialのサーバーを別のマシンに移動した

サーバーコスト削減の流れで、全てをさくらのVPSに集約することができた。

gotosocialのサーバー移動はやや手間取ったが、終わってみれば別段難しいことではなかった。一応ドキュメントに記述があるが、大雑把だ。

https://docs.gotosocial.org/en/latest/admin/backup_and_restore/

やったこと

  • 新しいサーバーにdocker-compose.ymlを配置する
    • gotosocialのdocker imageのバージョンが変わらないように注意する。ここを間違えて0.6から0.7に上がってしまい手間取った。gotosocialのバージョンが上がるとDBのスキーマが変わることがあり、マイグレーションが上手く通らなくてDBを参照できずに落ちる。
gotosocial    | timestamp="04/03/2023 15:27:59.346" func=admin.(*processor).MediaPrune.func3 level=ERROR msg="MediaPrune: error pruning meta: SQL logic error: no such column: account.last_webfingered_at (1)"

https://github.com/superseriousbusiness/gotosocial/blob/main/internal/db/bundb/migrations/20230202212700_rename_account_webfingered_to_fetched.go この辺かな?

  • 古いサーバーのsqliteのデータをdumpする
$ cd data
$ sqlite3 sqlite.db
> .output ./dump.sql
> .dump
  • このdump.sqlを新しいサーバーに持っていく
    • scpなりrsyncなりご自由に
  • 新しいインスタンス用のsqliteデータベースを作りdumpファイルを読み込む
    sqlite3 newdb
    .read ./dump.sql
  • 画像等のファイル(dataディレクトリ内のsqliteではないフォルダ群)も新サーバーに持ってくる
  • docker-compose.ymlをよしなに変更する
    • sqliteデータベースの名前とか注意
  • docker-compose upしてDNSを新しいサーバーのIPに向け直す
    • DNSが効くまで時間がかかって面倒なときはローカルマシンの /etc/hosts に書き込んじゃうとすぐ動作確認できる

日記

急に本格派の焼売が食べたくなったので中国人がやってる中華料理屋で食べた。その後近所を少し散歩した。
コミュニティセンターのような施設があって初めて入ってみたら、大小いろいろな集まりの募集があって面白かった。しかし公的な施設というのはどこも節電で薄暗くて陰気で良くない。

帰宅してのんびりアニメを見たり、RimWorldを見たり、カレーを食べたり。今のロットのカレーはじゃがいもも人参も大きすぎて火の通りが悪いのが反省点だ。

エアコンのフィルタの掃除をした。猛烈にほこりが飛ぶかと思ったがそこまででもなく、粘着コロコロと流水だけでかなりきれいになった。掃除機がなくてもなんとかなるね。

新しいことへの挑戦とリファクタリングを同時にしてはならない 五木寛之『生きるヒント 自分の人生を愛するための12章』を読んでいる

新しいことへの挑戦とリファクタリングを同時にしてはならない

サーバーコスト節約と技術的チャレンジを同時にやろうとしてk8sがわからなくて遅れているけどとりあえずサーバーコストだけでも落としたほうが良い。一番の金食い虫のt2.microのインスタンスを早急に潰したい。

その後さくらの方に全部移してみて、それでスペック足りるようだったら一旦終わりにしよう。大半のアプリケーションは常時起動が前提だからElasticである必要がない(何にでもElasticを注ぐAWS)。

五木寛之『生きるヒント 自分の人生を愛するための12章』を読んでいる

ぼんやりと落ち込んでいた時期に友人に勧められた本。今4章。

筆者が人生経験と知識に基づいて、「こうあると人生が楽しいんじゃないか」という話を取り留めなく書き連ねている。職業柄厳密に事実を書いた本を読むことが多いけど、こういう「私の感想」全開の本というのも良い。時間も空間も超えて他人の言葉に触れられるという本の特質を鑑みれば、むしろこういう本こそ読書の楽しみなのだと思う(まあ金持ってるジジイだから余裕ぶっこいた物言いができるんだよね、と鼻白むようなところもないでもない)。

3章「悲む」ではまず明治時代に「悲しいではないか」を挨拶とした若者たちがいたことに触れ、人生には悲しみが満ちていることを認め、現代の娯楽が明るさを求めすぎていることを指摘し、私達はもっと率直に悲しんで良いはずだと主張する。

みんなが、〈暗い〉と言われることを恐れている。そして明るく軽快で楽しげであることを求めている。
これはひとつの病気ではないかと、ぼくには思えるのです。

これは僕もその通りだと思う。アニメを見ていてキャラクターの底なしの明るさと作品に満ちるエネルギーに圧倒されてしまうことが多い。思えば記憶に残るお気に入りの作品は静かで悲しいものが多い。

仕事をしていても、目標は高く輝かしく、失敗も問題点の分析と修正して次は頑張ろうというエネルギーに転化される。もちろん営利企業だからそのエネルギー、欲望でカツオのように泳ぎ続ける宿命にあるわけだが、一人の人間としてはついていくのが辛いときもある。

IYマイレジ ピピットスマホを会員限定にするな うたもくとgfnと酒を飲んだ

たまには日記を書く。

起きて、昼食に丸亀製麺のトマトカレーうどんチーズのせを食べた。

スポーツクラブに行って30分歩いたり走ったりした。本来日曜日は泳ぐのだが、今日は足腰の筋肉痛が持続していたので軽くした。マシントレーニングで同じ筋肉を週1回鍛えるとして、筋肉痛が1週間持続したらその間その筋肉の負荷は抑えるべきらしいので、有酸素運動を軽減せざるを得ない。なんというか、配分が難しい。人生を通してきちんと体を鍛えたことがなかったのでどうやればいいのかわからないことが多い。

IYマイレジ ピピットスマホを会員限定にするな

その後スーパーで納豆とヨーグルトを買って帰った。これまでスーパーではスマホをセルフレジ代わりにするサービスが使えたのだが、今日行ったら会員登録しないと使えなくなっていた。しかもその会員登録がスマホからしかできず、登録したらメール送りまくりますメール停止は面倒にしておきますと宣言するかのような文言があったので、腹が立って登録をやめた。

スマホに通知を飛ばせるという点でアプリをインストールさせるのが効果的なのは理解するが、会員登録には

  • メールアドレスの入力
  • パスワードマネージャによるパスワード生成

という作業が必要であり、これらを豆粒みたいなキーボードと1つのアプリしか同時に起動できない制約のあるスマホでやるのは面倒くさい。

そもそもスマホレジは有人レジを減らして人件費を抑えながらレジの待ち時間を減らせるwin-winの仕組みのはずなのに、どうしてそこに会員登録誘導というハードルを設けてしまうんだろう。

うたもくとgfnと酒を飲んだ

やっていきエナジーをかなり充填したのだが、2人はコードを書くことで世界に対してオンリーワンの貢献をしている一方で、僕は至って普通の職業ソフトウェアエンジニアで、ともすれば社内の事情や評価のことを考えがちだ。能力の高低以前に世界観のスケールが違う。

とは言っても彼らは会社のことなんか知らないで技術的探求に耽溺しているというわけでもない。むしろ技術的な最先端を突き進むことが会社の利益につながっていたり、逆に会社での制約を経験することで技術的な視野を広げたりしている。

レベルを上げて物理で殴れば全てが手に入るのだろうか。答えはわからない。具体例があるだけだ。ただ、こうして刺激をもらえる機会があるというのはありがたいことだ。

サーバーゼニ節約&kubernetes入門

ふと毎月のサブスク費用を確認したらAWSとさくらインターネットで月額5000円くらいかかっていて、いくらなんでも辛いのでこれを圧縮する。

原因は必要以上に多くのサーバーを稼働していること。現在稼働しているのは3つ。

さくらインターネット 2GB

  • 1738円/月
  • 2017年から借りており、中途半端な技術的挑戦の残骸が最も多い
  • 金額に対するスペックが良い

積載物

AWS EC2 t2.micro

  • 1544円/月

積載物

AWS EC2 t4g.micro

  • 1076円/月
  • AWS謹製のGravitonプロセッサなので安くて高性能。ただしArm。

積載物

  • gotosocialインスタンス

移行計画

どうしたものか…

とりあえずEC2は新世代ほど高コスパの原則があり、t2.microはt4g.microに移行すべき。自分の学習を考えるとさくらはやめてEC2に揃えたい。全部t4g.microに相乗りを狙ってみようか。

そしてどうせならkubernetesに全部載せてみたい。複数のアプリケーションを相乗りさせるときのトラフィック管理をこれまではjwilder/nginx-proxyでやっていたが、もうちょっとナウいやつに移行して監視とかも統一的にやりたい。

ActivityPub用のtwilogみたいなやつを作っている(notestockがあるのは知ってるよ!)

gotosocialからnotestockが使えなくて、少し調べてもわからなかった上にnotestockがソースコードを公開しておらず(してないよね?)調査を進めるのが困難そうだったので、自分で作ってみることにした。もとより自分のデータを自分で管理することは重要だと思っていたので、そういう意味もある。

https://github.com/chao7150/activitypublog

使用技術はGo+Echo+MySQL8.0。まあ正直手慣れたRemix+Prismaでやったほうが早いとは思うんだけど、たまには違うことをやったほうがいい。自分でアプリケーションをGoで書くのはこれが初めて。普段一番書いているTypeScriptに比べると、補間、エコシステム、ドキュメント、ビルドの速さが優れている。型システムは劣っている。module/packageが難しく、挙動もベストプラクティスもよくわかっていない。この辺を読んで参考にしている

また、具体的なGoの書き方の作法はGoToSocialを真似ている。

Goで良いなと思ったのは、timeだ。たとえば

// Go
time.Now().Add(5 * time.Minute)

は間違いなく

// JavaScript
new Date(Date.now() + 5 * 1000 * 60)

よりエレガントだ。

フォーマット文字列も好きだ。大抵は%vでどうにかなるという逃げ道を残しつつ、各データ型の中でも様々な表現を可能にしている。

if err...の洪水については、エラーメッセージを真面目に考える契機になる。すなわち、エラーはerrを通して呼び出し元に順に伝播するわけだが、その過程の各関数の中で徐々に情報を付け加えることができる

if err != nil {
    return c.String(http.StatusInternalServerError, fmt.Sprintf("error GET /: %v", err))
}

具体的に何が失敗したのかはerrの中身をそのまま表示しつつ、この階層では GET / という場所でエラーが起きたという情報を付け加えている。