Posts for: #Go

地方は都会の人たちにとっての消費の場ではない

0時に寝てうまく眠れなくて、吐き気がして3時頃に起きてそのまま起きてたらいつの間にか寝て8時に起きた。夜遅くにアルフォート食べたのがよくなかったかもしれない。

go アプリケーションのライセンスチェック

お手伝い先で開発しているプロダクトは原則として oss ライセンスにするといった方針らしい。公けにソースコードを公開していないものの、お客さんが望めばソースコードも提供するといった運用にしているらしい。実際にお客さんでソースコードを要求されたことはないという。そのため、自分たちの開発したアプリケーションを oss なライセンスで提供可能かどうかを、一応は、調べておく必要がある。プレスリリースもしているし、いつお客さんが使い始めるかもわからないので、プロジェクトの隙間のときにライセンスチェックをした。

ググってみたら google/go-licenses というツールがあってこれを使って自分たちが開発したモジュールのライセンスチェックをした。問題なく apache 2.0 のライセンスで提供できることを検証した。

  • インストール
$ go install github.com/google/go-licenses@latest
  • レポート出力
$ cd path/to/repository
$ go-licenses report ./...
  • ライセンスチェック
$ go-licenses check ./... 2>&1 | egrep "^(W|E)[[:digit:]]+"

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

月例のカフーツさんのオンラインイベントに参加した。前回の所感はここ 。8月は私の予定があわなかったのでイベントを欠席したが、7月の所感がないのはなぜか忘れてしまった。単純に忙しくて書く余裕がなかったのかもしれない。

今回のテーマは都会と地方のコワーキングスペースの運営の違いなどについてざっくばらんに雑談するといったイベントだった。後半に ONOMICHI SHARE というコワーキングスペースを運営しているごとうさんという方が参加されて、広島県尾道市という地方というバックボーンをもっていて、ごとうさんからの視点や考え方を話していただいて、いくつか示唆を受けることがあった。ごとうさんが言うには、都会から尾道市へ移住してくる人たちにはなにかしら目的があって来る、しかし、地方は都会の人たちが求めているなにかを消費するだけの場所ではないという考えを大事にしたいと話されていた。

私が地方出身の都会暮らしだから感じることがある。都会の人たちにとっての地方は娯楽とみられることが多い。わかりやすさのために、地方の不便さや独特の文化などを例にあげるが、そこに住んでいる人たちにとってはそれが日常だから何も思わないことを、都会の人たちは娯楽だと接しているようにみえることがよくある。そのギャップを埋める役割があって然るべきだと私からも思えた。要は勘違いした人たちを、現実に引き戻す役割というべきか。その話の延長上で、地方の人たちは暮らしをよくしようとか、世界をより良くしようとか、ビジネスに挑戦しようとか、そういったことをまったく考えていなくて、自治体がどんなに過疎化していっても、生活が不便になっても、この生活が一生続くと思ってなにもせず、そのまま暮らしているという人たちも多い。都会の人たちの役割の1つとして、そういった地方の人たちに世の中はどんどん進んでいて、新しいことに挑戦する価値や楽しさもあるんだよという気付きを与えることができるんじゃないかと、雑談しながら思えた。

おそらく、ごとうさんの話しを聞く限りでは、そういう仲介をする役割を担っているようにみえた。コワーキングスペースマネージャーも奥が深いという気付きを得た雑談だった。

slog の完全移行の少し手前

0時に寝て何度か起きて6時に起きた。土曜日から喉が痛くてコロナ感染の懸念もあったけど、前日は一日中休んでいたせいか、喉の痛みは全くなくなった。たまたまだったのかもしれない。

slog 移行

slog 勉強会 で学んだ LogValuer という interface を使うと、機密情報のログ出力をカスタマイズできる。要はパスワードのような文字列を *** に置き換えるといったことをしたい。もっともシンプルな機密情報を扱う型として Secret を定義した。この Secret でラップした文字列を扱う分には slog のロガーでそのまま出力しても問題ない。

