goen v0.0.3について

goen v0.0.3には、以下の変更が含まれています:

  1. 生成されたInメソッドの引数を、スライスから可変長に変更
  2. no such table "\"hoge\"" などの、余分なクォートをしてしまう問題の修正
    • v0.0.1で入れたクォートの対応によって発生
    • String() と QuotedString() で、bare nameとquoted nameをそれぞれ取得できるように変更

goen v0.0.2 について

goen v0.0.2には、以下の変更が含まれています。

  1. CompilerHookの追加
  2. CompilerOptions.Hookの追加
  3. CompilerWithHookの追加

これにより、goenが生成したinsert/update/delete用のクエリを、ユーザがカスタマイズできるようになりました。 例えばpostgresのupsertをする場合は

type myHook struct {}

func (*myHook) PostInsertBuilder(stmt squirerl.InsertBuilder) squirrel.Sqlizer {
    return stmt.Suffix("ON CONFLICT DO NOTHING")
}

func (*myHook) PostUpdateBuilder(stmt squirerl.UpdateBuilder) squirrel.Sqlizer {
    return stmt
}

func (*myHook) PostDeleteBuilder(stmt squirerl.DeleteBuilder) squirrel.Sqlizer {
    return stmt
}
dbc := goen.NewDBContext("postgres", db)
dbc.Compiler = goen.CompilerWithHook(goen.BulkCompiler, &myHook{})
dbc.Patch(goen.InsertPatch("the_table", []string{"the_column"}, []interface{"the_value"}))
dbc.SaveChanges()

これでgoenを使ったupsertが可能になります。 ただこの機能については、もう少しブラッシュアップの必要があるため、しばらく使ってみてAPIに変更を加える可能性が高いです。

goen v0.0.1 について

goen v0.0.1には以下の変更が含まれています。

  1. CompilerOptions.StmtBuilderの削除
  2. CompilerOptions.Dialectの追加
  3. goenが生成するクエリについて、テーブル名とカラム名をクォートするように変更
  4. MetaSchemaをinterfaceに変更
  5. MetaTableの追加
  6. MeaColumnの追加
  7. RowKey.ToSqlizerWithDialectの追加

先日orderというカラム名を使っていたところ、goenの生成するクエリが不正になるというバグ報告を受けたため、対応したものになります。

goen v0.0.0 について

goenを使ったプロダクトがここ数ヶ月、特に問題なく稼働しているということと、大体APIも問題なさそうだということで、ベータからv0.0.0の正式版に移行しました。

v0.0.0では、以下の変更が含まれています。

  1. DBContext.QuerySqlizer
  2. DBContext.QuerySqlizerContext
  3. DBContext.QueryRowSqlizer
  4. DBContext.QueryRowSqlizerContext
  5. go generateで生成されるクエリビルダに、ToSqlizerを追加

Sqlizerでの取り回しが、よりやりやすくなったはずです。

Scheduled Eventsの挙動調査

AzureのVM起動/終了時にフックかましたくなったので、Azure Metadata ServiceのScheduled Eventsについて調査した。 今回はLinuxCanonicalUbuntu 16.04 LTS)のみ、かつ確認が面倒なためRebootのみが対象。

前提

  • Azureの東日本リージョンで、シングル構成のVMを用意
  • Availability Setは未構成
  • Scheduled Eventsを有効化済

調査結果

VMが通常稼動しているとき

curl -sS -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2017-08-01 を実行すると、 即座に 以下のレスポンスが返却される。

{"DocumentIncarnation":0,"Events":[]}

VMのRebootを実施したとき

Azureポータル上からVMのRestartを実施してみた。 検証した中では、Scheduled Eventsへの反映に数秒から十数秒程度かかっていた。

curl -sS -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2017-08-01 を実行すると、 即座に 以下のレスポンスが返却される。

{"DocumentIncarnation":1,"Events":[{"EventId":"F1B53BF4-85CE-4632-9D74-A9E2F38F5D53","EventStatus":"Scheduled","EventType":"Reboot","ResourceType":"VirtualMachine","Resources":["{virtualMachineName}"],"NotBefore":"Wed, 10 Oct 2018 03:49:39 GMT"}]}

NotBeforeには、Azureポータル上からRestartを実施した時刻から15分後の時刻が格納されていた。 この猶予時間は、EventTypeの種類ごとに定義されていて、FreezeとRebootなら15分、Redeployなら10分となる。 後述のApproveをせずにNotBeforeの時刻に到達すると、VMが実際に再起動される。

何度かScheduled Eventsから取得してみたが、何度でも同じレスポンスが取得できるよう。 そして、該当イベントをApproveするまでは、(上限の時間内で)VMは終了しなかった。

次のリクエストを投げて、該当イベントをApproveすると、その後数秒から十数秒ほどで実際にVMが再起動された。

curl -sS -H Metadata:true http://169.254.169.254/metadata/scheduledevents?api-version=2017-08-01 -d '{"StartRequests":[{"EventId":"F1B53BF4-85CE-4632-9D74-A9E2F38F5D53"}]}'

このとき、レスポンスは空(Content-Length: 0)が返ってきた。

再起動後に再度Scheduled Eventsを取得したところ、以下のようになった。

{"DocumentIncarnation":3,"Events":[]}

まとめ

Scheduled Events、かなり便利だった。 難があるとすれば、ポーリングしなければならない点だけれど、これはAzureのAPIが全体的にポーリングするデザインになっているため、まぁしゃーない。 しかしイベントが取得可能になってから、10分とか15分程度の猶予ができるため、ポーリングでもそこまで問題になることはないかな、という印象。 若干面倒な点は、同じイベントがずっと取れてくるところで、取得する側が既に処理済のイベントかどうか、を判断する必要がありそう。 適用可能なケースだと、かなり有用な機能だと思う。

VMでの挙動で、Scheduled Eventsの動きはおおよそ想像がついたため、今度はVMSSでの挙動を調査したい。

参考リンク

Scheduled Events for Linux VMs in Azure | Microsoft Docs