雑なメモ書き

気楽にいきます

golangのginでcontextをどう扱うべきだろうか

公式でのContextの扱いの解説

Incoming requests to a server should create a Context, and outgoing calls to servers should accept a Context. The chain of function calls between them must propagate the Context, optionally replacing it with a derived Context created using WithCancel, WithDeadline, WithTimeout, or WithValue. When a Context is canceled, all Contexts derived from it are also canceled.

サーバーへの着信要求はコンテキストを作成する必要があり、サーバーへの発信呼び出しはコンテキストを受け入れる必要があります。それらの間の関数呼び出しのチェーンは、コンテキストを伝播する必要があり、オプションで、WithCancel、WithDeadline、WithTimeout、またはWithValueを使用して作成された派生コンテキストに置き換えます。コンテキストがキャンセルされると、そのコンテキストから派生したすべてのコンテキストもキャンセルされます。

  • 本来引き回すべき物であって
  • 何かしら別の要件があった場合
  • cancel,deadline,timeout,withValueなどで派生コンテキストに置き換えるべきで
  • そのまま引き渡す方がいいに見える

gin.Contextのよくある扱い

  • 公式ではこのような例がある
package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    r.GET("/ping", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "message": "pong",
        })
    })
    r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
  • ここから関数を呼び出すときどうすべきなのだろうか
  • 例えば以下の様なメソッドを上記に追加した場合
func myMethod(ctx context.Context) {

}
  • c.Request.Context()を渡すべきなのか
myMethod(c.Request.Context())
  • gin.Contextをそのまま渡すべきなのか

gin.Contexを確認する

  • engine.Newをしているここにある
func New() *Engine {
    debugPrintWARNINGNew()
    engine := &Engine{
    engine.pool.New = func() interface{} {
        return engine.allocateContext()
    }
    return engine
}

allocateContext

func (engine *Engine) allocateContext() *Context {
    return &Context{engine: engine, KeysMutex: &sync.RWMutex{}}
}

ServeHTTP

  • これがリクエスト単位で呼び出されている
289 // Conforms to the http.Handler interface.
290 func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
291     c := engine.pool.Get().(*Context)
292     c.writermem.reset(w)
293     c.Request = req
294     c.reset()
295
296     engine.handleHTTPRequest(c)
297
298     engine.pool.Put(c)
299 }
  • このpool.Get()で呼び出されている
  • これの正体は
engine.pool.New = func() interface{} {
    return engine.allocateContext()
}
  • allocateContextなので
  • 毎回このこのコンテキストは割り当てられている
  • なので問題なさそうにみえる
  • 呼び出し単位で扱って良いように見える

rustのcreateのメモ

cargo edit

https://crates.io/crates/cargo-edit

 cargo install cargo-edit
  • こちらが使えるようになる
  • carog.tmolいじらなくて済む
cargo add
cargo rm
cargo upgrade

clippy

  • 所謂linter

https://github.com/rust-lang/rust-clippy

rustup component add clippy

cargo fix

doc.rust-lang.org

  • editionを更新する場合は以下のオプション
cargo fix --edition

ストレスな状況下でも嫌な展開にならずに気楽に見ることが出来るおすすめ漫画

新型コロナ騒ぎで世の中が鬱々としているので、 自分が読んだ中で鬱な展開にならずにお気楽に読める漫画を並べておきます。

異世界おじさん

異世界おじさん 1 (MFC)

異世界おじさん 1 (MFC)

乙女ゲームの破滅フラグしかない悪役令嬢に転生してしまった

ゆるキャン△

保安官エヴァンスの嘘

まったく最近の探偵ときたら

痛いのは嫌なので防御力に極振りしたいと思います。

緊急事態宣言が出た時にやったストレス対策(2020/04)

新型コロナウイルス感染症(COVID-19)の影響で緊急事態宣言が4/7にでました。

corona.go.jp

それに伴いまして、3蜜を避ける為に企業が出勤禁止の対応を行いました。 その為、自宅で作業するテレワークへ業務が移行。

当初2週間ほどはそこまでストレスも感じなかったのですが

note.com

こちらの記事にあるように、最初は元気でもそのうち段々元気がなくなってきました。

要因として考えたのは、

  • 緊急事態宣言の影響で映画は公開延期
  • 気楽にどこかへ食べに行ったりすることも出来なくなった
  • 仕事関係の業務運用がテレワークになってガラッと変わったこと
  • 在宅で長期間一人でやるという環境を作れていなかったのが大きかったと思います。

付け加えるなら、毎日のようにニュースで感染症の不安を煽るような内容を聞いていたのもいけ無かったのでしょう。

それで、対応として以下をやってみました。

  • 運動不足が深刻だったので朝と夜に近所を散歩
  • 部屋の換気
  • ニュースを聞く回数を減らした
  • 環境音を流すようにした

特に環境音はかなり効果的で以下の物はおすすめです

www.youtube.com

www.youtube.com

中々特殊な状況なので忘れないようにメモしておきます。

GDBFrontendというグラフィカルにgdbでdebugできるツールをrustで試してみた

GDBFrontendの場所

github.com

立ち上げ方

gdbfrontend

こんな感じでWebServerとして立ち上がります

f:id:hiroyukim:20200224224200p:plain

接続方法

  • 画面下にコンソールが立ち上がっています
  • ここへ以下で実行した結果を貼り付けます
#!/bin/sh

TARGET_PATH=$1
DEBUG_SRC=`strings $TARGET_PATH  | grep -o '/rustc/[^/]\+/' | uniq`
RUST_SYSROOT=`rustc --print sysroot`
echo "set substitute-path $DEBUG_SRC $RUST_SYSROOT/lib/rustlib/src/rust/"
  • その後breakpointを設定して
  • runを実行すれば次のような画面が出てきます
b main

run

f:id:hiroyukim:20200224224916p:plain

  • かっこいいですね。
  • xオプション渡せる方法誰か教えてください。

作りたくない一時ファイルを作らずにvimの力を借りたい(1)

なにかvimの力を借りて整形したい

  • 例えばRustのコードを別の箇所に貼るとき
  • とんでもなくインデントが深いコードを整形したい
  • あると思います
                    struct User {
                        username: String,
                        email: String,
                        sign_in_count: u64,
                        active: bool,
                    }
  • これをこのまま貼りたくないですよね
  • なのでvimを使って整形します
vim a
  • shift + < とかで頑張って調整します
  • もしくは、xxxfmtとかあればそれが頑張ってくれるはず
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

a つくりたくないよね?

  • そこでvim-jpの方々に聞いてみました。

そのプログラムがファイル開いて stdio で喋れるのなら::%!/path/to/program みたいなのでカレントバッファを流し込んむとか (よくやるのが JSON の整形で :%!python -m json.tool)

どういう意味なのか?

  • :%! で対象プログラムを指定すると
  • 現在の位置より下のbufferから流し込むことができる
  • 便利です。
  • また一ついいことを覚えました。
  • ありがとうございます。

ただ、僕が要望をうまく伝えられてないのでまだ終わっていない

  • 多分僕はaを作りたくなかった
  • tmpで編集できて邪魔にならない感じのファイルが欲しかった
  • vimよくわからないからこんな感じで書いてみたけど
  • 全然駄目でした。
:%! cat `tempfile`

次回に続きます。

参考になりそうなURL