2022-08-30 (火)
なんだか調子悪いな.
この日記はフィクションです.登場する人名・団体名・地名・職業などはぜんぶ架空のものです. なので実際のものとは何も関係がありません. それから,写真のように見える画像はCGもしくは念写によるものです.
なんだか調子悪いな.
goでビルド環境とテストを実行する環境が別の時,テストを呼び出すmain関数書いてコンパイルしてたけど,go test -cでコンパイルすれば良いだけなのを知った...
眠い...昼過ぎまで寝る日.
DokanではなくWinFspのGoのbindingsはメンテナンスされてそうな気配? cgofuse
今更ながら,Visual Studio を 2022 に移行する.Visual Studioをアップデートすると何かしらビルドできなくなること多かったけど,今回は今のところ何も問題ないな.
やること溜まっているので,色々雑用をこなしていたら夜になってしまった...
たくさんGoモジュールがある場所で go work use -r してVSCodeで開発していると,VSCodeでファイルの保存ができなくなったり,goplsがCPUを消費し続けたりするな...goplsのGo Workspaces対応がまだ微妙な感じなのかも.
Goの fs.FS をOSのファイルシステムにマウントしたい(Qiita)
今週作ってたやつをWindows以外でもとりあえず動くようにする.もともとはOculusQuestのリモートデスクトップ環境を改善しようとしていた気がするけど,FUSEのbindingsを実装しているの,なんでだろう.
あと,Qiitaに動画を直接埋め込めないので,twitterにデモ動画を投稿してツイートを記事に埋め込むのをたまにやるのだけど,先に動画だけ拡散して文章は読まれない罠がある.
https://github.com/binzume/fsmount
fs.FS interfaceを持ったファイルシステムがあればプラットフォームに依存せず1行でマウントできるようになった.go-fuseを使う実装は何年も前に書いたやつを無理やり入れたのでリファクタリングしたほうがよさそう.
サンプルプログラムとしてフォルダを開くことで進むリバーシ(オセロ)を作った.無駄にAIと対戦もできる.アクセス時にパスの文字列から盤面を生成するのでディレクトリをスキャンするようなアプリケーションが動いていると悲惨なことになる.エクスプローラのプロパティのフォルダ数からリバーシで到達可能な盤面の数がわかるけど,数え終わるまで見てると宇宙の寿命が尽きそう...
どうでも良いけど,Windowsのエクスプローラってファイルとフォルダを混ぜてソートできないのか.置けない場所は画像ファイル並べようと思ったのだけど順序がコントロールできなくて全部フォルダにして中にfolder.gifを置くことにした.ReadDirしたときはfolder.gifを返さないけど直接Statしたときは存在することにする雑な実装.
https://github.com/binzume/dkango
ディレクトリ周りやファイルのリネームとか対応してテストしてたのだけど,Goで実装されたプログラムがディレクトリにアクセスするときに,FILE_NON_DIRECTORY_FILE
フラグをつけてCreateFile()
して,失敗したらディレクトリとして開き直しているように見える.
よく意図が分からない挙動なのでGoのソースを見ると Open()
の中で通常ファイルかディレクトリか判定していて,さらに空ディレクトリかどうかチェックするためにFindFirstFile()
してるな...Open()
は1回のAPI呼び出しかと思い込んでいたけど空のディレクトリにアクセスする場合は4回ファイルにアクセスしているように見える.特にディレクトリOpenするの,ほとんどの場合は ReadDirするためで,事前にFindFirstFileするの無駄そうだけど,なんでOpen()
の中でやってるんだろ.
Go 1.18のworkspace,複数のライブラリに分かれたプログラムを開発するときに,古き良きGOPATH時代みたいに編集中のライブラリを使ってくれて便利なのだけど,よくgo.modファイルを更新し忘れる...
ここ最近,ファイルを扱う Go のプログラムで独自インターフェイスでアクセスしてたのを fs.FS に置き換えたりしていて,FUSE周りで少し困ったので色々実装する.
go-fuse や dokan-go をラップして使ってたのだけど,fs.FSを渡して終わりみたいな単純なインターフェイスではないのが少し面倒.特にdokan-goの方はずっとメンテナンスされてなくて,そのままでは最近のGoでコンパイルすら通らなくなっている.修正して使ってたけど,そもそも,Windowsのcgoが面倒事が多くて避けたいのでGoだけで実装したやつを作った.
https://github.com/binzume/dkango
2017年頃に少し書きかけてたやつだったのだけど,早めにやっておけば良かった.
眠い...
https://github.com/binzume/webrtcfs
先週書いたやつを,ファイルの書き込みとかもできるようにしておく.色々な場所にあるストレージをネットワーク越しに使うときWebRTCだとNATとかDNSとか気にしなくて良いのと,中継用のサーバ無くてもブラウザからも直接アクセスできるのは便利.
眠い.
しばらく使ってるけど,やっぱりまだ微妙に不安定.ドラッグ&ドロップやクリップボード周りでクラッシュすることあったけど,これは操作に慣れる(?)とクラッシュしなくなった.あとは,IMEの状態がたまにおかしくなるのどうにかならないかな..
あと,タブ機能を推してる割には,タブを別ウインドウに分離したり,ウインドウをタブに加えたりといった,今どきなタブアプリケーションっぽい機能が無いのも微妙に不便.
Goのjsonパッケージ,[]byte
や[]uint8
を勝手にBase64エンコードするの,うっかり忘れていると何故かGoで生成したjsonだけ他のライブラリで読めなくなったりして困る.単一の値や配列はそのままエンコードされるのに,スライスになった途端Base64エンコードしだすし,便利な場合より困ることが多い気がする.
この挙動はオプションでコントロール出来ないっぽいので,一旦 []uint16
に詰め直したり,専用の型にしてMarshalJSON()書く必要があって面倒.
https://github.com/soichisumi/go-simple-jsonmarshaler みたいなのもあるけど,継続してメンテナンスされてそうなライブラリあれば良いのだけど.
Goのfsパッケージを使って,ディレクトリ内のファイルを列挙したい場合,ReadDirFileとReadDirFSインターフェイスにReadDir()があるけど,ReadDirFSの方はファイルの個数を指定できないので全ファイル一度に読む必要があって,大量のファイルがあると困る.
特にfs.WalkDir()もReadDirFSを先に確認する実装になっているので,アクセスに時間がかかる場所に大量のファイルがあると,読み込み中にコールバックが呼びだされなくて微妙...
かといって,ReadDirFileを優先して使うWalkDirを作ってしてしまうと,今度はReadDirFileが実装されてるかOpenするまで不明なので,ReadDirFileを実装してないファイルシステムで無駄なOpenが発生して,これも微妙な動作になる..OpenDirFSみたいなインターフェイス作ってほしかった...
休みが終わってしまった...
Go の fs.FS
を実装したコードのテストを書いてて気づいたけど fs.ReadFile()
って実際のファイルサイズより常に1バイト多く読もうとするのか.実際は無害なのだけどファイルの範囲外にアクセスしようとするのがバグに見えて何か計算間違っているかと思ってしまった.効率的にEOFをチェックするために見えるけど,内部でStat()が呼び出されてるので,サイズが分かるときはそのサイズ分だけRead()してほしいような気が.
眠い...
https://github.com/binzume/webrtcfs
昨日,空港と飛行機の中で WebRTC 上でファイルを共有するやつをGoで書いていた.とりあえず,Ayameでシグナリングして以前作った WebXR 用のリモートデスクトップ環境からファイルを見れるところまで.
https://github.com/pion/webrtc を使ってるのだけどたまにChromeのWebRTCとの接続に失敗する.なんでだろ(と思ったけど,ice candidateが一方向にしか送れてなかった)
手を洗った時に日焼け止めが落ちたせいか,手の甲が日焼けして痛い.東京に戻る.
泊まったホテル,あちこちにUSBで充電するタイプの機器が置いてあるのだけど,充電大変そう..
タコライス.お腹いっぱいになってしまった.
分かりにくいけどミナミスナガニ.砂浜にたくさんいる.白い.
お昼食べたあと,涼しい場所を求めて早めに空港に.帰りの飛行機は下地島空港から(の予定だった).
待ってたら乗る予定の便が台風の影響で欠航に...代わりの飛行機が明日の神戸経由茨城空港行きという微妙なやつしか無いと言われてしまったので,SKY便をキャンセルしてJALで今夜の便を取り直す.キャンセルしたやつの倍以上の値段...予定外の出費(ついでに一度今日帰るの諦めてホテルも取ったりしてたので,完全に無駄なキャンセル料が)
もう一泊しても良かったのだけど,茨城空港の場所が不便そうだった...
宮古空港に着いたら羽田行きは行き先が変更になるかもとアナウンスされて不穏な感じが...夜は台風過ぎてるだろうし大丈夫そうに思ったのだけど,無難に明日の便にしておけば良かった気がする.そして,宮古空港のWiFiつながりにくい.
少し遅れたけど羽田に到着.ギリギリ今日中に帰れるかと思ったけど,家についたら日付変わっていた.
飛行機の中から繋がらないホストと繋がるホストがあったので何が違うのか見ていたら,IPv4で接続できないホストだった…….自分しか使わない環境はもうIPv4いらないと思って設定してなかったの完全に忘れていた.
自分の周りはIPv6に対応したのは2003年頃だったけど,19年経っても繋がらない環境があるのは,なんでこうなってしまったんだろ.もう完全に移行に失敗してる気がする.グローバルアドレスの数とかNAT設定とか忘れられるので嬉しいのだけど.
エアコンの効いた部屋に引きこもる誘惑に負けそうだけど,宮古島まで来たので今日は外に出る.
自転車借りに行って,暑さに負けて気づいたら原付スクーター借りていた.
伊良部大橋を渡りたかったので伊良部島に.
フナウサギバナタ展望台?思ってた場所と違うような気がしたので調べたら鳥のオブジェは取り壊されてしまったのか.
せっかくなので下地島まで行って,宮古そば食べた.(ソーキそばとの違いはよく分かってない)
通り池.下地島空港のすぐ近く.
これ,いっぱい生えてて美味しそうに見えてググったけど,アダンという木の実だった.デイリーポータルZ情報によると美味しくないらしい.実はパイナップルに似てるけど全く違う植物.
空港の進入灯.
反対は滑走路.飛行機が飛ぶとこ見たい気がしたけど,暑すぎて熱中症になりそうなので帰る.
眠い.とりあえず準備して出かける.
https://github.com/binzume/adbproto
GoでAndroidのADBにつなぐやつを独立したパッケージにしておく.SYNCパケットでのファイル転送とかは気が向いたら実装する.
JALの機内WiFi,SSHが繋がるホストと繋がらないホストがあるのだけど何でだろ.あと,電波が出る機器は使っては駄目という注意事項の直後にWiFiの案内するの,もう内容変える気ないんだろうか...
座席のディスプレイの再起動中に色々見えていたのが気になった.
さすがに接続できなかったけど,MACアドレス調べるとThales Avionics In-Flight Systems LLCの機器っぽい.
このモニタ,Video Inputとして黄色のRCA端子があるのだけど,2022年にそんな映像出力ができる機器を持ち歩く人いない気がする.
旧宮古島市役所.ホテルの地図見たらすぐ近くが市役所だったので,市役所前までタクシーで行こうとしたら一度違う場所に行ってしまった...だいぶ前に移転したらしい.見た地図が古かった.
うなぎ食べた.
水回りとかエアコンとかの掃除してたら半日使ってしまった…….
休みに家にいると睡眠時間がだんだん伸びていくので,過ごすのに良さそうな場所を探す.
基本的には引きこもるのでどこでも良い気がするけど,ゴールデンウイークは北に行ったので今度は南にする.とりあえず,明日の飛行機のチケットを予約.
朝から暑すぎる..
とりあえず寝る日.
夏休み
明日から,15日まで休みにしたので10連休.
Go1.19でGenericsのパフォーマンス改善されたみたいだし,そろそろ色々なものをGenerics使った実装に置き換えてたのだけど,なんだかとても実行が遅い...
気になったのでコンパイル結果を眺めてみたけど,
type SimpleComparator[T comparable] struct{} func (c SimpleComparator[T]) Equal(a, b T) bool { return a == b } func main() { var c SimpleComparator[int] fmt.Println(c.Equal(42, 42)) }
こういう単純な例でも,インライン化されていない.
type IntComparator struct{} func (c IntComparator) Equal(a, b int) bool { return a == b }
こっちは,もちろんインライン化される.基本的にGenerics型のメソッドはインライン化されないみたい.
実際には,Comparatorを型引数として色々な処理に渡していて, 空のstructならインライン展開されていれば実行時のコストは全くかからないと思ったのだけど,毎回レシーバを指定したメソッド呼び出しになってしまっていた.これならstructではなく関数を値として取り回した方が少し良さそう.
一応,main.SimpleComparator[go.shape.int_0]
みたいな型が生成されて使われてるので,将来改善されそうだし,ほとんどの場合は気にならないけど.
そういえば,Goが出力するアセンブリ,引数が全部スタックに積まれてた時代はCPUアーキテクチャほとんど意識せず読めたのが,1.17からレジスタベースのABIになってアーキテクチャごとのレジスタの用途を知らないと読みにくくなってしまった.
もう8月...時間が経つのがはやすぎる.