type Secret string

func (s Secret) LogValue() slog.Value {
	return slog.StringValue("***")
}

func (s Secret) String() string {
	return string(s)
}

あと自前で定義していたロガーのログ関数を slog のトップレベル関数を使うように1つずつコードを書き直していった。機密情報に関するところで一部まだ置き換えていないところもあるが、98%のログ出力のコードは slog に直接置き換えた。時間がかかるだけの面倒くさい作業なので、こういうプロジェクトの隙間に地道にやるのがよいと思う。今回も移行にあたって slog のコードを少し読んだが、slog は本当に既存のログ出力の機能で大事なところだけをシンプルに実装していてよく出来ていると思う。

お休み前の勉強会

22時に寝て24時に起きて2時に起きて4時に起きて6時に起きた。晩ご飯食べてからオフィスに戻る元気がない。本当は明日の出張に備えて今晩、実家へ帰ろうと思っていたが、まったく準備ができていないので明日の早朝に帰ることにした。

slog 勉強会

チーム勉強会向けに、今日は軽い話題として slog のブログ記事をピックアップしてみた。この内容を deepl で翻訳して社内の wiki に書いてそれをメンバーと共有した。

うちのプロジェクトの logger はすべて slog に移行済みではあるが、一部 slog を使う前に実装したログ関数があって、そのカスタムログ関数の移行だけまだできていない。アプリケーションの振る舞いには影響を与えないし、急ぐ必要もないので先送りにしているだけ。次の開発フェーズでカスタムログ関数周りもすべて移行して slog で万全の状態にしたい。そのための予備知識として slog でこんなことができるという全体像は理解できた。とてもよい記事だったと思う。

LT 資料の推敲

先日 LT 資料のたたき台 を作成した。いくらか寝かして週のどこかの空いている時間に推敲しようとずっと頭の中にはあったものの、現実にはさぼっていて前日に最終見直しをしている。でも、見直した方がよいところのアイディアは2-3個思いついてはいる。少し手直ししたら明日のイベントに備えて早めに寝る。

組織やプロジェクト横断的なメトリクスの視覚化

0時に寝て4時に起きてもう1回ぐらい起きて6時半に起きた。

もうすぐ期限がやってくる。私が担当している issue 対応はあらかた終わってメンバーに「大きいもので見落としある?」って尋ねて「ない」って返ってきたのでもうクローズに向けて調整していく感じ。今週末から月曜日と3日間お休みする (土日も含めて休むというのも変ではあるが) ので一安心。

dirsync 周りのリファクタリング

ずっとレビューが放置されていた。おそらくいま go-ldap のプロジェクトで最も活発なメンテナーが夏休みだったのではないかと推測する。昨日帰ってきたようで怒涛のレビューをされていて、私が3週間前に送っていた pr もレビューしてくれた。

概ね同意してくれて public な関数名をより適切な関数名に変えたところを、1度公開したものは互換性を維持するために deprecated のコメントをして残しておいてと言われたところだけ修正した。修正後、数時間ですぐにマージしてくれた。感謝。

go-ldap にいくつかコントリビュートした機能はうちのプロダクトのシステムに使われていて、それなりの qa テストをやった上で動いているので一定の品質は担保していると思う。直近1年間のコントリビューター を参照すると、私は2番目に貢献しているようにみえる。こういう見える化が自分のモチベーションになるならそれはそれでよいと思う。

組み込みの課題管理のプロダクトを作る上で、個人がみたいメトリクスを簡単に集計できるような機能を提供しようと考えている。それは自分が伸ばしたいスキルやプラクティスに対して、会社やプロダクトを横断的に計測できる仕組みがあるといいと私は考えている。とくにいまどきはプログラマーが転職するのは当たり前だが、転職したら前の会社でやっていたメトリクスがみれないとか、別の会社でのメトリクスと相対比較したいとか、そういうニーズはあるなと私自身が感じているからでもある。

go イベントのパネルディスカッション

