Screaming Loud

日々是精進

2023年振り返り

去年の振り返りはこちら

yuutookun.hatenablog.com

ブログを書くのが年の瀬だけになってしまいました。 今年もやっていきます。

仕事

マネージャーになった

2019年夏くらいから4年くらいリードエンジニアをやらせてもらっていましたが、ジョブチェンジをしてエンジニアリングマネージャーをやらせてもらいました。 正式には8月からやっていたのですが、マネージャー業務の引き継ぎとかでその前から実質業務はやっていました。

正式マネージャーになる前ではありますが、チームにおいての考え方とかを記事に書いたりもしてました。

tech.gunosy.io

あとはkubernatesの障害対応とかのためにOSSを作って対応したりもしてました。

tech.gunosy.io

広告部門からLLM部門へ

ちょうど今月12月から新卒から現職まで10年間ほどやっていた広告部門から新規事業のLLM部門に異動しました。 ずっと広告をやっていたのですが、LLMのようなインパクトのあるテクノロジーにチャレンジする機会を会社から頂いたので、異動を決めました。

広告チームから離れるのは心残りではあったのですが、チームメンバーもすごく成長してくれて、安心して任せられるチームとなったので今は心強いです。 マネージャーとしてもうれしい限りです。

LLM部門としてはこちらをやっていきます。

udekiki.jp

こちらでは、また実装をガンガンやっていっています。

プライベート

家買った

プライベートが直近は結構忙しくて、というのも家(中古マンション)を買いました。 ずっとコロナに入ってから賃貸で広いところを探していたのですが、条件にマッチするところがなくついに購入に舵を切りました。 賃貸で猫2匹を飼える物件が少なすぎたり、あっても申し込みが殺到してて全然内見までたどり着けなかったり、飼えても家賃が高すぎだったりで無理でした。

購入に際してよい物件を見つけたので、とてもよかったです。 ただ検討段階では考えていなかったリフォームを実施することになり、考えることがめちゃくちゃ増えてかなり忙しかったです。

キッチン解体後

まだリフォーム中で引越しはまだですが、新居が出来上がるのを眺めているとワクワクです。

引越して猫たちは慣れてくれるかな。

洗濯機の中のねこ

運動

コロナ明けて久しぶりにフットサルもやりました。

引き続きテニスもやってます。 大会とかで勝ってみたいですね。

まとめ

今年は環境が色々変わった年でしたが、ポジティブな変化が多い一年でした。 来年もやっていき!!

2022年振り返り

去年の振り返りはこちら

yuutookun.hatenablog.com

って載せながら、今年はブログを全く書いてなかったので前回の記事が去年の振り返りになってますね。。

仕事

今年の大きなトピックとしては、大きなコスト削減施策を実施しました。

tech.gunosy.io

tech.gunosy.io

またその結果が評価され、全社MVPとして表彰していただけました。 昨年はエンジニア部門として表彰されましたが、今年は全社MVPとしての表彰で初めてだったのでうれしかったです。

gunosiru.gunosy.co.jp

他にはRailsの一部の画面をモブプロで書き換えるプロジェクトを実施していました。 下記のブログはその一部の話なんですが、そもそも修正対象画面に大量のフォームが存在していて、 チームでも何をする設定なのかを知らないものがいくつもありました。 おかげでドメイン知識をチームみんなにインストールできたというのは大きな収穫でした。

tech.gunosy.io

個人的にはモブプロで一番良かったのは、結合テストでした。 結合テストって網羅的にテストを実行する必要があり、テストが失敗したときに自分の操作を単純にミスったのかほんとにバグが発生しているのか不安になることが多く、 精神的に結構つらい(みんなはどうなんだろう?)のですが、みんなで並列で実施するとテストの失敗した人数的にバグってるかどうかが確認しやすいのが良かったです。

それ以外でいうとチームメンバーにテックブログを率先して書いてくれるようになって、チームでのブログ執筆率が高かったことです。 チームのアウトプットが増えるのは誇らしいですね。

また、リードエンジニアになってから技術1on1という施策をずっと実施しているのですが、 おかげさまでやってほしいという声を頂いて1on1を実施する人数が増えてきました。

あとは結構大変だったことの一つでエンジニアの行動指針を作るというのを実施していたのですがこれがすごく大変でした。 というのも、何をもってできると評価するのかというのはすごく難しく、単純な表層のスキルだけだとすぐ陳腐化してしまうので、 根っこの行動する基準みたいなものがどうあるかを評価したい、でもそれって外から観測できないから評価できないのではないか、 などという堂々巡りが発生していました。

tech.gunosy.io

一応無事?第一弾は作成完了したのですが、改めて評価の難しさを認識しました。

今年も一年お疲れさまでした。

ねこたち

2021年振り返り

去年の振り返りはこちら

yuutookun.hatenablog.com

