ブックマーク / blog.utgw.net (12)

  • linterを導入していなかったプロジェクトにlinterを導入しようとするときにまずやること - 私が歌川です

    今どきlinterを使っていないプロジェクトなんて、と思われるあるかもしれませんが、歴史の長いプロジェクトだとそういうこともあるでしょうし、あるいは一部のDSLやスキーマ*1に対してのみlinterを走らせたいということもあるでしょう。 そういったプロジェクトに対してlinterを導入する前に、デフォルト設定でlinterを走らせたときにどういう出力になるのかを一通り眺める、というのをやっています。 どういうエラーがどこで何件出ているのか、warningなのかerrorなのか、linterのルールがプロジェクトにとって妥当なのか、一通り吟味した上で設定を調整してからlinterを導入するようにしています。なぜなら、linterのノイズが多いとlinterの言うことに従うモチベーションが下がる (と自分では思っている) からです。 最初からlinterが入っているなら、とりあえずlinter

    linterを導入していなかったプロジェクトにlinterを導入しようとするときにまずやること - 私が歌川です
    toshikish
    toshikish 2023/05/25
  • DBスキーマからGoのstruct定義を生成するグッズを書いた - 私が歌川です

    GoSQLを書いて実行するとき、素のdatabase/sqlだけだとさすがに心もとないのでsqlxなどのライブラリを使ってDBの行をstructにマッピングすると思います。db struct tagでマッピング元のカラム名を指定できるのが便利ですね。 一方で、このstructを定義する作業ですが、テーブルのカラムが多いと大変だし、typoしていたので直して再チャレンジする……ということが往々にしてあると思います。 こういうときのためにstruct定義を生成するツールを書いてみました。 go install github.com/utgwkk/rowstructgen@latest を実行したら使えるようになると思います。今のところMySQLにしか対応していません (普段はMySQLしか使っていないため)。main.goに全ての実装が書いてあってひどい感じなので、気が向いたらなおします。

    DBスキーマからGoのstruct定義を生成するグッズを書いた - 私が歌川です
    toshikish
    toshikish 2023/05/01
  • 有効期限を過ぎても消えないインメモリキャッシュの謎 - 私が歌川です

    tl;dr キーワードは「monotonic clock」です。 あらすじ Goで以下のようなコードを書いていた*1*2。あるAPIを叩くクライアントで、APIコールに必要なアクセストークンを4時間キャッシュしている。c.getToken() で得られたトークンを使ってAPIコールを行えばよい。 type Client struct { mu sync.RWMutex expiresAt time.Time token string } // トークンのキャッシュがあればキャッシュから返し、なければ更新してから返す func (c *Client) getToken() string { if cachedToken, ok := c.getTokenFromCache(); ok { return cachedToken } return c.refreshToken() } // トー

    有効期限を過ぎても消えないインメモリキャッシュの謎 - 私が歌川です
    toshikish
    toshikish 2023/02/24
  • GitHub Actionsで「matrixの全テストが通らないとマージできないようにする」設定を簡単に行う方法 - 私が歌川です

    GitHub Actionsで、複数環境でテストしたいのでmatrixに分けて、branch protectionの設定で全環境のテストが通ったらmasterにマージ可能にしましょう、というのをやろうとするとちょっと面倒です。 matrixの数だけ必要なstatus checkに含めないといけない jobの名前を変えたときにrequired status checkの設定も追従させないといけない? (未確認) 「なんか一生CI greenになりませんね」的なことになりそう jobの名前を途中で変えたら選択肢がめちゃくちゃ出てくる gyazo.com 全部のテストに通った、というのを1つのstatus checkで表現したいので、以下のようなjobを追加しました。 needs: test にして、 test jobが全てpassしないと作動しないようにする 1つでもテストが落ちたらcance

    GitHub Actionsで「matrixの全テストが通らないとマージできないようにする」設定を簡単に行う方法 - 私が歌川です
    toshikish
    toshikish 2023/02/22
  • Recoilとwebpack.DefinePluginと環境変数の名前 - 私が歌川です

    これは React Advent Calendar 2022 7日目の記事です。 Recoilを使っているアプリケーションでWebpackのDefinePluginを使って環境変数の値をビルド時に埋め込むとき、Webpackの設定によっては環境変数の名前がビルドしたコードに含まれてしまう場合があります。 具体的には、以下のようにDefinePluginの process.env キーに対してobjectを渡す場合に発生しえます。 new webpack.DefinePlugin({ 'process.env': { FOO: JSON.stringify(process.env.FOO), }, }); ここでRecoilのコードを見てみましょう。ランタイムに process.env の値を参照するコードがあるのに気づくと思います。 github.com optional chaining

    Recoilとwebpack.DefinePluginと環境変数の名前 - 私が歌川です
    toshikish
    toshikish 2022/12/08
  • ISUCON12 チーム :old_noto_innocent: で予選突破した #isucon - 私が歌川です

    今年も id:nonylene id:wass80 と出場しました。最終スコアは50,696点で予選突破できました。分析基盤 (Kibanaやプロファイラ) に流れてきたデータを見つつ作戦を立てて実装する、という流れがうまくはまって順調にチューニングを進められたのがよかったと思います。 最終的なサーバー構成 isuports-1 App (Go) nginx isuports-2 DB (MySQL, player_scoreのみ) isuports-3 DB (MySQL) やったこと リポジトリはこちらです。 github.com 分析基盤まわりの話を id:nonylene が書いてくれたので、こちらもあわせてどうぞ。 nonylene.hatenablog.jp id:wass80 視点の記事もあるので、こちらもあわせてどうぞ。 memo.wass80.xyz テナントごとのDB

    ISUCON12 チーム :old_noto_innocent: で予選突破した #isucon - 私が歌川です
    toshikish
    toshikish 2022/07/24
  • 味玉のレシピをMakefileで記述する - 私が歌川です

    最近よく味玉を作っているのだけど、ジップロックに日付を記入し忘れたり、ボウルに水を入れてから氷を入れようとしたりしていて、手順の依存関係を意識しないとめちゃくちゃになる。 Makefileは依存関係と成果物を記述できるので、レシピをMakefileの形で書いたらおもしろいのでは、と思ったけど記述量が多い気がする。 .PHONY: お湯を湧かす 卵を茹でる 8分待つ ボウルに氷を入れる ボウルに水を入れる ボウルに卵を入れる 卵の殻を剥く ジップロックに日付を書く ジップロックにめんつゆを入れる ジップロックに卵を入れる 一晩寝かせる 味玉 お湯を湧かす: @echo お湯を湧かします 卵を茹でる: お湯を湧かす @echo 卵を茹でます 8分待つ: 卵を茹でる @echo 8分待ちます ボウルに氷を入れる: 8分待つ @echo ボウルに氷を入れます ボウルに水を入れる: ボウルに氷を入れ

    味玉のレシピをMakefileで記述する - 私が歌川です
    toshikish
    toshikish 2022/06/22
  • ペアプロ活動パターン - 私が歌川です

    仕事でよくペアプロでコードを書くのですが、気をつけていることがいくつかあるので共有します。みなさまは何に気をつけていますか? 考えていることを声に出す やりたいことが実現できずに詰まっていると黙りがち どうやったらいいか分からず困っている・違う結果になる、みたいなのを口に出す ペアの人が解決方法を知っているかもしれない クマさんデバッグみたいな効果もありそう ところで「クマさんデバッグ」って一般に通じる言葉なんですか? 書いているコードの自己評価を行う 最高のアルゴリズムになった、とか、これは一時しのぎです、みたいな 認識がずれていないかの確認をする 「こう思っているけどそれで合ってますか?」 こまめにcommitする こまめにセーブするイメージ git diffを確認したら、どこまでできているのかを見れる いざとなったらgit resetで戻れる ひと通りできあがってからちょっとずつco

    ペアプロ活動パターン - 私が歌川です
    toshikish
    toshikish 2021/06/07
  • GitHub Actionsを使ったDDoSに巻き込まれた - 私が歌川です

    事例集です。 きのう、GitHubの通知を見たら、個人のリポジトリに My First PR というタイトルのPRが来ているのに気づいた。PR出すところを間違えたのかな、と思って見てみたがどうも様子がおかしい。 prog という名前のバイナリファイルを置いている .github/workflows/ci.yml*1の中身をガッと書き換えている on: [pull_request] でworkflowを起動している 20並列でjobが走るようにmatrixを設定している fail-fast: false なので、どれか1つのmatrixが失敗しても他のジョブは続行される base64 encodeした文字列をdecodeしてevalしている ドメインの名前解決を行ったあと ./prog を実行するコマンドにdecodeされた PRをめちゃくちゃな回数closeしてreopenしている PRを

    GitHub Actionsを使ったDDoSに巻き込まれた - 私が歌川です
    toshikish
    toshikish 2021/02/05
  • MySQLのEXPLAINが直感とは異なっていた事例 - 私が歌川です

    おもしろかったのでメモ。 CREATE TABLE `tbl` ( `id` BIGINT UNSIGNED NOT NULL, `done` BOOLEAN NOT NULL DEFAULT FALSE, PRIMARY KEY (`id`), KEY `done_and_id` (`done`, `id`) ); tbl テーブルに done = FALSE で100万行INSERTしておく SELECT id FROM tbl WHERE done = FALSE ORDER BY id ASC LIMIT 50 でidを順に集める 処理する UPDATE tbl SET done = TRUE WHERE id IN (...) で処理済にする これを done = FALSE な行がなくなるまで繰り返す KEY `done_and_id (`done`, `id`) ありでEXP

    MySQLのEXPLAINが直感とは異なっていた事例 - 私が歌川です
    toshikish
    toshikish 2020/10/24
  • ふだんの開発でPRを出すときに考えていること - 私が歌川です

    業務の話です。OSSとかだとまた変わってくるのかもしれないし、共通することもあるかもしれません。 先に作戦を練る 実装する前に、方針段階でレビューしてもらえるとよい 自分だけでは気づけない考慮漏れとか、こういう方針もあるよっていう提案とか、いろいろ得られるものがある 先に実装完成させてから、これでは要件を満たせない・うまくいかないねってなるともったいない 巨大なPRにしない diffの大きさについては、プログラミング言語とか、利用するフレームワークによっても変わってくるので、一概には言えなさそう +1500, -1500 だけどスナップショットの更新があったとか インデント1つ下げることになったとか たとえば、あらゆる機能を1つのPRで実装してたら巨大なPRになると思う 1つのPRであらゆるものを実装しない、1機能ずつ実装するとか、1つの層だけ実装する、とか PRが巨大だと、コミュニケーシ

    ふだんの開発でPRを出すときに考えていること - 私が歌川です
    toshikish
    toshikish 2020/10/09
  • ふだんの開発で小さなPRに分けるために考えていること - 私が歌川です

    ふだんの開発でPRを出すときに考えていること - 私が歌川です の続編です。小さなPRを出す、という話がありましたが、どうやって小さくしているのか、というのを書きます。 どういうメソッドが欲しいか考える Aという情報をBという画面に出したい Aを取得するメソッドがないので、それを作る必要がある (メソッドCとする) というときに、メソッドCを作るPRをまず先に出して、マージされたら続いてCを使って得られる情報Aを画面Bに出すPRを出す、というのをやります。 実装方針を考えて既存実装を眺めてからそういう作戦を立てることもあれば、実装しているうちにメソッドCが足りないな、と気づいて別ブランチでPRを作ってそちらを先に出す、ということもあります。 このとき、1つのPRで両方やろうとすると、メソッドCの実装のレビューと、情報Aを画面Bに出す実装のレビューが同じPRで行われることになります。メソッド

    ふだんの開発で小さなPRに分けるために考えていること - 私が歌川です
    toshikish
    toshikish 2020/10/09
  • 1