より長続きするブログ

続けていきたい気持ち。

複数人による同時編集でロストアップデートするのを防ぐ

もう散々語り尽くされているのかもしれないが、Web画面で、同じリソースの複数人による同時編集でロストアップデートするのを防ぐ方法が自分の中でちゃんと確立できていなかったので考えた。

流れはこんな感じ。

  1. 編集対象をブラウザで開いたとき、リソースの最終更新日時など、最新リソースであることを確認できるデータを取得する
  2. 編集してアップデートするとき、取得していた最終更新日時のようなデータも一緒に送信する
  3. 更新するまえに最終更新日時のようなデータをselect for updateで取得し、一致しているかチェックする
  4. 一致していたら更新し、違っていたらエラーにする

以上でOKなはず。

 

ポイントとして、更新前のデータ取得でselect for updateを使う。

複数のトランザクションが走っていたら、2番目以降の更新はここで止まり、その後読み込むと既に別のトランザクションがコミットされているので履歴IDは一致せずエラーにできる。

 

一致を確認するデータとして「最終更新日時のようなデータ」と書いたが、リソースの変更履歴テーブルのようなものを用意して、そのバージョンが変わっていないか見るというのがより良いと思う。特に一つのモデルが複数のテーブルから成っているときは最終更新日時はいくつかある…みたいな状態になり、モデルごとの更新履歴テーブルは使いやすい。

 

で、運用上はリクエストに履歴IDを付けるのは必須じゃなくて、付いていたら一致を確認して、無かったらそのままアップデートみたいな緩い感じでもいいかなと思っている。

 

ちょっと混乱していたのだが、この挙動はトランザクション分離レベルでは解決しずらい。

SERIALIZABLEなら、解決するけどそれは普通やらないし。他の分離レベルで他のトランザクションからの影響をなくしてもあんまり意味がない。他のトランザクションに対して待ちを発生させる必要がある。

 

懸念点として、select for updateで最新のデータを取得する…というのはこういうコードになるとおもうのだが、

SELECT * from change_log a
where not EXISTS (
  select * from change_log b
  where a.created_at < b.created_at

) for update;

 

 行ロックではなくテーブルロックになってしまうようである。行ロックにする方法があればいいけれど、「最新」というのはテーブル全体をロックしておかないと確定できないような気がするので仕方ないのかもしれない。

まあ、同時更新絶対防止したいようなリソースは更新頻度低いだろうし、ロック掛けても大丈夫なように作れることが多いかとは思うけど。

2018年の振り返り、および2019年の目標

2018年の振り返り

低レイヤー技術の向上

  • パタヘネ本を読み始めた。しかし3章くらいで中断している
  • 基礎に時間を投資する余裕が少なかった

リリースエンジニアリング

  • シェルスクリプトで書いていたビルドスクリプトを、Makefileに置き換えた
  • makeコマンドでビルドタスクをメソッドっぽく扱うことで、CI側のコードをシンプル化した
  • もうちょっと時間投資したかった

設計力の向上

  • BFF構成を使ってみた
  • しかし本来BFFを使う必然性がなかったところに、プロジェクトの制限をしわ寄せを受け入れるレイヤーとして使ったので、あまり健全でなかった

資格の取得

  • ITサービスマネージャ2度目の撃沈。
  • 論文が全然書けなかった(結果、D判定)

ソフトウェア工学に親しむ

  • できなかった。

新しいプログラミング言語を習得する

  • Elmを使い始めた。
  • オペレーションツールの画面などを書いている。
  • 純粋関数型言語に触れるのは初めてなので、新概念を色々取り入れたい。

保育所生活に慣れる

  • 勤務時間の都合もあって、送り迎えは妻にお任せ
  • ありがたいことにあまり変化がなくて済んでいる

資産を調整する

  • MVMOした。
  • 品質が悪いという根拠の無い噂があったために躊躇してしまったけど、ある程度調べたらさっさとやっとけばよかった。何も困らない。
  • 資産投資は始められず。

アウトプットの増加

  • ブログとQiitaで数本ずつ記事を書いた

2019年の目標

去年の目標をそれぞれ先に進める感じでやっていきたい。


リリースエンジニアリング

  • 新規プロジェクトで、現実的なコストでCI環境を用意できるようになる

資格の取得・設計力の向上

  • 取得できていなくてあれなのだが、ITサービスマネージャの勉強は飽きてしまった
  • 次はシステムアーキテクト受けとこうかなと思っている

論文を読む

  • 査読付き論文は正義

新しいプログラミング言語を習得する

  • 新しいジャンルに挑戦するきっかけになると思うので今年も何か一つ
  • JuliaとかRとか?

保育について知る

  • 子供について知りたい、子供のいる環境について知りたい
  • 保育士の資格対策本とか眺めてみる?

投資

  • MVMOで浮いたお金ができてくることに期待

DockerでVolumeの容量が増え続けていたときの対処