仕事

今年は広告のシステムを全部見るようになりました。

引き継いだシステムが結構速報とかでスパイクリクエストが多くてアラートが鳴りがちで、以下のような対応とかしてました。 今年は結構ここらへんの対応が多かったですかね。

tech.gunosy.io

去年あたりから始めた失敗共有会の「はにびぶ会」ですが、どんなふうにやってどこらへんが困ってるかなどをブログに残しました。 勉強会運営って結構モチベーション維持が大変なので、もっと楽に運営していきたいなぁと思ったり。 こちらは社内勉強会ですが、社外で勉強会開催してるってすごいエネルギーが必要だと思うので、すごいと思います。

tech.gunosy.io

あとはHudiなどのデータレイク周りに手をいれたりしました。 GlueSparkをちゃんと本番にリリース、運用したのは初めてだったのでよい経験でしたね。 ずっとHudiを本番で使ってみたいなぁという気持ちがあったので、使えてよかったなぁと思ってます。

tech.gunosy.io

あとは終盤コロナが明け始めて月1くらいで出社をするようになりました。 会社がWeWorkなので、午後5時以降生ビールが飲み放題なので、コミュニケーションの起点になっててよいなぁと。

また技術1on1なるものをリードエンジニアになってからメンバーとやってるのですが、その範囲が増えてきたりしました。 コロナ前に始めたんですが、リモート環境で会話機会が少ないのをカバーする役割に運良くなりました。

あと、今年は締め会でエンジニアとして表彰されました。 こういう表彰は久しぶりでもあったので新鮮でうれしかったのと、 チームメンバーの頑張りのおかげでもあったと思うので、 さらにチームのチカラを上げていけるように尽力していこうと思います。

プライベート

テニスの頻度がすごい増えました。 昔のテニスを仲間が続々とテニス復帰していてそのおかげでやる頻度が増えました。 上手くはなってるんですが、周りも一緒にうまくなっているので、やっぱりまだまだだなぁと思うことのほうが多いですね。

あと引っ越しをしようとして物件を探してますが、猫2匹を飼える家で今より広い家を見つけるのがすごい大変で苦戦しました。 絶賛探し中です。

まとめ

来年もやっていきます。

Goで重い処理をtimeoutさせる ~その2~

前回はGoでtimeoutさせる処理に関して書きました。

yuutookun.hatenablog.com

しかし、前述の記事で書いているのはレスポンスが返らない場合でした。 多くの場合、レスポンスが必要だと思うので、レスポンスを付与するパターンを紹介します。

functionの返り値が値とエラーの二つになっていますが、ここは type result を変更すれば増やすことができます。 ただ、レスポンスをstructにしておけば、このメソッドで事足りると思います。

流れとしては、

  1. 引数の関数の結果格納用のチャネルを作成
  2. goroutineで引数の関数を実行。結果はチャネルに。
  3. for ループのselectでcontextを監視して
  4. チャネルに結果が入れば、結果を返す
  5. context.Doneになれば、空の結果を返す

という感じです。 responseのresultは汎用性のために interface{} で定義しています。

関数終了前にcloseしたりすると、内部でpanicが発生してしまうので、チャネルのcloseに関しては goroutineの終了と一緒にcloseしてます。

以下実際のコードになります

var FailedGetChannel = errors.New("failed to get Channel")

type result struct {
    value interface{}
    err   error
}

func main() {
    f := func() (interface{}, error) {
        time.Sleep(10 * time.Second)
        return []int{1, 2, 3}, nil
    }
    ctx, cancel := context.WithTimeout(context.Background(), 2 * time.Second)
    defer cancel()
    inter, err := ExecWithContext(ctx, f)
    if inter == nil { // interがnullだとcastでpanicになるため
        fmt.Println(err)
        return
    }
    fmt.Println(inter.([]int), err)
}

// ExecWithContext f()の結果をcontextキャンセルされるまで待つ
func ExecWithContext(ctx context.Context, f func() (interface{}, error)) (interface{}, error) {
    resultCh := make(chan result) // f()の実行結果を入れるresult チャネル

    go func() {
        defer close(resultCh)
        resultCh <- func() result {
            i, e := f()
            return result{value: i, err: e}
        }()
    }()
    return waitResult(ctx, resultCh)
}

// contextがtimeoutになるまでchannelの結果が返るのを待つ
func waitResult(ctx context.Context, ch chan result) (interface{}, error) {
    var i result
    for {
        select {
        case <-ctx.Done():
            return i.value, ctx.Err()
        case i, ok := <-ch:
            if !ok {
                return nil, FailedGetChannel
            }
            return i.value, i.err
        default:
        }
        time.Sleep(1 * time.Millisecond)
    }
}

実際のplaygroundは以下です。

Go Playground - The Go Programming Language

追記

ライブラリとして公開しました

github.com