mercari.go #23 Go1.21 パネルディスカッション オンライン開催 に参加した。視聴者が少なかったのか、youtube のコメント欄でちょくちょくツッコミもいれたら現場で拾ってくれておもしろかった。私が関心のあった話題を3つあげてみる。

gonew の提供

For a long time now, we have heard from Go developers that getting started is often the hardest part.

Experimenting with project templates

go で新規プロジェクトを始めるときにテンプレートからプロジェクトのレイアウトを作ってくれるユーティリティとして gonew というツールが公式から提供されたらしい。知らんかった。私も新しいリポジトリ作るときに標準的なものはファイルを基本コピペしているのでこういうのできれいに作れると嬉しいかもしれない。 

derrors の是非

pkgsite という pkg.go.dev というサイトのリポジトリの internal として実装されている derrors というパッケージがある。defer を使って必ず関数がエラーを返すときに wrap するという、ユニークな発想で実装されたツール。明示的なコードを書くという go の文化とはあわない気はするけど、ユニークな使い方ではあるのでおもしろい。

この延長でエラーが発生したときにレポートを生成する derrors のユーティリティもあったりする。google がやっていることだから、わりと開発者間でもこれと同じものを自前で実装する開発者が増えているといった話しも聞く。

go 2 はもうリリースされない

The answer is never. Go 2, in the sense of breaking with the past and no longer compiling old programs, is never going to happen. Go 2 in the sense of being the major revision of Go 1 we started toward in 2017 has already happened.

Backward Compatibility, Go 1.21, and Go 2

これまでの go の言語処理系の開発の中で非互換な変更について「go 2 で」とプロポーザルだったり、issue の議論で先送りされてきた。最近コア開発者の Russ Cox 氏が (現時点で) go 2 はもう出ないと宣言した。go は既存のプログラムをコンパイルできない状態で新しいバージョンを出すことはしない。この背景の1つとして、誰もがジェネリクスの導入で go の互換性は崩れると思っていたものが互換性を維持して導入できたことが大きいと思う。(現時点で) go 2 はもうリリースされないらしい。

トークン認証のプロバイダ実装

22時から寝始めて何度か起きて6時に起きた。最近は早寝早起きにしている。

client ライブラリのトークン認証対応

いまの開発の新機能の1つにローカルアカウントの管理機能がある。普通のパスワード認証により、JWT によるアクセストークンを発行し、リフレッシュトークンを使ってアクセストークンの再取得を行う。api サーバーで実装してもらったこれらの web api を使って、api client 側でもログインしてアクセストークンを取得して web api のリクエストができるようにする。一般的にアクセストークンは有効期限が短いため、有効期限が切れたときは透過的にリフレッシュトークンを使ってアクセストークンを再取得する。またリフレッシュトークンの有効期限が切れたときは再ログインして、アクセストークンとリフレッシュトークンを再取得する。

文章で書けばこれだけの機能だけど、このための AuthProvider を実装した。最終的には次のインターフェースになった。

type AuthProvider interface {
	CanRefresh() bool
	GetAuthorization() (string, error)
	GetType() AuthType
	Refresh() error
}

先週たまたま Azure/azure-sdk-for-goAuthProvider のソースコードを読んだ。やりたいことに対して、かなり複雑なことをしているようにみえたが、アクセストークンのキャッシュ、有効期限が切れたときのリフレッシュを透過的に行うコードだった。このライブラリの実装が読みにくいコードで、私だったらもっとシンプルに実装するというイメージが先週からあったのでそのイメージ通りに実装して1日で対応を終えた。本当はこの機能をいまの開発フェーズで提供する予定はなかったんだけど、うまく簡潔に実装できたので一部 agent で導入してテストで検証することにした。

コンテナー間のデータ通信と named pipe

22時頃から寝ていて2回起きて3時に起き出して、4時までネットみたりしていて、また寝て6時に起きた。生活のリズムがおかしい。

コンテナー間のデータのやり取り

