Grape+Rspec環境でAPIをテストする
既存RailsアプリにRspecを入れる - コピペコードで快適生活
の続き。
まず、JSONのテストを簡単にするgemを入れる。
gem 'json_expressions'
テストコードはこんな感じで書ける。
require 'rails_helper' require 'json_expressions/rspec' describe "GET api/orders/:order_ids" do context '存在しないIDを指定するとき' do it '空の配列が返る' do order_ids = "aaaa,bbbb" get "/api/v1/orders/#{order_ids}" pattern = { orders: [], total_count: 0 } expect(response.status).to eq 200 expect(response.body).to match_json_expression(pattern) end end end describe 'PATCH api/orders/:order_id/cancel' do context '存在しないIDを指定するとき' do it '204が返る' do order_id = "aaaa" params = {xxx: 2} patch "/api/v1/orders/#{order_id}/cancel", params expect(response.status).to eq 204 end end end
capistranoでデプロイされているブランチのコミットハッシュを確認する
cat ${PATH}/repo/refs/heads/${BRANCH}
Nodejsでのバイナリの取り扱い
よくわかっていなかったので整理した。
Bufferオブジェクト
Node.jsではバイナリデータはBufferオブジェクトで扱う。
ArrayBuffer
実際のメモリに格納されたバイナリデータを配列で表現したもの。読み込み専用。
Uint8Array
バイナリデータを8bitごとに区切って配列にしたもの。1つの要素には0~255の値が入る。変更可能。
// 128バイトのバッファを作成 // 初期化はされない let buf = new Buffer(128); console.log('定義だけ', buf); // バッファに0を書き込む buf.fill(0); console.log('0で初期化', buf); // 10バイト目から20バイト目まで2を書き込む // (先頭は0と数える) buf.fill(2, 10, 30); console.log('2バイトで一部初期化', buf); // 文字列をバイナリ化 buf = Buffer.from('テスト文字列', 'utf8'); console.log('文字列バイナリ', buf); console.log('文字列のバイト数', buf.length); console.log('元の文字列を出力', buf.toString('utf8')); // bufferをArrayBufferにする function toArrayBuffer(buffer) { var ab = new ArrayBuffer(buffer.length); var view = new Uint8Array(ab); for (var i = 0; i < buffer.length; ++i) { view[i] = buffer[i]; } return ab; } buf = Buffer.from('TEST', 'utf8'); let arrayBuf = toArrayBuffer(buf); console.log('ArrayBuffer', arrayBuf); // arrayBufferからBufferを作る buf = Buffer.from(arrayBuf); console.log('arrayBufから作成したBuffer', buf); // ファイルを読み込む let fs = require('fs'); buf = fs.readFileSync('./buf.js'); console.log('ファイルのバイナリデータ', buf); // axiosでバイナリデータを取得するときは // responseTypeに arraybuffer を指定する // そうすることで、arrayBufferオブジェクトとして受け取れる // let client = axios.create({ // 'responseType': 'arraybuffer', // }); // Bufferオブジェクトかどうかのチェック console.log('Bufferかどうかチェック', Buffer.isBuffer(buf));
補足
html5のJSにはBufferはない。Blobで扱う。
https://www.sejuku.net/blog/67735#Blob-2
ArrayBufferをBlobに変換
http://var.blog.jp/archives/62330155.html
AWS NLBとコネクションプールについて
NLBの後ろに1台足してもそっちに全然クエリが流れてこなかった。
間違っているかもしれないけど、多分こういうことじゃないかな。
コネクションプールについて
接続確立は負荷を伴うので、一度確立した接続を維持して、その中でクエリ発行することで負荷を軽減する仕組み。
クライアントの実装によるが
・プール数上限設定があってそれ以上のクエリ発行をしようとすると待つ。
・接続断が発生したあと、再度クエリを発行すると再接続確立を試みる。
・一定時間使われていないコネクションがあると閉じる(ガベージコレクタに回収させたり)
・なので、クエリ発行が休みなく正常に続いているコネクションはずっと開いたまま。
AWS NLB
NLBは単にバランシングしているだけで、実際にはその後ろにあるサーバとコネクションが確立されている。
なので、
・クエリ発行が休みなく正常に続いているコネクションはずっと同じサーバとつながったまま。
・NLBの後ろに1台足しても、クエリ発行が休みなく続く限り、新しいサーバには通信はいかない。
・クライアント側を再起動してコネクションを再接続すると、新しいサーバにも通信がいくようになる。
シェルスクリプトで対話的に選択肢を選ばせる
よく忘れるのでメモしておく。
# # 入力値チェック/セット # echo 'CloudFrontログを抽出します。' echo '対象ドメインを番号で指定してください' echo ' 1) a.example.com 2) b.example.com 3) c.example.com ' read num case ${num} in 1) DOMAIN='a.example.com' CF_ID='xxxxx' ;; 2) DOMAIN='b.example.com' CF_ID='xxxxx' ;; 3) DOMAIN='c.example.com' CF_ID='xxxxx' ;; *) echo '番号が不正です' exit ;; esac
PostgreSQLでプロセスとロック状況を確認する
## 実行中のSQLを確認する。 SELECT * FROM pg_stat_activity; ## 実行中のSQLを確認する ## スロークエリとか主に見る分だけ SELECT pid, query_start, substr(query, 0, 80) AS query FROM pg_stat_activity WHERE state='active' ORDER BY query_start; ## ロック状況の確認 SELECT l.pid, db.datname, c.relname, l.locktype, l.mode FROM pg_locks l LEFT JOIN pg_class c ON l.relation=c.relfilenode LEFT JOIN pg_database db ON l.database = db.oid ORDER BY l.pid; ## AccessExclusiveLockロックがかかっているか SELECT l.pid, db.datname, c.relname, l.locktype, l.mode FROM pg_locks l LEFT JOIN pg_class c ON l.relation=c.relfilenode LEFT JOIN pg_database db ON l.database = db.oid WHERE l.mode = 'AccessExclusiveLock' ORDER BY l.pid; ## Railsのマイグレーションでロックをかけない呪文 ## デフォだとSELECTも通さないAccessExclusiveLockがかかる class AddStatusToUsers < ActiveRecord::Migration disable_ddl_transaction! def up # 略 Users.find_each do |user| user.update_columns(status: 'xxx') end end def down # 略 end end ## インデックス追加中にロックかけない ## (concurrentlyオプションを有効にする) ## https://thoughtbot.com/blog/how-to-create-postgres-indexes-concurrently-in class AddIndexToAsksActive < ActiveRecord::Migration disable_ddl_transaction! def change add_index :asks, :active, algorithm: :concurrently end end
メモ
PostgreSQL×Rails環境でのマイグレーションで、バカでかいテーブルに対して、add_column + eachまわしてupdate ということをやると、こうなる。
・add_columnsで、AccessExclusiveLockかかる。
・AccessExclusiveLockの中でeachでUPDATE走る。
・AccessExclusiveLockはSELECTも通さないロックなので、
該当テーブルに対するSELECTがすべて待ちになる。
・待ちのSELECTでDBプロセス食い尽くす。
・DBが応答なくなる。
・障害発生 :unko:
Imagemagickコマンドメモ
## 黒塗り / 中央寄せ / リサイズせず正方形に整える convert -background black -gravity center -extent 960x960 tamanegi.png _tamanegi.png ## 白色を透過に変える(transparent) / 白から5%くらいずれていても透過させる(fuzz) convert input.png -fuzz 5% -transparent white output.png ## 複数の画像をマージする。 ## 横につなげる convert -append 01.png 02.png out.png ## 縦につなげる convert +append 01.png 02.png out.png ## 横につなげる + 上下左右に30の余白を開けて連結する convert -append -border 30x30 01.png 02.png out.png ## 文字画像を作る convert -size "256x128" -background "#f5f5f5" -fill "#dc143c" caption:"image\nmagick\n" output.png