Posts for: #2023/06

雨の四万十川

0時に寝て1度トイレに起きて6時半に起きた。疲れていたせいか、わりとよく眠れた。

四万十川市へ

雨が降ったり止んだりの、途中豪雨にふられたりしながらの移動。お昼ご飯に天然のうなぎを食べに 四万十屋 さんへ行く。おそらく学生の頃の卒業旅行でここに来たことがある気がする。2階席からの風景をなんとなく覚えていた。

私は滅多にうなぎを食べない (数年に1回ぐらい?) ので養殖と天然ものの違いに疎いが、身の引き締まり具合が違うらしい。刺し身の鮮度や良し悪しだったら身の引き締まり具合で私もわかるので食べ慣れた人にはわかるんだなぁと聞いていた。

その後、四万十川の途中にある 佐田 (今成) 沈下橋 へ行く。

雨がぱらぱら降ったりもしながらの、沈下橋を歩いて往復してきた。雨空なので四万十川っぽいきれいさはないものの、川の広さや雰囲気は伝わってきた。

土佐清水市へ

それから 足摺海洋館 へ行って海の生きものをみてきた。もう個人で水族館へ行くことはないけれど、なにかの機会で水族館へ行くことは稀にあって、大人になってから水族館へ行くと子どもの頃にはわからなかった楽しさがある。めっちゃ楽しかった。20-30分程度でコースを見終えてしまう規模の水族館だったけど、爬虫類、カメ、甲殻類、サンゴ、貝、さまざまな魚がいていろいろみれた。水槽の形もいろいろ工夫があって見学者が飽きないよう設計されていたと思う。規模こそ大きくはないものの、質はとてもよかったように思う。

その後は高知市の昨日泊まった旅館へ戻ってきて晩ご飯を食べて、部屋でくつろいでお風呂入って、疲れて寝た。車での移動距離が往復で200kmを超えていたので乗せてもらって座っているだけでも疲れた。雨降りの中、運転された方はしんどかったんじゃないかと推測する。

うだつの町並みと祖谷のかずら橋

22時に寝て何度か起きて6時に起きて7時過ぎまで史記を読んでシャワーを浴びて8時には ADLIV さんをチェックアウトした。

うだつの街並み

すぐ近くに道の駅があり駐車できる。道の駅の駐車場から歩いて土手にのぼり脇町の潜水橋 を眺める。この土手からの景色がとても気に入った。

お盆にはこの川で 花火大会 があるらしい。おそらく宿泊施設はすでに予約でいっぱいだろうと話されていた。実家からなら1時間半ぐらいで行ける場所なのでちょっと遠出して見に来てもよいかもしれない。

その後にうだつの街並みの通りを歩いてきた。平日の朝の8時半頃だったので観光客はまったくいなくて地元の人に何人か挨拶をしたぐらい。数百メートルの通りなのですぐに歩ける。

この通りは歴史的建築を残してはいるが、一般の民家であるらしく、オーナーがいたり、普通に住んでいる人もいるらしいと、昨日なかがわさんから教えてもらった。城崎温泉のような自治体ぐるみで街づくりしているのとは少し趣は異なるようにみえた。

「うだつが上がらない」という言葉に表れる「うだつ」を初めてみた。2階の屋根からちょっと飛び出している防火壁を指す。うだつを上げるにはお金がかかることから出世や富の象徴としてみられたらしい。  前日になかがわさんに案内していただいた解説を思い出しながら写真を撮ってぶらぶらしてきた。

この通りのすぐそばに のどけや さんというコワーキングスペースもある。立ち寄ってもよかったんだけど、昨日なかがわさんと一緒に挨拶へ行ったらオーナーは出張でいなかったのと、朝8時半からとくに用事もないのに再訪するのもどうかな?と思って今日は見送った。また次回行くときがあれば宿泊してみたい。

アンドワーク

うだつの街並みのすぐ横に ミライズ という行政施設があり、その中に アンドワーク というコワーキングスペースがある。9時過ぎに軽く見に行こうと行ってみた。受け付けのスタッフの方と軽く雑談。ここでもいとうさんの名前は通じていた。スタッフの方が地元の人たちはあまり使わないといったことも話されていたので外部からきたデジタルノマドが活用する機会の方が多いのかもしれない。まだ新しい施設で設備面からコワーキングスペースとしてはとてもよい環境にみえた。9時20分から10時50分まで作業してみたが他の利用者は誰も来なかった。

祖谷のかずら橋

昨日からお手伝い先の会社さんが社員旅行で四国に来られている。私もその社員旅行に途中参加で帯同する予定になっていた。今日の目的地である高知へ移動する途中で 祖谷渓 に立ち寄るというからそこで私も合流することにした。

