2023年に買ってよかったもの

2023年に買ってよかったものをAmazonの購入履歴から見る

デザインスッキリしてるし、取り回しもよいので家の電源コードは大体これになっている。便利

サッカーのオシム監督が言葉を実際に受けた人がその後どうしているか?というお話。 「お祝いの花は、もう枯れた」という言葉があって、過去に固執してないでもっと先を見ろとか、今までの努力と失敗を疑えとか、ウィットにとんだ表現をしててよかった。 一番よいエピソードは子供が「コーチからリフティングを100回やって言われた。どうやったらうまくなる?」と聞かれて、「試合中に100回リフティングしてる選手みたことある?今すぐ止めろ」と言ってたのはよかった。さすがに100回はやってなかったけどピクシーくん...

普段はPC用の電源として使っていて、旅行とかに行くときにはバッテリーに使っている。今年は2回ぐらい二人で旅行に出かけてるけど二人まとめて充電できるからこれ1つ+ケーブルがあればよい。

音質もいいし、マイク性能もよいので仕事でのオンラインミーティングやPCで音楽聴くときはこれ1つで済んでいる。kispは解約した。ただし、それなりのパワーが必要で今使っているPCだとつなぎ直したりロック解除すると音声のバランスが安定しないので、セルフパワーのUSB経由で繋いでいる

後は生活雑貨ばっかりだった...

古いterraform でAWSLambdaをあげたときにはまった話

AWSsharp - High performance Node.js image processing を使ったNodeを動かすためにLambdaを使っていました。sharp部分をLayerにして実際のコードをLambda関数というごく当たり前の構成にしてました
それをNode.js18に上げようとしたのですが、たぶん Error expanding plan for AWS Lambda Provisioned Concurrency · Issue #14267 · hashicorp/terraform-provider-aws だと思われるバグに遭遇して、いったんはS3のサンプルにあるようにLayerを使わずにやろうと。サンプル:チュートリアル: Amazon S3 トリガーを使用してサムネイル画像を作成する - AWS Lambda

結論

ちゃんとバージョンアップをしてLayerを真面目に使うか、DockerをLambdaで動かせばいいのでは

はまりポイント: null_resource, archive_fileの扱いを熟知してなかった

最初package-lock.jsonとかコードを変えたらトリガーすればいいやん。と思って、こういうコードをを書いてたんです。
terraform planすると差分でるし、terraform applyするとうまくいくのでよかったよかった。
ただ、次の作業をしようとしたときに、CI(GitHub Actions)上で「あれ?差分がでるぞ?」となって調査。
自分の手元のPCでもplanすると差分がでる。 更になぜかラムダ関数のzipの中身にnode_modulesがない。

これは理解がたりてなかったんですが、 data.archive_filedepends_onnull_resource をしてるけど、triggerが走ってない(npm ci)が走ってない状態でzipファイルを作っていたんです。なので、そりゃぁ差分がでるよね。
これを調べている間にローカルPCでplan実行していたのですが、そもそも null_resource が動いている気配がない。これapplyのときしか local-exec がうごかいないんですね。よくよく考えたらplan時に副作用あったらこまるからそうか。
だから、巷で流れている 「null_resource ので○○しました」って、planが考慮されてない気がする。applyとplanがずれるなら何のためのplanやねん。
(まぁ実際にplanは成功してapplyして失敗することはあるんだけど)

resource "null_resource" "test" {
  triggers = {
    change = join("", [
      filebase64sha256("${path.root}/lambda/index.js"),
      filebase64sha256("${path.root}/lambda/package.json"),
      filebase64sha256("${path.root}/lambda/package-lock.json")
    ])
  }

  provisioner "local-exec" {
    working_dir = "./lambda"
    command     = "npm ci" 
  }
}

data "archive_file" "test" {
  type        = "zip"
  output_path = "function.zip"
  source_dir  = "${path.root}/lambda"
  depends_on  = [null_resource.test]
}

どう対応したの?

考え方としたら、aws_lambda_functionsource_code_hash をかえなければよい。つまり作成されるzipファイルのsha256をbase64エンコードした結果が同じであればよいです。
なので、 data "external" をつかって常にzipファイルを生成するようにしました。ただ、これだと毎回zipファイルの結果が異なります。
なので、その中のシェルでzipファイルの中身も全て同じ時刻にしました(この時点でもうダメ過ぎる)。 もちろんファイルの中身が変わればzipファイルの中身もかわるのでそれにも対応してる。 という、ワークアラウンドでなんとかしようかなぁと思います