昨日 モジュール分割 したことにより、いままで1つのモジュールで管理していたが、モジュールを分割したのでそれぞれのバージョンを取得できるとよいという話題が出た。コンテナー内にアプリケーションのバイナリがあり、バイナリを実行するとバージョン情報を取得できる。それぞれのモジュールは独立したコンテナで動いてるため、コンテナー間でその情報を受け渡す方法が必要になる。ググってみると次の so がヒットして named pipe がプラクティスだという。

ホスト os 上の named pipe をコンテナーの volumes でマウントして、それぞれのコンテナーが読み書きすればよい。構築時に named pipe さえ作ったらコンテナー内での読み書きでデータ通信を実現できるため、シンプルでよいんじゃないかと思えた。

mypipe という named pipe を作る。

$ mkfifo mypipe

読み込み用コンテナーのための read-Dockerfile を作る。tail コマンドで named pipe を読む。

$ vi read-Dockerfile
From bash:latest

ENTRYPOINT [ "tail", "-f", "/app/mypipe" ]
$ docker build -t mypipe-read:latest -f read-Dockerfile .

named pipe をマウントして読み込み用コンテナーを起動する。

$ docker run --rm --mount type=bind,source="$(pwd)"/mypipe,target=/app/mypipe,readonly mypipe-read

書き込み用のエントリーポイントのスクリプトはちょっと工夫がいる。おそらく Dockerfile 内で直接リダイレクトの操作ができない (やり方がわからなかった) 。シェルスクリプトを呼び出す形にして、シェルスクリプト内部でリダイレクトにより、named pipe に書き込みする。

エントリーポイントのスクリプトは次のような感じ。eval "$@" で任意のコード実行できるようにちょっと細工。

$ vi myentrypoint.sh
#!/bin/sh

cleanup() {
    echo "cleanup ..."
    exit 0
}

trap cleanup INT TERM

while true
do
    echo "$(date)"
    eval "$@"
    sleep 1
done

書き込み用コンテナーのための write-Dockerfile を作る。先の myentrypoint.sh を ENTRYPOINT として起動させる。

$ vi write-Dockerfile
From bash:latest

COPY myentrypoint.sh /app/
RUN chmod +x /app/myentrypoint.sh

ENTRYPOINT [ "/app/myentrypoint.sh" ]
$ docker build -t mypipe-write:latest -f write-Dockerfile .

適当に乱数を生成する cli を eval 実行させる。

$ docker run --rm --mount type=bind,source="$(pwd)"/mypipe,target=/app/mypipe mypipe-write "tr -dc 0-9 < /dev/urandom | fold -w 8 | head -1  > /app/mypipe"

読み込み用コンテナーで乱数を表示できるはず。

なにも難しくなく、linux の標準の機能を使ってコンテナー間のデータ通信を実現できたことにちょっと驚いた。

go で named pipe を読むときは linux ならば syscall.O_NONBLOCK を指定することで書き込みしていなくてもブロックせずに読める。値を取得できない可能性はあるけど、それが許される要件ならこれで済む。またテックブログにまとめたい。

func readNamedPipe(path string) ([]byte, error) {
	flag := os.O_RDONLY | syscall.O_NONBLOCK
	pipe, err := os.OpenFile(path, flag, os.ModeNamedPipe)
	if err != nil {
		return nil, fmt.Errorf("failed to open path: %w", err)
	}
	defer pipe.Close()
	reader := bufio.NewReader(pipe)
	b, _, err := reader.ReadLine()
	if err != nil {
		return nil, fmt.Errorf("failed to read line: %w", err)
	}
	return b, err
}

go の処理系も驚く sdk のコード生成

0時に寝て何度か起きて6時に起きた。そのまま7時過ぎまでだらだらしてた。しんどい。

msgraph-sdk-go のサイズ問題