11時頃に脇町を出発して12時45分にかずら橋に着いた。合流はちょっと遅れそうとのことだったので大きなお土産屋さんのカウンター席を使って作業をしていた。この施設は冷房がきいてなくて暑かったこと以外は快適だった。暑かったんだけど。他の社員さんを待っている間に軽くコードレビューをしていた。

かずら橋渡ろうかどうか迷ってやめた。学生時代に1度来て渡ったことはある。いつからか高いところが怖くなって、下をみると足がすくむ。万が一の粗相があったら社員旅行に迷惑をかけるなとリスク管理的な視点から安全に振る舞う考えが出てきてみんなが渡っているのを見学することにした。おもしろいもので、人によって高さをものともしない人がいて、怖くてゆっくりしか渡れない人もいる。かずら橋は人間の多様性を観察する装置の1つにも受け取れた。

かずら橋は蟲師13話「一夜橋」のモデルになっているらしい。リアルタイムにみていたときには気付かなかったけど、そう言われてみればそのまんまよね。

高知市へ

かずら橋から 1.5 時間ぐらいかけて高知市の 城西館 という宿泊先に向かう。

晩ご飯は 土佐料理 司 高知本店 で食べた。お約束として出てくる食べものはすべておいしかった。その中でこれは過去に食べたことないなとおもったのが鮎素麺だった。

小さい鮎と素麺が一緒につゆに浸かっていて、鮎は骨まで食べられるぐらいに身をほろほろほぐせた。鮎の身をほぐしながら素麺と一緒にいただくという食べものだった。それぞれの食材は食べたことがあったけど、一緒の組み合わせで食べたことがなくて食べ方も楽しめて味もおいしかった。

その後、ホテルに戻ってきて大浴場入って眠くなるまで休憩スペースで作業をして寝た。

徳島のコワーキングスペース訪問

23時に寝て4時に起きて6時に起きて8時に起きた。今日はお休みをとって徳島のコワーキングスペースの見学へ行くことにした。当初は明日の午前中だけ見学しようかと考えていたけど、宿泊もした方が気付きが多いんじゃないかと思って一昨日に予定変更した。結果的にこれはとてもうまくいった。

ADLIV さん訪問

以前 カフーツさんのオンラインイベント徳島県美馬市脇町 のコワーキングの取り組みを伺っていた。機会をみつけて行きたいと考えていたのを今日行くことにした。10時過ぎに実家を出て、途中 道の駅いたの で休憩して、11時45分には ADLIV さんに着いた。

近くのラーメン屋さんでお昼ご飯を食べて12時半過ぎに ADLIV さんに着き、少し待たせてもらう。宿泊は4,500円で13時からチェックインできる。翌日のチェックアウトまでのコワーキングスペースの利用料も込みだという。13時まで待ってスタッフさんが来られて施設を案内してもらうことになった。

2Fはシェアオフィスになっていて通常コワーキングスペースの利用者には案内しないということなんだけど、他に利用者が少なくて余裕があったのか、私が伊藤さんの紹介だとメモに書いたおかげなのか、2Fも案内してもらえた。ラッキー。外国人が来たときも2Fをみたいという要望も多いと話されていたのでちょくちょく案内しているように聞こえた。

コワーキングスペースに宿泊できるが、ホテルではないのでスタッフは19時にはいなくなって翌8時ぐらいまでいない。それは全然構わない。チェックアウトもとくにスタッフに声をかけなくても勝手に出ていけばよいらしい。お世話になったので挨拶はして出ようとは思う。

今日の宿泊者は私だけなので自由に使ってよいとのこと。カプセルのカーテンを締めると暑いから他に宿泊者がいないから開けっ放しの方がよいとお奨めされた。他に誰かいたらコワーキング的な話を聞いてみようかと思っていたが、週の半ばでそれは叶わなかった。

チェックインして普通に作業していたら、オーナーのなかがわさんが来られて名刺交換して軽くご挨拶した。小さいスペースの方が涼しいからこちらへどうぞとハンモックがあるスペースで作業した。

その後、18時過ぎから一緒に晩ご飯行きましょうとなかがわさんに声をかけてもらって、自転車も貸してくれて、うだつの街並みの案内を受けながらお好み焼き屋さんへ行った。あとから地元の農家さん夫婦も合流して4人で雑談していた。