#!/bin/sh

# 結果のjqだけほしいので全部 /dev/null 2>&1にしている
set -eu
export NODE_ENV=production
timestamp='2023-11-01T00:00:00'

# install module
npm ci > /dev/null 2>&1
rm -rf node_modules/sharp
SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm ci --arch=x64 --platform=linux --libc=glibc sharp > /dev/null 2>&1

# function.zipを何回生成されても同じファイルになるようにtimestampを統一する
# find node_modules -type f -print | xargs -I{} touch -d "${timestamp}" {}
# find node_modules -type d -print | xargs -I{} touch -d "${timestamp}" {}
find node_modules \( -type f -o -type d \) -print0 | xargs -0 -I{} touch -d "${TIMESTAMP}" {}
touch -d "${timestamp}" index.js

zip -r -X function.zip index.js node_modules > /dev/null 2>&1
touch -d "${timestamp}" function.zip
FILE_SHA256=$(openssl dgst -binary -sha256 < function.zip | openssl base64)
mv function.zip ..
jq -n --arg code_hash "$FILE_SHA256" '{"code_hash":$code_hash}'
data "external" "make" {
  working_dir = "./lambda"
  program = ["sh", "make.sh"]
}

resource "aws_lambda_function" "test" {
  function_name    = "test"
  role             = aws_iam_role.lambda.arn
  filename         = "function.zip"
  handler          = "index.handler"
  runtime          = "nodejs18.x"
  source_code_hash = data.external.make.result.code_hash # ここを変えたくない
}

追記

find を2回かいてるのださいなーと思ってMan page of FIND見直してたら -o でor検索できるのか。みんな思うところは同じなんだな

何回も言いますがSlackは文章を書くためのツールではないです

なんか気軽にツイートけどもう少し文章を構造化したいなぁと思ったので書く

ツールの使いかたから考える

Slackは様々なチャネルで多くの人がリアルタイムでやりとりをしている。更にメンションされることもある。と言うことは、人が1つの投稿に対してかけられる時間は少ない。 また、また長い投稿をしてもそれはすぐに流れてしまう。恐らく今日書いた情報の8割は明日には忘れてるし、それを探すのも大変である。 長々と書かれた文章に対して長々とスレッドをみんなで返してるのを見てると途中の読む気が失せる(実際読んでない)

ツールの入力から考える

画面から見てわかるとおり長い入力を想定しているインタフェースではない。

Slackの画面
スニペット機能なども備えていることからもわかるとおり、ちょっと長いもの(かきすてのコードとか)を書きたいときはそっちを使うことを想定していると思われる。 Canvasはまだちゃんと使っていないのでわからないけど、結局流れていくというインタフェースからは抜け出せない気がする。

あとなんと言っても段落付けができない。段落付けができないから文章の起承転結がわからなくて、何が言いたいのかがわからない。
特にお気持ち長文を書かれていると、事実とお気持ちとその他成分が混じり合うので何が何だかわからなくなる。

どういうときにSlackは向いているのか?

昨日・今日・明日の情報で十分、短いことを共有したいときには向いている。 毎日の開発のやりとりとか、質問に答えたりとか、メンテ作業の作業ログとかに使っている 他に自分の今の仕事の使い方だと、

  • 毎日遅いAPIのレスポンススピードをスニペット機能に貼り付けてコメントを書いてる
    • これは数日の数値の変化が必要なので、別途スプレッドシートにストック情報としてまとめている
  • あとはサーバメトリクスの画像をはったりとか
    • これもCloudWatch Application のダッシュボードであとで見れるのでフロー情報として十分
  • 作業やトラブル対応などのハドルをつかったミーティング
  • Google Meetだと画面にペンで書く機能が無いのでこれが一番役に立っている
  • Notionで書いた内容のサマリ
    • NotionのURLをSlackにはると Notion冒頭の callout が表示されるのでそれで代用することもある

文章を書くツールの特徴

まず、基本的かつ大切なところで文章構造がとれる。見出しをつけることができて段落構造がとれる。読み手が途中まで読んで、あとから読むときに段落の途中から読める。 画像も文章の途中で差し込める。まずこれだけで読みやすさが全然違う。

Google Docの例