先週 msgraph-sdk-go を使った開発 を終えてデプロイする段階になってライブラリのサイズが大きくて、コンパイル速度が遅くなったり、バイナリサイズが大きくなったりする弊害があることに気付いた。コンパイル速度は2-3倍遅くなり (3分が7-10分ぐらい)、バイナリサイズも2-3倍大きくなる (30 MiB が 100 MiB とか) 。たまたまこのリポジトリは他のツール類からも依存パッケージとして使われるものなので想定よりも影響が大きいことに気付いた。

朝からチームのメンバーとミーティングして、本来は qa に入ったこの時期にこんな変更をすべきではないが、これは放置するデメリットが大きいのでリポジトリ分割 (モジュール分割) しようと提案して了承を得た。私がやれば作業は1日もあれば完了するだろうと見積もって、見積もり通り、夕方には分割したモジュールをテスト環境にデプロイして当面の解決を得た。アプリケーションのモジュール構造をちゃんとレイヤー化して作ってあるから、今回みたいに急遽、モジュール分割が必要になってもほぼ変更する必要はなかった (たった1箇所だけ) 。

この本質的な問題は次の issue のコメントで説明されている。

ざっと機械翻訳してみる。

コンテキスト

この SDK は kiota を使用してメタデータから自動的に生成されます。オリジナルのメタデータは、Microsoft Graph の配下にあるすべてのサービスチーム(v1用とベータ用)によって入力された CSDL です。この CSDL は最終的に OpenAPI のフォーマットに変換されますが、これは非常に大きなものです(1k 以上のエンドポイント、1.5k のモデル …)。API のサイズが大きいため、完全な API surface の SDK を手作りすることは実現不可能でしょう。

私たちは、SDK を複数のサブモジュール(ファイル用、メール用など)に “スライス” して、人々が関心のあるものだけを簡単に入手できるようにすることをしばらく考えてきました。実際、私たちは PowerShell でこれを実現しました。しかし、“グラフ” の性質(すべてのモデルは互いにある程度関連している)と構築されるアプリケーションの多様性により、スライスは誰にとっても “正しい” ものにはならない(大きすぎたり、小さすぎたり、モデルの重複につながったり…)。

そのような理由から、私たちは「完全なSDK」を提供することにしました。すべての人にとって理想的とは言えないかもしれませんが、Go開発者の中には「アプリケーションを作るためのSDKが欲しいだけ」という人もいると感じています(以下で説明する2つ目のオプションとは対照的です)。

Go の欠点

Go の探求を通して、いくつかの欠点に気づいた。現時点では、私たちのプロジェクトやパッケージが適切にセットアップされていないせいなのか、Go や大規模プロジェクトの制限のせいなのかはわからない:

go build は、変更されておらず、依存関係も変更されていないサブパッケージをリビルドすることが多い。go build が直前に実行されていても、go test がリビルドすることがよくあります。なぜある種のキャッシュに頼らないのでしょうか?同じ問題が go lint にもある。
私には、たくさんのサブパッケージがある大きなプロジェクトをビルドするコストは、依存関係が更新されたり、キャッシュが削除されたり、コードが変更されたりしない限り、「セッションごとに一度」だけ支払われるべきだと感じます。

私たちのプロジェクト構成/構造において、そのような状況を改善するための最適化について、自由に概説してください。また、Goコミュニティ(Goコンパイラを開発している人たちなど)と関わって、そのようなフィードバックを提供する方法があれば、喜んでそうします。私たちのプロジェクトは、その規模の大きさから、世の中にあるほとんどのGoパッケージと比べると、ちょっと変わり者だとわかっています。

適切なサイズの SDK