経営者しか経営者の気持ちがわからないとはよく言ったもので本当にその通りだと思う。うちみたいなお気楽な1人会社であっても、経営者という立場にになって初めて考えることや悩むことが多々ある。そして、経営者は会社の中では孤独な役割になる。経営者は経営という共通の話題をもっていて、他社の経営的な話しに共感しやすく、普段相談する相手もいないことから経営者同士は打ち解けやすい。学校で友だちを作る感覚に似ている。徳島県は淡路島から近いし、なかがわさんとはまたなにかの機会で縁があるといいなと思えた。

  • プロジェクトを通してそれぞれの専門家が一緒に働く仕組み作り
  • 寄せ集めのメンバーを統括してプロジェクトを為すマネージャー大事、超大事
  • 人と人との信頼はアウトソースできない
  • コワーキングスペースをやっていると、向こうからおもしろい人がやって来てくれる
  • 気付きを得て自律的に働く人とそうじゃない人の見極めは難しい
  • 社員にやってほしいことをやれと指示しても自律的に働くようにならない
  • 楽しく働く

18時半から21時までお好み焼き屋さんでわいわい雑談して ADLIV さんに戻って休むことにした。田舎なので閉店も21時半と早めだ。

寝る前に眠くなるまで、書架にあった 史記 を読んでいた。歴史好きなので読み始めると止まらなくなる。

scim 調査に着手

22時に寝て24時に起きて4時に起きて6時に起きた。実家だとやることないので寝るのも早くなる。早く起きているので始業も7時半ぐらいになる。早起きは三文の徳。

リモートワークのタグを新設

神戸のオフィスに行かなかった日は day off というタグを付けている。名前の通り、お休みしたということを表す。この定義に従うと、実家に帰ってリモートワークをしたときもお休みになってしまうため、それを区別するように remote work というタグを作った。

scim 調査

id 連携の文脈で System for Cross-domain Identity Management (頭文字をとって SCIM、すきーむと呼ばれている) という標準がある。基本的には rest api とスキーマを扱うように仕様が決められていて、それに準拠したサービス間で id 連携を標準化する狙いがある。id 連携と同じ用途を表す用語として id プロビジョニングという用語もあるが、多くのクラウドサービスでは id プロビジョニングのために scim 対応していたりする。

たまたまサイボウズさんが okta と scim 連携に対応しているプレスリリースをみかけた。

その延長で調査していたところ、go の scim ツールを提供していることに気付いた。しかもこれを作っているのが Maki さん。これはソースを読んでおこうと思った次第。Maki さんはメルカリに所属していたと思うのでこれは副業でやっているのかな?

scim-server は scim ライブラリを実際に使うときの参照実装としてアプリケーションの開発者に開発の雰囲気を伝えるための実装になっている。これ自体をプロダクトのサーバーとして使うわけではない。sqlite を使ってユーザー/グループの crud な操作と検索機能を提供している。

scim ライブラリのソースコードも軽くざっと読んでみた。github.com/lestrrat-go/sketch という go でスキーマを記述してコード生成する Maki さん製のツールがある。これを起点に scim のプロトコルやリソースの仕様にしたがって go のコードでスキーマを定義し、リソースに関する go のコードと scim スキーマを自動生成している。sketch というツールに関連して他にも Maki 製のメタプログラミングライブラリを多用していて、scim の標準化されている部分のエンドポイントやリソースのインターフェース部分をすべてコード生成している。

go generate やコード生成の実際の応用例として非常に参考になる。このライブラリは scim のプロトコル仕様に関する開発者と、そのエンドポイントの実際の処理 (バックエンド) の開発者を明確に分離するという開発体制を期待している。scim に関するところは Maki さんが独りでコード生成を多用してオープンなプロトコル仕様の開発を担当し、そのバックエンドをサイボウズさんの開発者が実装するという分業体制を想定しているようにみえる。

scim 対応のアプリケーション開発のプロトコル部分を外部に委譲するといった設計になっているが、scim が十分に安定していてプロトコルの仕様が変わらないのであれば理に適っているとも考えられる。バックエンドの開発者はいくらか sketch の学習コストを強いることになる。そのため、アプリケーションはその学習コストを支払ってもコード生成のメリットが上回るだけの規模や特性を要求する。おそらく scim はそれだけの価値があると判断されたのだと推測する。

私はメタプログラミングが好きな方なのでこういうやり方もあるんだなと設計の参考になった。またコード生成の要件があったときにソースを参考にしようと思う。

実家での初めてのリモートワーク

23時に寝て2時に起きて4時に起きて6時に起きた。親が4時頃から作業し始めるからそのぐらいからだらだら起きている。その影響で8時前からお仕事を始めた。

パスワードの表現の答え合わせ