サービスによって異なる機能として便利な機能としていくつかある。 各種マニュアルや仕様書・設計書などを書くときにほぼ使う機能としてこのあたりが上げられる

  • ドキュメント履歴管理や共同編集
  • 提案機能
  • 行に対してコメントをつけることができる
    • esaにこの機能が欲しいんだけどプレーンテキストという特性上難しいんだろうなぁ... 😢

書き方として便利な機能

会社として使うのに便利

  • 閲覧権限管理

自分の使い方を例に挙げる。今の会社ではNotionがほぼメインでたまに社外の人とやりとりするときはGoogle Docsを使う。

  • 議事録、マニュアル
  • 毎月のAWSコストを月初にみんなにアナウンスするとき
  • 開発時の設計などをするとき。コメントもNotionに集約するように促している
  • 時間がかかりそうな(設計の見直しとかが必要そうな)パフォーマンスチューニングや性能検証
  • ポエムぽい物

どのツールがいいの?

文章を書くツールは長く使う&みんな使うので値段はそれなりにするのできちんと吟味した上で検討したいところで、必ずしもこれが絶対にいいとは言えない。
一時期だとみんな「Notion最高」と言ってた気がするけど、正直日本語入力がイケていない。よくカーソルが飛ぶので結構ストレス。
コンフルは今も重いのだろうか...?
なので、この辺は機能比較+トライアルで全力で試してみてみるしかない。
値段抑えたいし、権限管理したいし、ある程度の使いやすさを求めたいのであればGoogle Docsは悪くない選択肢だとは思うんだけどどうなんだろうなー
この辺を解決したかったのがGoogle Waveくんだった気がするんだ...

なぜ自分たちがソフトウェアを細かくアップデートする必要があるのか

いろんなところで100万回語られてることなので特に目新しいものはなにもないです。

ここでのソフトウェアはプログラミング言語フレームワーク、ライブラリ、DBなどの各種ミドルウェアなどを指します。

ソフトウェアをアップデートしたときのメリット

セキュリティの向上

提供サービスに脆弱性攻撃を受けても素早く対処ができて安全・安心なサービスをユーザに提供できます。

新しい機能が利用できる

ソフトウェアは日々改善されています。アップデートではより便利な機能、生産性向上に寄与する機能、性能が改善されたソフトウェアを利用することができるようになるため、サービスをユーザへ素早く・安全に品質高く提供することが可能になります。

採用・技術力の向上に繋がる

ソフトウェアのアップデートは 正しくソフトウェアを作るプロセス の1つで現在では当たり前のことです。 正しい物作りをしている会社とそうでない会社を比較したときに求職者がどちらを選ぶかは自明です。 また、改善されたソフトウェアを学び続けることは、新しい知識・概念、コードの書き方の習得などエンジニアの技術力の向上にも繋がります。

自分たちでアップデートをする理由

いつも自分たちが一人一人責任を持ってコードを書いてサービスを改善していると思います。 では、そのサービスは何でできていますか?そこには自分たちが実際に書いたものだけではなく、自分たちが考えて検証して導入したソフトウェアもありますよね。 すなわち、ソフトウェアはサービスを構成するための1つであり、一人一人が責任を持って導入したものなのです。 自分たちが実際にコードを書いて作った物は改善するのに、自分たちが考えて検証して導入したソフトウェアを自らアップデートしない理由はありませんよね? 逆に言うと 自らメンテナンスできない・メンテナンスする意思がない ソフトウェアを導入すべきではないのです。

いつアップデートするか?

人が採用されたらやりますか?まず、そんなに都合よく人は来ません。 時間ができたらやりますか?その時間は永遠に来ません。

細かくアップデートをする理由

ソフトウェア開発には「ビックバンリリースを避けるべし」という言葉があります。 これは大きなリリースを行うと影響範囲が大きくなりトラブル発生時の調査などが困難になる・エラー(トラブル)が出やすくなるという問題があります。 小さく修正、レビュー、テスト、リリースを繰り返して、影響をできるだけ小さくするため細かくアップデートを行う必要があります。 また、ビックバンリリースをするには時間がかかります。上記で述べた通り時間ができたらやるということは不可能なのです。

まとめ

ソフトウェアを定期的に自ら細かくアップデートを行うのは 開発プロセスの1つ あり、で エンジニアの責務の1つ です。 誰かがやるのではないです。自らが責任を持って行う必要があります。