最後に、すべてのエンドポイントを備えた完全な SDK を持つことは、様々な理由からすべての人に適しているわけではないことを認識しています。私たちは新しい “適切なサイズのセルフサービスSDKエクスペリエンス” を可能にするために取り組んでいます。そこでは、APIユーザーは誰でも、この SDK と同じように見え、同じように感じる SDK を生成することができますが、完全な API サーフェスの代わりに、彼らのアプリケーションのために彼らが気にするエンドポイント/モデルのみが含まれています。 私たちは今、そのような取り組みに本当に早くから取り組んでいますが、それでもフィードバックをいただけるとうれしいです。大まかな手順はこんな感じだ:

  1. 新しいgoプロジェクトを作成するか、既存のプロジェクトを特定する。
  2. kiotaの依存関係を追加するか、msgraph-sdk-go-coreを追加します(これはKiotaの依存関係をプルし、いくつか追加します)。
  3. グラフエクスプローラで必要なリソースを選択(左パネル、2番目のタブ、…、“コレクションに追加”)。
  4. コレクションをプレビューをクリックし、postmanコレクションとしてエクスポートします。
  5. hidi を postmanコレクションと先ほど共有したOpenAPIの完全な説明文と一緒に使って、“フィルタリングされた” OpenAPI フォーマットを生成する。
  6. kiotaを使って、プロジェクトにMicrosoft Graph用のGoクライアントを生成する。
  7. APIの呼び出しを開始する。

この時点で、私たちはこれらのステップをすべて文書化し、効率化するために取り組んでいます(おそらくステップ4~5を圧縮しています)。このアプローチの素晴らしいところは、ステップ5から7までが、Microsoft Graphだけでなく、呼び出したいOpenAPIで記述されたAPIで動作することだ。
繰り返しますが、この最後の提案はまだ初期段階です。自由に試して、様々な場所でフィードバックを提供してください。

この長い投稿で、私たちがどこに向かっているのかが明らかになり、Goコミュニティからこれらの側面すべてについてさらにフィードバックが得られると本当に助かる!

簡単に言えば、ms graph api の体系が巨大過ぎて、その定義は openapi.yaml にあるが、この定義からすべてコード生成すると巨大なモデル定義をもつ sdk が出来上がってしまったという話しである。後半に書いてあるワークアラウンドとして kiota で必要なモデルだけを選択して専用 sdk を生成すればサイズを小さくできるとある。しかし、それはそれで graph explorer で選択しないといけなかったりして面倒そうではある。次のドキュメントでもその手順について書いてある。

うちの用途ではモジュール分割により、局所化したのでひとまずこの問題は大きな影響をもたないようになった。また余裕があるときにモデルを選択して専用 sdk を自動的に生成する仕組みを構築できるならそれに挑戦してもよいかもしれない。

msgraph-sdk-go のビルド問題

1時に寝て何度か起きて7時に起きた。昨日は少し早めにお仕事を終えて家で休んでいたので少し回復した。

msgraph-sdk-go を使った開発

昨日の続き 。前日に作ったマージリクエストをチームのメンバーにレビューしてもらっていくつか修正して、マージを終えた。一段落。

さらにこの sdk を使うことで8月の前半に開発していた差分比較のところも変更しないといけないことに気付いた。public な構造体のメンバーにアクセスして差分比較する処理を実装していたが、この sdk は getter で構造体のメンバーにアクセスしないといけないことに気付いた。reflectoin の処理に追加で実装を入れるだけなのでそんなに難しくはない。そういった修正をしていたら1日終わってしまった。開発していると時間が過ぎるのは早い。

たまたま ci/cd ジョブの実行時間の上限を10分にしていて超えるときがあってジョブが失敗した。 調べてみると、msgraph-sdk-go の api が巨大過ぎてメモリを浪費したりコンパイルに時間がかかったりするという issue をみつけた。

私のローカル環境で測ってみると、約36秒で完了していたテストが2分23秒かかるようになっていた。テストの実行が4-5倍ぐらい遅くなった。さらにコンテナイメージのサイズは 36 MiB から 109 MiB と3倍ほど増えた。無駄に開発を遅らせる環境要因になっているのでこれは別途調査して対応しないといけないことに気付いた。

開発の瞬発力が足りない

最終の新幹線で帰ってきて、2時に寝て2回ぐらい起きて8時前に起きた。寝坊した。7時頃に起きてない時点で疲れているんやろなと思えた。

msgraph-sdk-go を使った開発