先週末に課題としていた パスワードの表現 になかなか苦労したようで半日ぐらいかかった。私が答えを言うのではなく、本人が自分で考えて、自分で調べて実装できるまで粘り強く待っていた。概ね、私の模範解答に近いものを実装してきて、コードレビューで少し手直しはあったものの、go でコンストラクタに近いものを実装する方法を学んだと思う。

実家の離れスペースで働いてみた

今朝は軽く雨が降っていて、それ以降もずっと曇っていた。天気がどんよりしていたのもあり、エアコンは除湿に設定してソファで働いてみた。数年前から淡路島に帰ってきてリモートワークをしたことは何度かあったが、すべてマクドナルドへ行って電源を借りて作業していた。実家で丸1日リモートワークで働いたのは今回が初めてだと思う。どんな施設でもインターネットとエアコンさえあれば働けるということを改めて実感した。実家なのでお昼になったらおかんがお昼ご飯だと呼びに来る。食べるものも考えなくてよい。

iphone で作った wifi ルーター の 2GiB プランで契約している。普通に macbook でリポジトリを操作したり、課題管理を使ったり、ブラウザで調べものしたり、slack でやり取りしたりしていたら約9時間で 987 MiB の通信量となった。いまやネットワークの通信量を意識することはないと思うが、普通にお仕事したらいまの時代1日 1GiB ぐらい使うもんなんやと気付いた。

iijmio の管理画面で日次の通信量を当日分も含めて確認できる。

1週間とか、実家でリモートワークするなら 2GiB プランだと全然足りない。機をみて 5/10 GiB 程度のプランに変更するとよさそう。これでコワーキングスペースにして複数人が使う想定なら光回線をひかないとネットワークが厳しいということも理解できた。光回線をひくと安くても5,000円/月は固定費がかかってくるので維持費の問題は悩ましいことも分かってきた。

実家でいろいろな一日

0時に寝て何度か起きて4時に起きた。親が4時から起きて台所でごそごそしているからつられて起こされる。

魂入れのお経

9時から住職が来られて本位牌の 魂入れ のお経をあげてくれた。法事のときとは少し違うお経を30分ほどあげてくれた。感謝。喪主になってみて実感したことの1つに、死者のためにできることは限られることに気付く。どんな宗教でもよいと思うが、なにかしら死者の供養のために尽力してくれることがありがたい。そのまま白木位牌は住職が持って帰って処分?してくれるみたい。ついでに12月に1回忌をする予定の調整をお願いした。

トラクター

10時前から11時半ぐらいまで軽くトラクターで田んぼを耕した。周りの田んぼを耕しているトラクターをみたらエアコンがついていてうちのよりもやや小型にみえる。小さい田んぼならトラクターも小さい方が小回りがきいて端や隅を耕しやすいのかもしれない。うちのトラクターはおそらく中古でもう10年以上は使っているだろうから真面目に農業するときにトラクターを新調してもいいかもしれない。いまどき鍬で田んぼを耕すなんて事実上できないのでトラクターだけは妥協せずお金を払った方がよいと思う。私は鍬仕事を30分やっただけで腰と握力がなくなって大変なことになる。

海鮮丼とサワラ

お昼は 魚魚やす (ととやす) という漁師がお昼だけあけている食堂のようなところに食べに行った。母は何度か行ったことがあったそうだが、私は初めて。ちょうど満席で15分ほど待った。店員さんが愛想なかったり待っている客の対応もよくなかった。田舎の忙しい食堂はサービス精神とかない。

一番人気の魚魚やす海鮮丼 (1,850円) を注文してみた。普通にはおいしかったが、値段が高いのでコスパという側面からみると普通かな。これが1000円前後だったらもっと印象は変わった気がもする。いろんな魚の刺身を食べられてよいのだけど、やや刺身の切り身が薄い気がしてコストダウンなのかなぁとか思ったのがさらにマイナスだった。魚そのものの鮮度はまぁまぁでした。

淡路島はサワラ (鰆) もよく漁れるところでサワラ食べるの久しぶりで懐かしかった。個人的に好みではなかったのであまり意識したことがなかった。生サワラ丼があちこちで食べられるみたい。昔はサワラも当たり前だったので特別な魚に思ってなかったけど、淡路島の特産品としてみるとお客さん向けによいかもしれない。次は生サワラ丼を食べてみたい。

膳先の品物選び