大阪旅行の帰りで「自分のエンジニアとしての遊びが減ってた」ことに気づく

この連休は大阪の友人夫婦に「ご飯行くぞ!」って突然予定をあけてもらって、夫婦で大阪に行って色々話をしてきた。 4人とも前職の知り合いで大変な時期を一緒に働いてたのでその頃に話に花を咲かせつつ、 お互いにこれからどうしようかねーとか色々話してた。

帰りの新幹線の中で考えていて、特にこの2〜3年はライフスタイルの大きな変化があったので、今までの優先事項と全く違う優先事項を置いていた。 この優先事項は今も変わってほぼ変わって無くて、これを変えるイメージもあんまりできてない。

  1. 二人で生活をする上でまとまった額のお金が必要
  2. 日曜日はフルに家族に使いたい
  3. 土曜日は自分の健康のため(病院、カイロプラクティックやらテニス)に使いたい
  4. 家族の都合上、仕事ではフルリモートが必須だった
    • 今は家族の都合上というよりは自分のためにフルリモートの方が嬉しい
    • 元々移動という行為に価値を感じない
    • オン・オフでの仕事を経験してるけど、自分がやってることはオフィスだろうが家だろうがほぼ変わらない。ドキュメント書いて、コード書いて、Slackでコミュニケーションをする
      • 「個人情報の取り扱いで」で外部ネットワークからアクセスできないので、出社せざるを得ないと言うことはあった
    • 無駄に体力が削られる満員電車の意味がわからないし、移動時間はなぜか勤務時間扱いじゃないし、家の仕事部屋を整えてしまったので家の方が仕事は集中できる

色々落ち着いてきたこの1年は仕事とプライベートと個人の時間の使い方に違和感を感じることがあって、「インプットが単調で遊びを増やしたい」という感覚があるのが結構自分の中で危機感を感じている。 例えば、ある仕事で課題があってその課題の回答の解き方は「たぶんこの方法が一番早く解決できて、まぁそこそこの結果を生めるんだろうなぁ」となってしまってる。 仕事としては期間やお金やいろいろな制約がある上での判断でそれで結果が出てるからいったんはよいのかもしれない。

上記で「違和感を感じることがある」が、前と状況が変わってるから「違和感」になるだけで、それが実は当たり前なことかどうか判断基準も持てていない。

でもそれは遊びがなくて、ライブラリのこのオプションなんだ?とか、AWSのこのサービスなに?とか、この言語の方向性とかどうなっていくんだろう?というそういう寄り道や遠回りをすることが極端に減ってる。 知の高速道路を通るのは正しいんだけど、自分の中ではプログラミングは遊びの延長線からスタートしてるので、仕事という形に変わったとしても、寄り道して回り道して、迷子になって、変なところにぶち当たったとしても楽しんで行きたい。 このあたりはもう少しいい時間の使い方をしたいとずっと思ってるんだけど、いい案が出てこない。

また、インプットと同様に「アウトプットも単調で遊びがない」とは思う。 機能を追加するときにどこまで考えるか?という幅だったり、こっちの方がより言語特性生かせるとか、実際に役に立つかどうかはともかくとして、話のネタとして。 自分の経験や知見が世の中にだして その方向があってるのか?という確認することもできてない。 形が個人のブログなのか勉強会なのか、(結局実現しなかったけど)副業でエンジニアの壁打ちや相手パフォーマンスチューニングになるのかよくわからないけど。 もう少し世の中と接点を持っていきたいなとは思う。

正直この辺はみんなどうしてるんだろう?もちろん全員の話が自分に当てはまるとは思ってないけど

ATH-M50xSTS-USB + Macでサウンドの左右バランスが崩れる問題の解決?

ATH-M50xSTS-USBを24bit 96kHzで使っていて、音声も非常によくて最初は満足してた。

www.audio-technica.co.jp

朝一にMacを開いてミーティングをしようとしたら片側から大音量が

左右バランスがおかしい

左右バランスと音量が崩れていた。まぁバグかなーと思って中央に戻して使ってた。 お昼から返ってきてまたミーティングをしようとしたら今度は逆側から大音量が。 と言うのをずっと繰り返してた。

他のMacでも再現するか?

仕事用のMacBook Airで発生していたので個人で持っているMacBook Proで試した。そうすると再現する。 MBPはUSBが3ポートある1ポートにさして、左右バランスを中央に戻して同じポートに指すとそのままだけど、他のポートに指すと再現する。