昨日の続き 。ライセンスやグループのメンバーを扱うときの特殊な処理を実装してからマージリクエストを送った。本当は火曜日の時点でできたらよかったことが2日遅れになった。モチベーションがあれば、日曜日や月曜日の夜にできたことかもしれない。加齢のせいかもしれないし、私の中でまだ開発になにかが足りない。誰かから責められるわけではないが、自分で自分に嘘をつかないために自分なら間に合わせられたものが2日遅れになっているという事実にだけは気付いている。id 連携のビジネスロジックに相当するところの置き換えに4日かかったというのはノウハウがなかったらそんなもんという気もせんでもない。一通り実装できたのであとは qa テストで複雑なテストケースのバグ出しをすればよいだろう。

年度末打ち上げ

22時に寝て何度か起きて6時に起きた。カプセルホテルに泊まるときにいつも忘れることで、下の方のカプセルにしてもらうのをお願いすべき。おっさんには上のカプセルによじ登るのが辛い。カプセルホテルに泊まるので盗難防止を考慮して着替え以外はもっていなかった。パソコンがないので朝からやることもなくてお風呂入って、休憩スペースでのんびりしていた。

msgraph-sdk-go を使った開発

azure との id 連携のリファクタリング の続き。

microsoft 社のシステムの仕様が直感的でなかったり、sdk の api が使いにくかったり、この sdk を使うことの学習コストがやや高い。一方でドキュメントを読めば仕様はちゃんと書いてあるのでドキュメントを読みながら開発していくのがよさそうに思える。当たり前と言えば当たり前だが、ドキュメントを読まないと絶対に分からない仕様が多いという意味で学習コストが高い。

例えば businessPhones というプロパティはリストで設定するけれど、これは1つしか設定できないという仕様になる。2つ値を設定しようとするとエラーになる。

businessPhones String collection The telephone numbers for the user.
NOTE: Although this is a string collection, only one number can be set for this property.
https://learn.microsoft.com/en-us/graph/api/user-update?view=graph-rest-1.0&tabs=http#request-body

だいぶ sdk に慣れてきて、あともうちょっとのところだったが、今晩は予定があるので切り上げとなった。

年度末打ち上げ

お手伝いしているお客さんが8月が年度末になる。年度末の会社の打ち上げをやるのでよかったらどうぞとお声がけをいただいていた。うちのプロジェクトのスケジュールにあわせると定例を行う週の火・水の2日間だけ参加可能として予定を提出していた。他の社員さんの予定と調整して2週間もあるからそんなあわないだろう?と思っていたらあってしまって出張するしかないかと今回の出張が決まった次第だ。

17時半から東銀座へ移動して、ホテルの地下にあるちょっとよい雰囲気のレストランでお食事をいただいた。立派な陶磁器に芸術的な料理が添えられていて、おいしかったし、みて楽しむこともできて、会社で来ないと食べられないような内容で私はよかったと思う。食べものはコースだったが、若い人向けにはもっと量がないとお腹が空くだろうから追加でいくつか料理を頼んだりしていた。行ったことないレストランの量はわからないのでコースの選択は難しいと思う。

約55%の社員 (+お手伝い) が参加していた。欠席者の半分以上はリモートワークだったり業務都合で参加できなかったのを考慮すると、私用で欠席している社員は少数派にみえる。私用で欠席できるというのも多様性の文脈では大事だと思えるし、それでも7割ぐらいは参加する意志があるというのは組織としてのまとわりを表す指標の1つに思える。

私自身、昔はあまり会社の全体飲み会が好きではなく、チームや部署単位なら行くが、全社となると欠席する方が多かった。会社の中のよく知らない人たちと親睦を図ることにあまり価値を見出していなかった。しかし、いまマネジメントの立場で考えると、一定の理解はできるようになった。マネジメントとして社員に平等に報いる方法はかなり限定的であること。個別の社員ごとに好ましい方法で対応することはできないという現実がある。したがって、こういった全社的な催しもしかたないと言える。

