私は人類の考へた事を collection するのを趣味としてゐるが、桃山の古本市場でこの本を捲ってゐて、
「アイスブルー」と言って植物に触れると、痛みに関する記憶のクリーニングを促すことができます。
と書いた一節を見附け、「壽司 虛空編」だ! と嬉しくなり買った (なにしろ安かった)。「壽司 虛空編」にはこの言葉が出てくるふざけた場面が在る。著者等の意圖には沿はぬだらうが、私にとってこの本はそれだけのものだ。
.。oO(此のblogは、主に音樂と考察と Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)
音樂は SoundCloud に公開中です。
考察は現在は主に Scrapbox で公表中です。
Programming は GitHub で開發中です。
私は人類の考へた事を collection するのを趣味としてゐるが、桃山の古本市場でこの本を捲ってゐて、
「アイスブルー」と言って植物に触れると、痛みに関する記憶のクリーニングを促すことができます。
と書いた一節を見附け、「壽司 虛空編」だ! と嬉しくなり買った (なにしろ安かった)。「壽司 虛空編」にはこの言葉が出てくるふざけた場面が在る。著者等の意圖には沿はぬだらうが、私にとってこの本はそれだけのものだ。
adventar.orgの 12/14 (木) です。
ここにエクストラバージンオリーブオイルが在ります。
油です。ものを炒める時に引く油として使へます (香りが飛んで勿體無くはありますが)。頻繁に料理するのでもない限り、或いは揚げ物でも作らなければ、油は中々減りません。長期閒置かれると油も傷みます。傷まない內に使ひ切りたいものです。
ところでエクストラバージンオリーブオイルは、オリーブの實を加熱せずに破碎し遠心分離した果汁です。香り高く滋養の有る果汁 100% juice です。
飮めます。
料理用油としても使へ、パスタの香り附けにもなり、飮めば速やかに減ります。よかったですね。
と、ここで記事を終はりにしようかとも思ひましたが、これでは「おい」てはゐますが「つくっ」てゐません。つくりおきではありません。
では米を炊いて保存してゆきませう。二合炊き、半合づつ冷凍します。
flowchart LR 米を洗ふ --> 浸水["米を 30 分〜1 時閒水に浸す"] 浸水 --> 鍋に入れて蓋をする 鍋に入れて蓋をする --> 沸騰する迄強火 沸騰する迄強火 --> 弱火にして泡が湧かなくなる迄 弱火にして泡が湧かなくなる迄 --> 蒸らす["10 分閒蒸らす"] 蒸らす --> 半合毎にラップに包み冷凍
米二合。
洗ひます。
水 400mL に漬け一時閒置きます。
鍋に入れ蓋をし、強火。
沸騰したら弱火。
水が米に吸われて見えなくなったら強火十秒。
火を止め、十分閒蒸らします。
炊き上がり。
四つに切り、
ラップに乘せ、
包みます。
四つ包み、冷凍します。
電子レンジで解凍すれば食べられます。
米が炊かれてゐれば料理が食事になります。出汁を引けば材料が料理になります。そこで昆布と鰹節の合はせ出汁を 2L 取りませう。
flowchart LR 昆布を2時閒浸水する --> 昆布を煮る["昆布を鍋に入れ、沸騰直前迄煮る"] 昆布を煮る --> 昆布を取り出す 昆布を取り出す --> 鰹節を煮る["鰹節を鍋に入れ、沸騰する迄煮る"] 鰹節を煮る --> 10分置く 10分置く --> 鰹節を取り出す 鰹節を取り出す --> 容器に移し冷蔵庫に入れる
昆布適量。鰹節 2g4 パック。
昆布を水に漬け二時閒置きます。
色。
昆布ごと湧かします。
沸騰する前に昆布を取り出します。色と泡。
鰹節を入れ、
湧かします。
沸騰したら火を止め、十分置きます。
色と濁り。
濾します。
冷藏庫に置き、二週閒以內に使ひます。溫めて味噌を入れれば飮めます。
出し殻は本當に始末に困ります。味はさっき抽出しましたので、これは無味。
昆布は切り刻み、鹽小匙一、味醂大匙一。
唐辛子が在ったので入れます。
水分が飛ぶ迄中火で炒めます。
姿。
ラップして冷藏庫に仕舞ひます。
翌日。昨日炊いて解凍した米、昨日取った出汁適量、味噌、卵。
米に餘熱が有るので、電子レンジで三十秒。混ぜます。
無味は無味。
明日は id:dstn18c さんです。
qiita.comの 12/12 (火) です。
去る 12/2 (土) に Go Conference mini 2023 Winter IN KYOTO で「作ってよかったgraceful shutdownライブラリ」と云ふ事を喋りました。
event report は以下。 scrapbox.io
ここでは喋った事を紹介します。
はてなでは Go を (も) 使って application を作ってゐます。或る時「Go の code は記述量が多い」事が話題になりました。その中の一つに、graceful shutdown を實現するのに、似た code を每囘長々と書いてゐる事が擧がりました。そこで graceful shutdown の記述を改善できないか探索する事にしました。
graceful に起動・終了するとはどう云ふ事か? と云ふ一般論は省略しませう。slide には少し書きました。
滿たしたい條件は以下のものです。
http.ErrServerClosed
を扱ふのを忘れない以下の code で實現します。
package main import ( "context" "errors" "log" "net" "net/http" "os" "os/signal" "sync" "time" "google.golang.org/grpc" ) var shutdownTimeout time.Duration = 10 * time.Second func main() { ctx := context.Background() ctx, stop := signal.NotifyContext(ctx, os.Interrupt) // signal を trap する defer stop() ctx, cancel := context.WithCancelCause(ctx) // net/http の例 srv1 := &http.Server{Addr: ":80"} go func(ctx context.Context) { // parallel に起動する if err := srv1.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { cancel(err) // 起動に失敗したら、異常終了する } }(ctx) // google.golang.org/grpc の例 srv2 := grpc.NewServer() go func(ctx context.Context) { // parallel に起動する listener, err := net.Listen("tcp", ":8000") if err != nil { cancel(err) // 起動に失敗したら、異常終了する return } if err := srv2.Serve(listener); err != nil { cancel(err) // 起動に失敗したら、異常終了する } }(ctx) // 終了処理 <-ctx.Done() if err := context.Cause(ctx); err != nil && !errors.Is(err, context.Canceled) { log.Fatalln(err.Error()) // 起動に失敗したら、異常終了する } ctx, cancelT := context.WithTimeout(context.Background(), shutdownTimeout) // context.Context を新たに生成する。終了處理に timeout を設定する defer cancelT() var wg sync.WaitGroup wg.Add(1) // parallel に終了する go func(ctx context.Context) { defer wg.Done() if err := srv1.Shutdown(ctx); err != nil { log.Println(err.Error()) } }(ctx) wg.Add(1) // parallel に終了する go func(ctx context.Context) { defer wg.Done() stopped := make(chan struct{}) go func() { srv2.GracefulStop() close(stopped) }() select { case <-stopped: case <-ctx.Done(): } }(ctx) wg.Wait() if err := context.Cause(ctx); err != nil && !errors.Is(err, context.Canceled) { log.Fatalln(err.Error()) // timeout したら異常終了する } }
…今見たら、timeout せずにしかし終了處理が error を返した場合に exit 0 してゐますね。まぁ結果的に作った library では、正しく exit 1 しますから氣にしない。
まづ既存の library を探しました。しかし設計が古かったり、net/http server 專用であったり、單一の server した扱へなかったりと、條件を充分に滿たすものは見附かりませんでした。先日話して、皆さん 1. graceful な shutdown を氣にしないか、2. 手書きするか、3. closed source な framework を作るかしてゐさうだと感じました。
見附からなければ作れば宜しいのですから、作りました。
先程の例は、かうなります。複數の server を扱ふので少し冗長ですが。
package main import ( "context" "errors" "fmt" "log" "net/http" "time" "github.com/ne-sachirou/go-graceful" "github.com/ne-sachirou/go-graceful/gracefulhttp" "github.com/ne-sachirou/go-graceful/gracefulgrpc" "google.golang.org/grpc" ) func main() { ctx := context.Background() srv := graceful.Servers{ Servers: []graceful.Server{ &gracefulhttp.Server{Server: &http.Server{Addr: ":80"}}, &gracefulgrpc.Server{Addr: ":8000", Server: grpc.NewServer()}, }, } if err := srv.Graceful(ctx, graceful.GracefulShutdownTimeout(10 * time.Second)); err != nil { log.Fatalln(err.Error()) } }
大分短く成りました。
Mackerel の一部 system に導入した結果も slide に書きました。
同じ library を使ふ利點は、改善が容易くなる事です。
よかったですね。
Erlang/OTP みたいな application 管理を實裝したくなりますが、抑へてをります (ぉ。
勿論 feedback を受け附けてをります。
developer.hatenastaff.com (はてなエンジニアのカレンダー | Advent Calendar 2023 - Qiita) の 12/11 (月) です。
今、數人で大きな機能を開發してゐます。その中で mobbing を暫く續けてみたので、體驗を書きます。
明日は id:Windymelt です
qiita.comの 12/8 (金) です。
Mackerel では從來のメトリックに加へ、メトリックにラベルを附与できる形式である「ラベル付きメトリック」を開發中です。OpenTelemetry 規格のメトリックそのものを Mackerel に投稿し閲覽できます。
只今ベータ版テストを受け附け中ですので、是非とも御應募ください。
さて。Mackerel に投稿したラベル付きメトリックはグラフを作って閲覽したり、(將來的には) アラートを發報できます。この時にラベル付きメトリックを讀んだり計算するには PromQL と云ふ query 言語を介して行ひます。PromQL を書いて柔軟にメトリックを檢索したり計算したりできるのです。
そもそも PromQL とは Prometheus と云ふ監視 application が備へた query 言語です。Prometheus はラベルの付いたメトリックを保存し、閲覽したりアラートを發報できます。Prometheus のメトリックの形式は OpenTelemetry のメトリックの形式とは一致しませんが、メトリック名やラベル名を變換する事で保存できます。保存したラベルの付いたメトリックを Prometheus は PromQL を介して讀んだり計算できるのです。この世に知られた、ラベルの付いたメトリックを柔軟に處理する實績の有る PromQL を Mackerel でも query 言語として採用しました。
PromQL がどの樣なものか Prometheus の document を御覽いただけます。
この PromQL を處理する system の現時點 (2023/12) での內部を少し御傳へしませう。(將來もこの設計である事を保證するものではございません。)この system を「reader」と呼びませう。下記の記事で「OTel metric Reader」として登場する system の事です。
rmatsuoka.hatenablog.com speakerdeck.com
reader は 2 つの DB からラベル付きメトリックを讀みます。ラベルを保存する「ラベル DB (PostgreSQL)」と、メトリックを保存する時系列 DB「diamond」です。(diamond についてはまかれるあなとみあ ―Mackerel のしくみを理解する 30 分― @ Hatena Engineer Seminar #16 - Speaker Deckやメトリックはいかにして見え續ける樣になったか #devio2022 - Speaker Deckを御覽ください。)それぞれの DB からの讀み出しを形式的に書くと、
と表せます。ラベル DB はラベル檢索條件と期閒を引數としてメトリックキーを返す函數と見做せ、diamond はメトリックキーと時刻と粒度を引數として値の列を返す函數と見做せます。reader は PromQL からラベル檢索條件と期閒と粒度とを抽出して DB を讀まねばなりません。reader 內の on memory での計算は自由な data 構造を用ゐて最適化し易いのですが、DB への query は所詮 DB の實現できる data 構造に制約されます。ですのでラベル檢索條件・期閒・粒度に關はる PromQL の仕樣を精査しました。
調査 resource は、
github.com/prometheus/prometheus/promql
packageです。結果として以下の仕樣を抽出しました。それぞれの說明は Prometheus の document を御覽ください。
これらを特に念頭に置いて、以下の設計で處理可能である事を議論しながら腦內 simulate しました。
格好惡いので用語は少し變へますが…、
github.com/prometheus/prometheus/promql/parser
を fork したもの。OpenTelemetry のメトリックを變換せずに扱へる樣に擴張しましたmemory を活用して、處理を單純に、高速にする目論見です。
そして irate 等幾つかの函數を含めて本當に實裝でき (irate 函數を含めて多くを實裝したのは監視ツールのカウンタへの向き合い方 - Diary of a Perpetual Studentも書いた id:arthur-1 です)、その後 tuning されてゐるのが、今ベータ版テストで提供してゐる reader です。御試しください。
そして Meetup にゐらしてください。LT 枠もございます。
明日は id:taxintt さんです。