USB TypeC へ変換するプラグインの故障

他のを試したけど再現する

ヘッドフォンの故障?

サポートに連絡をして一度検査をするために送った。結果として問題は無かった。そしてヘッドフォンにはバランスなどを変更する信号が送られていないらしい。何か回避方法とかない?とか聞いてみたけど、Mac側の問題だからどうすることもできないとのこと。それはそう〜〜 サポートにはかなり丁寧に対応してもらった大感謝...

Macの問題?

Appleにチャットで問い合わせをした。チャットに繋がるのに30分。状況を説明した後にリアクションが来るまでに30分。いきなり気づかないうちに切断されて、別の人に変わって最初から説明し直すのに30分とずっと同じ話をしてた。チャットの会話履歴見てたけど完全にキレてた。 で、最後に技術に明るい人と電話と画面共有でサポートしてもらった。USBとかハードウェア方面とかに詳しい人だったみたい。

「かいつまんで説明すると相性の問題」

2023年にこの言葉を聞くとは思わなかった。自分も詳しいわけではないし正しい解釈をしているかわからないけど、USBをMacに指したり、ロックから解除するときに認識させるために電気を流しているらしい。このときにほんのわずかに熱が発生するらしく、これが何らかの原因を起こしているとのこと。

まじかーー

解決案

お礼も込めてオーディオテクニカのサポートの人に連絡を取ると「セルフパワー型のUSBハブならば解決するかもしれない」とのこと。なにそれ?と思ったけど、電源が安定して行ってるんだろうなと解釈。

とりあえずサンワダイレクト品を購入。Mac - USBハブ - ヘッドホン としててこれだと、ロック画面から復旧しても再現しない!解決じゃん!!勝った!!!

macOS Sonoma

OSアップデートしたらUSBハブがなくても再現しなくなった気がする(ちょっと様子見)

まとめ

(おことわり)あくまでも個別事象です。

  • まずはOSをSonomaにする
  • セルフパワー側のUSB経由でつなげる

ぼくのかんがえたさいきょうのRubyMine(JetBrains IDE製品)のSQLコードスタイル設定ができた

モチベーションとしては生のSQLを結構書く機会があるが、いまいち自分の中でしっくりこない部分がある。 これは製品の善し悪しではなく今まで教えてもらった書き方とか、Gitでdiff取ったときにコードの差分が少ないとかが背景にある。

IDEのデフォルト設定(たぶん)

インデントが4だったり、select句の最初の項目やwhere句の最初に改行がほしかったり、exists句のJOINが変なところにあったりする。 結局こうした

結果

本当はJOINの中のサブクエリにインデントをつけたりしたかったがサブクエリ周りはいい感じの調整ができなかった。 主な変更点は

  • インデントを2
  • select句,where句の最初の項目に改行
  • join句のonは継続的インデントを設定
  • case 文のendの前に改行

たぶん人によってはselect句の各項目の前にカンマ付けたり、onにインデントをつけないとかあると思う。 この辺のSQLのコードスタイルなので完全に好みです

コードスタイルのXMLファイル置いておきます。今の設定を一度複製してそれに対してインポートするとよいです。 差分更新ではなく、デフォルト設定に対して全上書きされるので、自分の設定を一度XMLにエクスポートして code_scheme の中の属性をマージしてインポートすると安全だと思います

<code_scheme name="Custom" version="173">
  <SqlCodeStyleSettings version="6">
    <option name="QUERY_ALIGN_ELEMENTS" value="false" />
    <option name="SELECT_EL_LINE" value="101" />
    <option name="FROM_INDENT_JOIN" value="false" />
    <option name="FROM_ONLY_JOIN_INDENT" value="1" />
    <option name="FROM_PLACE_ON" value="12" />
    <option name="WHERE_EL_LINE" value="101" />
    <option name="WHERE_EL_BOUND" value="0" />
    <option name="EXPR_CASE_END" value="1" />
  </SqlCodeStyleSettings>
  <codeStyleSettings language="SQL">
    <indentOptions>
      <option name="INDENT_SIZE" value="2" />
      <option name="CONTINUATION_INDENT_SIZE" value="2" />
      <option name="TAB_SIZE" value="2" />
    </indentOptions>
  </codeStyleSettings>
</code_scheme>