そして、こういった場で人と人の結びつきや人間関係を良好に保つように、社員みんなが努力して組織が成り立っているのだとわかるようになってきた。 私は直接部門だから売上を上げてれば文句ないだろうとずっと思ってきたけれど、必ずしもそういった見た目の数字だけが会社を維持させているわけではない。目にみえない価値もたしかに組織にはある。 若い頃の私はその努力に欠けていた、もっというとフリーライドしていたという見方もできることに気付けるようになった。

その価値をいま風に言えばチームビルディングといったラベルがついている。それをどうやってうまく成し遂げるか、こういう場で見聞きすることの大事さもわかるようになってきた。だから、いまの私は自身にとって重要ではないイベントも後学のために役に立つかもしれないと前向きに参加するようになった。結局のところ、イベントを楽しむのもそうじゃないのも自分次第である。どんなことからも学べる。その学びがあるのならきっと楽しいと言えるかもしれない。社員旅行へ同行しての学び も大いにあった。

18時から始めて21時前でお開きになった。それから東銀座を出て9時24分の新大阪行きの最終新幹線に乗れた。新大阪に23時48分頃に付いて23時55分発の新快速に乗った。新幹線が2分遅れたことで新快速も2分出発を遅らせて57分発になった。その後、他にも神戸線で事故があった影響か、信号待ちがどうこうで芦屋あたりからずっと低速運行していた。最終的に三ノ宮には到着予定から17分遅れになった。疲れて早く帰りたいなと思っているときほど、こんなもんという印象。考え方を変えれば、いろいろあったのに、ちゃんと三ノ宮まで帰れてよかったと思えばそんなに気も悪くない。

2023年最初の記事は事例紹介

0時に寝て7時に起きて8時前までだらだらしていた。昨日は開発してないけれど、なんか疲れて起き上がれない。

先週末に恒大集団が米国で連邦破産法適用を申請というニュースが出ていたので香港市場でひと波乱あるのでは?という憶測も出ていたけど、とくに変わりなく1日が終わった。別の不動産大手もデフォルトの危機らしくて、その2回目の期限が1ヶ月ほどあるようなのでもう1ヶ月してから波乱があるのかもしれない。

最後のリファクタリング課題

このマイルストーンで開発を終えて次マイルストーンからテストへ移行する。機能拡張はほとんど終わっていて、作り直した方がよいリファクタリングのチケットをいくつかやっている。そのうちの1つに azure 連携するときに rest api を直接使っていて sdk を使っていない。microsoft 社も go の sdk を提供している。将来的には型によるバリデーションの仕組みを導入したいと考えている。あらかじめ sdk を使ったコードに置き換えておきたい。sdk が使いやすい api になっていれば、すぐに進捗するところが、これがなかなか、この sdk の api 設計もコードもあまりきれいなものではない。一方で大半のコードはスキーマからコードを自動生成しているようもみえるのでモジュールの構造を理解してしまえば、api の設計も類推は効くようになると思う。

ユーザー/グループの取得周り、ユーザー作成の web api 呼び出しを置き換えて疲れて晩ご飯を食べに帰ってしまった。家に帰ったらもうダレてしまってそのままだらだら休んでいた。残りの開発を明日に先送りにする。疲労もあるのか、モチベーションコントロールがうまくいかなくて、昔だったらあと2-3時間作業して帰るところのひと踏ん張りがきかなくなりつつある。気を引き締めないとあまりよくない。

事例紹介

昨日更新したたたき台 を最終版にするつもりが、午前中、先方に送る前に読み直したら細かいところに気付いてちょっとだけ推敲した。午前中にレビュー依頼を出して、夕方には返信がきてそのまま OK が出て、事例紹介を公開した。会社のサイトをすっかり触らなくなってしまっていて、8月になって2023年初めての更新になる。何度も書いているけど、この事例紹介は私の自己満足で、これを書くと世の中の役に立っている気がして嬉しくなる。さらに今回はプロジェクトマネージャーとして実績を出すことができたので次のキャリアへの大きな一歩となる。今後も課題管理の探求をがんばっていく。