普段使っているラップトップはSSD256GBなのだが、近頃ディスク使用量が90%越えてしまい、どうにかせねばと思っていました。ディスクの内訳を調べてみると、dockerのvolumeが溜まりまくっていたことがわかりました。

 

調査

sudo du -hs /*

からはじめて、大きいディレクトリを手動再帰で調べました。自動化するほどでもなく、容量を食っているディレクトリは簡単に見つかりました。

130G /var/lib/docker

これは…SSD全容量の半分以上食ってるやんけ……

さらに調べるともう削除したはずのコンテナの、volumeコンテナであることがわかりました。
条件はよくわかりませんが、ある用途で使っているコンテナで使ったvolumeが残り続けてしまっているみたいです。

そのコンテナはちょいちょい新しく作り直していたので、その度にvolumeが増えていく。

 

削除方法

たまに

docker system prune

は実行しているのですが、これだと消えていないようです。

代わりにこちらのコマンドで削除できました。

docker volume rm $(docker volume ls -qf dangling=true)

dangling=trueなので、他のコンテナに紐付いていないvolumeだけが削除されます、たぶん。

消えたら作り直せばいいコンテナしかなかったので、気楽に実行しました。

 

これで130GBもあったディレクトリはほとんど空になり、空き容量が50%は以下。しばらくはディスク容量のことは忘れられます。

 

参考

Docker関連の削除コマンド集: https://qiita.com/boiyaa/items/9972601ffc240553e1f3
本記事で利用した削除方法: http://zashikiro.hateblo.jp/entry/2016/08/16/201633

 

追記

docker system prune -a

これを使うべきなようです。

 

PandocでMarkdownを段落番号のついたPDFに変換したい

Markdownへの回帰

Markdownは段落の機能が貧弱なのに耐えきれず、Sphinx(reStructuredText)を使っていたこともかつてはありました。
でも本当はMarkdownで書けたら楽なのになと思っていたのです。
普段メモ取ったりするのはreStructuredTextではなくてMarkdownを使うし、周りにも使える人が多いし、エディターのサポートも手厚いから。

ということでMarkdownの見出しから段落をつくり、番号のついたPDFに変換するのを試してみました。
変換ツールとしてPandocを使います。

以下、今のところこうしているよというメモになります。

 

環境構築

OSはUbuntu16.04を使いました。

aptで適当にインストールして使います。

apt -y install texlive-full pandoc

tex環境はデカイですが、下手に省略するとハマりそうなのでfullで入れてしまいます。

Ubuntu16.04のaptで入れるとバージョン1系がインストールされるようですが、
現時点で最新版は2系なので、必要ならばstack installとかすると良さそう。


変換コマンド

だいたいこれでいい感じに変換できてしまいます。すごい。

pandoc *.md -o output.pdf -V documentclass=ltjsarticle --latex-engine=lualatex -N --toc --highlight-style=tango

 

「*.md」

一つのディレクトリに、大見出しごとにファイルを分けたmdファイルを置いておいて、
コマンドを実行すると良さそうです。
「*.md」でファイルを読み込むので、「01_概要.md」, 「02_本題.md」など、
プレフィックスを付けて順番を決めました。
(変更するときは面倒なので、昔のBasicよろしく10_, 20_とかやるべきなのだろうか)

 

「-o」

「-o」で出力先のファイル名を決めます。
pandocでは出力先ファイル名で、何のファイルに変換する決まるようなので、ここでoutput.texとか指定すると
pdfに変換する前のtexファイルを確認したりできます。

 

「documentclass=ltjsarticle」

lstjsarticleを使うと、日本語を上手く表示してくれる設定が読み込まれるみたいです。

当初、1文字間違えてタイプして「ltjarticle」となっていて、見た目が微妙なPDFを出力してしまいました。
latexのtemplateでどうにかしないといけないのかと試行錯誤しましたが、
ltjsarticleのデフォルト設定でほぼ満足です。

 

「--latex-engine=lualatex」

latexには色々な実装があるようなのですが、lualatexを選択します。
名前の通りLuaが使えるのが特徴とのことですが、単に日本語文書にも対応できているlatexとして使います。

「-N」

段落番号を付けるオプションです。
これが欲しかった。

# AAA
## BBB
### CCC

みたいに書くと、

1 AAA
1.1 BBB
1.1.1 CCC

のように表示されます。

「--toc

Table of Contentsの略。目次を出力します。
複数枚の文書であれば、付けておくと良いと思います

 

「--highlight-style=tango」

PDFの中にコードを埋め込みたかったのですが、デフォルトだと背景色が白で、
どこまでがコードブロックなのかわかりずらいのが好みではありませんでした。
tangoはコードブロックの背景がライトグレーになるのでわかりやすく、
文字色が好みだったので、これを選んでみました。

 

 使わなかった設定「--template=mytemplate.tex

ltjsarticleデフォルトの見た目では満足できない場合、自分でtemplateを用意して見た目をカスタマイズできます。
思い通りにするのは結構難しく、使わないことにしました。

簡単だったら見出しをもう少しメリハリのある感じにしたいのですが、意外と面倒くさい。

 

~~~

「pandoc -D latex > mytemplte.tex

pandocでの変換に使う、デフォルトのテンプレートを出力できます。
これを叩き台に。

 

「\usepackage{titlesec}」

見出しのデザインを簡単にカスタマイズできるようにするパッケージ。
参考になったサイト: https://qiita.com/kiritex/items/deeec0843caf37b66054

pandocを使ってMarkdownを変換した場合、見出しはsection, subsection, subsubsection, ...となるので
chapterは使えないみたいでした。

 

「\usepackage{color}」

色を定義するパッケージ。titlesecを使っているサンプルではだいたいこれも使っているので自分も読み込んでみたが、エラーになる……
デフォルトのテンプレートでは別のパッケージから既に読み込まれいるのだと思います。
\usepackage{color}を追記しなくても\definecolorができました。

 

「\usepackage{ifthen}」

titlesecでsectionをカスタマイズして、\thesectionでセクション番号を表示させた場合、
--tocで付けた目次にまでセクション番号「0」が入ってしまいました。

セクション番号は1から表示でいいので、1未満の数字だったときは表示させたくない……
ということでこの条件分岐パッケージを使います。

条件分岐させれば、対処できることは確認できました。

 

~~~

ここまでやって、コストに見合わない感じがしてきたのでテンプレートカスタマイズは一旦諦めました。
頑張れば好きな見た目のテンプレートができるんだろうと思いますが、
そこまで複雑なことはやりたくないので、強い不満が無い限りはデフォルトのテンプレートを使っていくつもりです。

 

まとめ

カスタマイズテンプレートは諦めたものの、MarkdownをPDFまでコマンド一発で変換できて、そこそこいい感じのPDFができあがりました。

応用的にやりたいことは色々あるので、使いながら試していきたいと思います。

(画像の配置はどうなるかとか、PlantUMLの埋め込みができるかとか)

2018の目標

会社で4半期スパンで色々書いているので、そちらに乗っかればいいやと去年は書かなかったけど、個人的な目標の行き先がなかったので、今年は書いておく。

 


低レイヤー技術の向上

リリースエンジニアリング

  • 昨年作ったCI/CDの仕組みを洗練
  • 自分が十分楽に使えるようになったら他の人も広まるようにアウトプット

設計力の向上

  • マイクロサービス本のトピックを1つ以上取り入れて実装してみる
  • アーキテクチャ系の本を1冊以上読む

資格の取得

  • ITサービスマネージャ再試

ソフトウェア工学に親しむ

  • ニュースだけでなく、論文で原文をあたっていく

新しいプログラミング言語を習得する

  • Rust・HaskellC++のいずれかをちょっとやる

保育所生活に慣れる

  • こどもが4月から保育所に入る可能性が高いので、適応せねばならない

資産を調整する

  • いい加減MVMOして固定支出を削減
  • 学資保険くらいしかやったことないので、何か手を付ける程度で投資する

アウトプットの増加

  • とりとめのない内容でも、このようにブログに書いてみる

 

 


このあたりをやりたい。
1年は長すぎて後半予想ができてないけどとりあえず。

サーバーテストツール(2016)

最近の情勢は気が向いたら調べねば。

 

 ServerSpec

Ruby
RSpecでテストコードが書ける
・サーバーの内部からミドルウェアのインストール状況や稼働状況、設定などをテストする
・情報量が多い(書籍も出ている)

 

Infrataster
Ruby
RSpecでテストコードが書ける
・サーバーの外側から、サーバーの振る舞いをテストする
・情報量が少ない

 

Testinfra
Python
・TDDライクなスクリプトでテストコードが書ける
・サーバーの内部からミドルウェアのインストール状況や稼働状況、設定などをテストする(はずだが未検証)
・情報量は多くはなさそう(未検証)

 

goss
Golang
・サーバーの内部からミドルウェアのインストール状況や稼働状況、設定などをテストする(はずだが未検証)
・コマンド操作でテストコードを追加する機能がある

 

envassert
Python
・ServerSpecにインスパイアされてでてきたみたいだけど、メンテナンスされてなさそう

 

Sphinxの導入にあたってのメモ書き(for Windows)

概要

会社で使うドキュメントはほとんどがExcelによって生成されていた。

文書作成にWordを使うと、テキストに比べるとバージョン管理しづらく、再利用性に難がある。

簡単なものはMarkdownでガリガリ書き捨てていたけれど、ネストのある箇条書きに番号降るとか、ちょっとレベルの高いレイアウト設定とか、対応しようとするととたんに厳しい。そこでSphinxに白羽の矢が立ったのだった。

Sphinxはテキストで書けるのでGitで管理できるし、再利用もしやすい。インデックス作る機能も標準で備えている。

ここではSphinxのインストール手順と、個人的によく使いそうな設定と、導入したプラグインをまとめて書いた。

なお、インストールは公式手順ほぼまんまなので、Windowsへのインストール — Python製ドキュメンテーションビルダー、Sphinxの日本ユーザ会を読んだ方がいい。

 

続きを読む