法事を終えた後に参加者に渡す手土産のようなものを膳先と呼んでいる。本来の意味もなにかあった気がするのだけど忘れてしまった。一家に1つなので参加者数よりも少なくなる。法事のときは参加人数の食事と家数の膳先の品物を数えて準備しないといけない。言うても49日以降、減ることはあっても参加者が増えることは基本的にあり得ないので最大49日の人数と家数を考慮しておけばよい。膳先の品物選びに大きなホームセンターのギフト売り場へ行ってきた。予算は5千円程度でよさそうな品物を見繕って次の配分になった。

  • 揖保乃糸: 2千円
  • 佃煮セット: 2千円
  • お菓子: 1千円

実家の離れスペースのオフィス化

出張所作り の続き。夕方から新設したばかりのエアコンをつけて、セカンドモニターに映して、iphone で作った wifi ルーター に繋いでしばらく作業してみた。あとは作業をするための作業机がない。どこかで作業机を購入しないといけない。いずれコワーキングスペースにすることを考慮すると最初から大きな机を買ってもいいかもしれない。

お仕事をしない週末

3時に寝て7時頃に起きて8時半に起きた。1時前に帰ってきて軽く夜食を食べてだらだらしてた。

ストレッチ

今週はそんなに忙しかったわけではないのに疲弊している。気温が上がって暑くなってきている。家でもエアコンをつけるようになってきた。その暑さで夏バテしているのかもしれない。食べるよりも飲む方が多い。ストレッチを受けてみて、腰はそれほど悪くなかったが、右足全般の張りがつよかったように思える。今日の開脚幅は開始前158cmで、ストレッチ後160cmだった。数値はよかった。右股関節の改善のためにスクワットをやるようにしてほしいとトレーナーさんから指導をうけた。続くかどうか、やってみる。

合鍵の精度

2-3日前から合鍵がオフィスの扉のシリンダーに入りにくくなった。入らないわけではないが、すっと入っていたのが引っかかりが出るようになった。直感的にいままで使えていた合鍵が悪いとは思わずシリンダー側の原因かな?と運営会社のサポートに連絡したらスタッフの方が来られて、たまたまオリジナルキーをもっているので交換しますよという。そのスタッフさんがオリジナルキーをシリンダーに入れてみるとスムーズに入る。これは合鍵の問題だなとわかって、私も自分のオリジナルキーを家からもってきて試してみたらスムーズに入る。

この合鍵は作ってから半年ほど使ってきたわけだけど、なにかしら老朽化して変形したのかな?と作ってもらった合鍵屋さんへ行って話しを聞いてみた。

  • 数千本に1本あるかないかの事例
  • (目でみて?) 合鍵とオリジナルキーを比較した限りでは変形や歪みはない
  • 合鍵屋さんにあるまったく同じシリンダーではスムーズに入る
  • オフィスの扉のシリンダーが変化してオリジナルキーの精度を要求するという問題ではないか?
  • オリジナルキーと合鍵は 0.03mm 以内の誤差があるのでまったく同じではない

これまで使っていた合鍵が入りにくくなるといったことは初めてだったので私も驚いた。一方でシリンダーにあわないのであれば、この合鍵を使い続けるのはよくないということで、新しく作り直してもらった。新しい合鍵ではオリジナルキーほどスムーズではないが、すっと入るようにはなった。鍵をシリンダーへ差し込むときの微妙な違いがあるんだなと気付きを得た。

社用車の半年点検

13時からの点検予定をすっかり忘れていて13時ぴったりにスマホの通知で気付いた。こういうのはカレンダーにタスクじゃなくてイベントで住所も登録した方が現在位置から移動時間も考慮して事前に通知がくるのでよさそうだと気付きを得た。

ディーラーの営業さんに慌てて一報入れて13時半に着く。点検作業は約1時間。そのままディーラーでのほほんと待っていた。エンジンオイル交換してくれて、とくに異常はないとのこと。これから実家へ帰って、来週は四国を横断してくるので安心を手に入れた。次も半年後に1年点検がある。整備士さんにガソリンは半年ほどで劣化しますか?と聞いてみたら半年ぐらいなら大丈夫ではないかと話されていた。車のガソリンタンク内であれば密閉されているのでまだ劣化しにくいという。しかし、ポリタンクや一斗缶などで保管している場合は湿気や空気と触れやすくて半年ぐらいで劣化してしまうかもしれないと話されていた。

実家へ帰る

明日、住職が来てくれて白木位牌から本位牌に 魂入れ のお経をあげてもらう。通常は49日までに行うのが慣習らしいが、うちは段取りが遅れたのか宗派の違いなのかまだ行っていなかった。調べていると49日後から1周忌までに行う場合もあるという。ちょうど来週は四国へ旅行へ行くのもあって、週末から実家に帰って実家の出張所でちょっと働いてみてその後に四国へ行こうと思う。

トイレにうんこ

0時に寝て4時に起きてドラクエタクトやりながらだらだらしているうちに少し寝て7時に起きた。

トイレにうんこを詰まらせた

いや。正確にはトイレが詰まってうんこを浮かべた。朝トイレへ行ったら洋式トイレにトイレットペーパーが漂っていた。前に使った人が流していないのかな?と考えて気持ち悪いのですぐ流した。これまでも過去にそういうことがたまにあった。あとから考えると、誰かのいたずらでなにかしらトイレに詰まるものがトイレットペーパーの下に隠されていた可能性もある。この時点で次に水が流れるかどうかのチェックをするべきと洞察できていなかった。

それから、うんこして流したらトイレが詰まったようで流れない。微妙に便器から水が溢れてきた。ぎりぎり溢れ返ることにはならなかったのでトイレの床にうんこが散乱する最悪の状況にはならなかった。しかし、トイレにうんこがぷかぷか浮かんでいる状態になった。べつに私が悪いわけではないと思うのだけど、トイレにうんこが浮かんでいる状態にしてしまったことにとても罪悪感を感じた。

幸い朝8時からシェアオフィスにいるのは私ぐらいで、多くの利用者は10時前後にならないと出社してこない。いまトイレに誰かが入ってきて犯人扱いされることはなさそう。なんか行き当たりで人を殺めてしまった殺人犯みたいな心境になった。運営会社のサポートは9時から。1階へ降りていって掃除のおばちゃんに尋ねてみたけど、うんこが浮かんだトイレの階は自分たちの管轄じゃないと断られてしまった。(´・ω・`) 仕方なく、時間を待って9時ぴったりにサポートに電話して聞いてみる。サポートにも断られたらどうしよう?不安と緊張が走る。サポートのお姉さんは (当然ではあると思うけれども) 全然平気ですよーと快く応じてくれて安心した。まぁ、電話しているお姉さんが対応するわけじゃないしね。

電話で一報を終えて、その後、トイレ業者さんが来るまで自分のうんこを浮かべておいていいのかどうか、すごく悩んだ。かといってうんこを取り出す勇気もなく結果的にそのまま放置した。人間がしょぼい。40年以上も生きてきて自分のうんこの処理もできないのかと思うと本当に情けなくなった。「入るな、危険」ぐらいの張り紙しといてもよかった。本当の犯人だったらここでとんでもないトリックを思いついて実行するところだけど、一報したことでそこまでの切羽詰まった状況でもなくなっていた。もし警察がやってきてもサポートのお姉さんが犯人じゃないと証言してくれるだろう。

9時から打ち合わせがあって、1時間半後、恐る恐るトイレを見に行ったらすでに詰まりは解消していてうんこもなくなっていた。平和な日常が戻ってきてよかった。

平安時代とか、都はうんこまみれだったという記事を昔読んだのを思い出した。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。今日の議題はこれら。

最初の30分でサイトデザインをみながら、はらさんのレビューの視点や背景を教えてもらっていくつか気付きを得た。後半は来月の雑談会へ向けて、課題管理の資料のレビューを始めて、いつもは1時間で打ち合わせを終えるのだけれど、つい課題管理の話しでテンションあがって話し過ぎてしまって30分オーバーした。打ち合わせのような時間を決めている会議で議論に熱くなるのはよくない。失敗したなーと反省した。

パスワードの表現

go でパスワードを扱うときに平文をハッシュ化して保持するためのユーザー定義の構造体を作りたい。構造体にハッシュ化した値をもつとしても、プログラマーが誤って任意の値を設定できないように制御したい。ここで go はオブジェクト指向言語ではないのでコンストラクタという概念がない。私が知っているもっともシンプルな方法は interface と private な構造体を組み合わせてコンストラクタに近いものを実装する。コードレビューしていてメンバーにパスワードがハッシュ化されていることを保証する仕組みをお題として指摘してみた。

今日のところは解決できなくて月曜日に持ち越しになった。私の想定する模範解答は次のようなものだけど、ちゃんと自分で考えて実装できるかなぁ。

type Password interface {
	Authenticate(s string) error
	Get() []byte
	String() string
}

type passwd struct {
	hashed []byte
}

func (p *passwd) Authenticate(s string) error {
	return bcrypt.CompareHashAndPassword(p.hashed, []byte(s))
}

func (p *passwd) Get() []byte {
	return p.hashed
}

func (p *passwd) String() string {
	return string(p.hashed)
}

func NewPassword(s string) (Password, error) {
	h, err := bcrypt.GenerateFromPassword([]byte(s), bcrypt.DefaultCost)
	if err != nil {
		return nil, err
	}
	return &passwd{hashed: h}, nil
}

雨降り後、曇りで散髪

0時に寝て5時に起きて7時に起きた。朝から雨降りでテンションが低くなった。いろいろマネージャーのお仕事をやってはいるのだけど、これと言って特筆するものがあったわけでもなかった。いろいろ細かい作業して、コードレビューや課題管理して、気付いたら時間経ってた的な1日だった。

散髪

週末から実家へ帰って来週は実家と四国で作業するのでその前に散髪しておこうと慌てて行ってきた。たまたま予約を取れてよかったが、いつもカットしてもらっている人とは違う人がになってしまった。過去にみたことがない若い人で初めてカットしてもらう。おそらく最近入った新人さんではないかと推測する。隣でどんな感じにカットしたらいいか、いつもやってくれているスタッフがアドバイスしてくれたせいか、大丈夫かな?と思ったものの、いつも通りにカットできて問題はなかった。

若い人だったから話しするのがあまり上手くなかった。ゴールデンウィーク何してました?とか聞かれた。いま6月下旬だよ。いまさら聞かれても詳細を覚えてないし、私は基本的には法人決算していたんだけど、あまりおもしろい話しもできたのでお仕事忙しくていろいろやってました的に返した。

厄介なインフラ問題をやっつけた

2時に寝て6時に起きて7時に起きた。夜に作業していたら遅くなった。

厄介なインフラの問題 解決編

運用のトラブルシューティング の続き。アプリケーションアカウントを作って compose 環境を構築したら nginx のコンテナが起動して即時終了する状態になったという。これまで起きていた現象とまた違う問題が発生してさらに混迷をもたらすかに思えたが、私の中では nginx のコンテナでなにかがおかしいと問題の発生箇所を局所化できたのでそこからの調査はそんなに時間を必要としなかった。

結論からいうと podman の aardvark-dns の不具合だった。なんらかのトリガーでコンテナネットワーク内の名前解決が不整合な状態に陥る。

vagrant@bookworm:$ podman-compose exec proxy /bin/bash
...
root@3742c45c7c60:/# dig app

; <<>> DiG 9.16.37-Debian <<>> app
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56696
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 37ff0fd63315d70e (echoed)
;; QUESTION SECTION:
;app.				IN	A

;; ANSWER SECTION:
app.			86400	IN	A	10.89.0.36
app.			86400	IN	A	10.89.0.36
app.			86400	IN	A	10.89.0.136
app.			86400	IN	A	10.89.0.136
app.			86400	IN	A	10.89.0.146
app.			86400	IN	A	10.89.0.146
app.			86400	IN	A	10.89.0.156
app.			86400	IN	A	10.89.0.156

;; Query time: 4 msec
;; SERVER: 10.89.0.1#53(10.89.0.1)
;; WHEN: Thu Jun 22 02:45:26 UTC 2023
;; MSG SIZE  rcvd: 172

podman 4.0 から aardvark-dns がコンテナネットワーク内での dns を提供する。nginx が app を名前解決したときに起動しているコンテナの ip アドレスではなく、削除された過去のコンテナの ip アドレスが返される状況が発生する。app という名前に対して複数の ip アドレスが返る。

このとき nginx は複数の ip アドレスのうちの1つに接続しようとするが、正しい ip アドレスでない場合、リクエストがタイムアウトする。タイムアウトした後に fallback で他の ip アドレスに接続しにいく。このときに正しい ip アドレスがみつかればクライアントにレスポンスが返る。この fallback のリトライの回数分だけリクエストのレイテンシの時間がかかっていた。

vagrant@bookworm:$ podman logs -f proxy
...
2023/06/22 02:46:26 [error] 15#15: *41 connect() failed (113: No route to host) while connecting to upstream, client: 10.89.0.38, server: ucidmsv1-app, request: "GET / HTTP/1.1", upstream: "http://10.89.0.136:3000/", host: "localhost:4430"
2023/06/22 02:46:29 [error] 15#15: *41 connect() failed (113: No route to host) while connecting to upstream, client: 10.89.0.38, server: ucidmsv1-app, request: "GET / HTTP/1.1", upstream: "http://10.89.0.156:3000/", host: "localhost:4430"
2023/06/22 02:46:32 [error] 15#15: *41 connect() failed (113: No route to host) while connecting to upstream, client: 10.89.0.38, server: ucidmsv1-app, request: "GET / HTTP/1.1", upstream: "http://10.89.0.136:3000/", host: "localhost:4430"
10.89.0.38 - - [22/Jun/2023:02:46:32 +0000] "GET / HTTP/1.1" 200 2864 "-" "curl/7.88.1"

ワークアラウンドとして、次のファイルに複数の app の ip アドレスが登録されていれば不整合な状態なのでネットワークを削除して、このファイルも手動で削除してしまえばよい。

$ cat /run/user/$(id -u)/containers/networks/aardvark-dns/mynetwork

ファイルを監視していると、どうやら mynetwork ファイルから名前と ip アドレスの情報が削除されるのは該当のコンテナが削除されるタイミングになる。なんらかのエラーにより、コンテナ削除時にマッピングの削除が実行されないと、古いコンテナのマッピング設定が残ったままとなり、compose サービスを起動したときに複数の ip アドレスの名前解決できる状態になってしまう。ちょっと調べても aardvark-dns に関する issue はたくさん登録されている。

コワーキングのオンラインイベント

月例のカフーツさんのオンラインイベントに参加した。先月の所感はここ 。今日はもともと予定していた話しをする参加者が急遽参加できなくなってしまったので他の参加者での雑談会になった。

いとうさん曰く、これまで外国人のデジタルノマドは自分で業務時間を選べるフリーランスの、さらにお金に余裕をもった人たちが多いと考えられていた。しかし、実際にコワーキングスペースに来られている外国人にキャリアを伺うと、大企業の普通の社員であることがわかってきた。グローバルな会社だと、働く場所に制限のない会社もあって、ただ日本へ行ってみたかった的な理由で日本へ来られて数ヶ月滞在して普通に会社のお仕事をするといったデジタルノマドもいるという。過去に私が働いていた職場の同僚も、コロナのときに会社がフルリモートワークの体制を設けて、airbnb で全国を旅しながら1年ほど働いていた。日本でもそういう社員はいるのだから外国人はなおさらという感じ。

そういった外国人のデジタルノマドが要求することが3つある。

  • 24時間利用できること (勤め先の会社と時差があるから)
  • セカンドモニターがあること
  • ・・・ (あともう1つあったが、忘れてしまった)

コワーキングスペースに外国人のデジタルノマドを呼び込むにはどうすればよいか。実際にコワーキングスペースへ来られた外国人に理由を伺うと英語のホームページをみて来ましたということらしい。至極、当たり前の話し。英語のホームページをちゃんと作ろうねみたいな話題で話していた。

go の channel 制御の学び

0時に寝て2時に起きて5時に起きて6時に起きた。久しぶりに夢をみたような気がする。

go の channel とクローズ制御

rabbitmq/amqp091-go を使った pubsub の consumer の実装で次のような for ループでメッセージを取得していた。この場合 deliveries の channel が閉じられると内側の for ループが終了して、外側の for ループの接続処理へ遷移する。

for {
    // コネクションの接続処理

    for d := range deliveries {
        // メッセージ処理
    }
}

この処理を context を使ってキャンセルできるよう、次に書き換えた。channel の Receive operator のドキュメントによると、channel は2値を返すことができて、戻り値の2番目の ok の値を調べることでその channel がクローズされているかどうかを判定できる。この仕組みを知っていれば select で ok を調べてエラー処理を実装できる。そうしないと deliveries の channel が閉じられれたときに select では常にゼロ値のメッセージが返るようになって意図したメッセージ処理とならない。

for {
    // コネクションの接続処理

    for {
        select {
        case <-ctx.Done():
            // context がキャンセルされたら終了処理
            if err := s.ch.Cancel(cid, false); err != nil {
                return fmt.Errorf("failed to cancel channel: %w", err)
            }
            return nil
        case d, ok := <-deliveries:
            if ok {
                // メッセージ処理
            } else {
                // エラー処理
                break
            }
        }

        // コネクションが閉じていればループを抜けて再接続
        if s.conn.IsClosed() || s.ch.IsClosed() {
            log.Info("the session was closed, try to reconnect", nil)
            break
        }
    }
}

同じ channel からメッセージを取り出すループ処理でも用途によって使い分けがあるなぁと今更ながら学んだ。というか、自分でバグを埋め込んで自分で直した (´・ω・`)

マージまで約1ヶ月

先日送った amqp091-go の pr が最終的にはほぼそのままマージされた。約1ヶ月ぐらいの議論やレビューがあって取り込まれた。新しいリリースバージョン (次は 1.9.0?) が出たらうちのアプリケーションでもこの新しいメソッドを使うようにして実績を積ませる。この pr は「あったら便利」程度の機能なのでそれほど重要ではない。

この成功体験をもって次は本命の go-ldap の pr のマージに向けて勢いをつける。こっちの pr は業務に直結しているので本気でやり取りしている。