OmniAICreator/Qiita-1.07M huggingface dataset:
ページグパラメーターが大きいときにレスポンスタイムが遅くなる問題


Qiitaのあるタグがついた投稿一覧ページのページングの末尾まで飛ぶリンクをクリックした時に、レスポンスが明らかに遅い気がします。
体感的には、2〜3倍は遅い感じがします。

http://qiita.com/tags/JavaScript/items

![スクリーンショット_2016-12-05_23_06_54.png](https://qiita-image-store.s3.amazonaws.com/0/74551/1deee647-6c00-e3a4-3d3c-99587e827e8d.png "スクリーンショット_2016-12-05_23_06_54.png")

# 計測してみた
## 方法
とはいえ、なんとなく、遅いと言うのはただの言いがかりなので、どのくらい遅いのか計測をしてみました。

今回はページングのパラメーターを大きくしながら、リクエストを投げて計測します。
測定するメトリクスはTTFB(Time To First Byte)です。

TTFBの計測は以下のようにcurlコマンドを使って行いました。

```
curl <URL> -s -o /dev/null -w '%{time_starttransfer}\n'
```

## 結果

測定結果を箱ひげ図にしたグラフを以下に示します。
横軸はページングのパラメーター(そのまま表示させると、グラフの横幅が大きなってしまうので、幅15のビンを作成しています)
縦軸は、TTFB(Time To First Byte)です。

![シート 1.png](https://qiita-image-store.s3.amazonaws.com/0/74551/f5b27477-1190-d0b2-c7c5-d93e8cadc691.png "シート 1.png")

ページ番号300を境界にして、振る舞いが大きく変わっていることがわかります。

300番よりも若い番号をキャッシュするような実装なのでしょうか。
Incrementsの採用ページを見ると、RailsやAWSを使っていることが読み取れるので、おそらくキャッシュ用のミドルウェアはmemcachedかRedisでしょう。

おそらく、ソースコードのどこかに300というマジックナンバーがあるはずなので、それを600くらいにしてもいいのではないでしょうか？
これほど多くの投稿があるタグもそんなに多くないので、キャッシュサイズの増加の影響はそこまでないかと思います。

```
s/300/600
```

# ちなみに、Qiita::Teamでは
Qiita::Teamでも同様のことを調べようとしたら、ページが重すぎて、502になってしまいました・・・

![スクリーンショット 2016-12-06 0.37.16.png](https://qiita-image-store.s3.amazonaws.com/0/74551/f10758f3-58b6-a9ab-7c69-fa1c35013532.png "スクリーンショット 2016-12-06 0.37.16.png")
データベースのutf8mb4対応


普通にMySQL使ってると、絵文字が使えなかったりして辛い時がある。これは文字コードをutf8mb4にすることで解決できる。

### Mac側の対応

HomebrewでMySQLを入れた場合、次のような手順になる。

まず、my.cnfを作ったことがなければ、デフォルトのを探してコピーしてくる。

```
$ find /usr/local/Cellar/mysql -name "my*.cnf"
/usr/local/Cellar/mysql/5.6.24/support-files/my-default.cnf
$ cp /usr/local/Cellar/mysql/5.6.24/support-files/my-default.cnf /usr/local/etc/my.cnf
```

以下のように編集してMySQLを再起動する。

```
$ vi /usr/local/etc/my.cnf
[mysql]
default-character-set=utf8mb4

[mysqld]
character-set-server = utf8mb4
skip-character-set-client-handshake
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init-connect = SET NAMES utf8mb4
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix
```

具体的に何をやっているかは、``mysql utf8mb4``とかでググると出てくるので調べる。

### AWS RDSの対応

本番環境でAWS RDSを使っている場合も、同様のことをやる。[クラスメソッドさんの記事](http://dev.classmethod.jp/cloud/aws/utf8mb4-on-rds-mysql/)などが参考になる。

ただし、``innodb_file_format``を``Barracuda``、``innodb_large_prefix``を``1``にする部分が抜けており、これを忘れると後で詰まる。

### 変更用のスクリプト作成

やらなきゃいけないことが以下の４種類あるので、それぞれ実行していく。

* データベースのCHARACTER SETの変更
* テーブルのROW FORMATの変更
* テーブルのCHARACTER SETの変更
* text型のカラムが自動的にmediumtext型になってしまうのでtext型に戻す

テーブルロックに注意。巨大なテーブル等の変更には工夫が必要。

```
ALTER DATABASE database_name CHARACTER SET utf8mb4;
ALTER DATABASE database_name COLLATE utf8mb4_general_ci;

ALTER TABLE table_name ROW_FORMAT=DYNAMIC;
ALTER TABLE table_name2 ROW_FORMAT=DYNAMIC;

ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4;
ALTER TABLE table_name2 CONVERT TO CHARACTER SET utf8mb4;

ALTER TABLE table_name MODIFY COLUMN text text;
```

ワンライナーは以下のようになる。ただし、これだと最後の``ALTER TABLE table_name MODIFY COLUMN text text;``などはカバーしきれない。``mediumtext``で問題がある場合は別途、対応した方が良い。

```
(mysql -uroot -p <DATABASE_NAME> -e "show tables" --batch --skip-column-names | xargs -I{} echo 'alter table `'{}'` convert to character set utf8mb4;') > /tmp/alters.sql

cat /tmp/alters.sql | mysql -uroot -p ...
```
シェルから使うオフラインの英和・和英辞書

[Linux のコマンドラインでオフライン英和辞書](http://qiita.com/yubais/items/21cac44d71c30edd22c9)を読んで、これちょっと変えるだけで和英としても使えるなー、と思ったのでやってみた。

## セットアップ
1. [GENE95 辞書](http://www.namazu.org/~tsuchiya/sdic/data/gene.html)を入手する。
2. 文字コードと改行コードを変更する。
    - ダウンロード時点ではCRLF改行、文字コードはcp932(shift-jis)になっているはず。
    - 私はvimで開いて`set ff=unix`、`set fenc=utf8`として変更している。
3. 適当な場所に配置する。
    - 以降の説明では`/usr/share/dict/dict`として保存するものとする。
4. シェルの設定ファイル(.zshrcなど)に以下のような関数を定義する。

```shell-session
# 辞書を引く(英和)
function ejdict() {
  grep "$1" /usr/share/dict/dict -E -A 1 -wi --color=always | less -R -FX
}
# 辞書を引く(和英)
function jedict() {
  grep "$1" /usr/share/dict/dict -E -B 1 -wi --color=always | less -R -FX
}
```

## 使い方
- 英和辞書を引く(`ejdict glasses`)。

![ejdict.png](https://qiita-image-store.s3.amazonaws.com/0/28487/5367f287-5941-247b-953e-8161e7f55a06.png)

- 和英辞書を引く(`jedict 眼鏡`)。

![jedict.png](https://qiita-image-store.s3.amazonaws.com/0/28487/cb033506-0654-5d46-d021-30c4bd5193d5.png)

## 補足
- GENE95の辞書ファイルが「英語、日本語、英語、日本語・・・」と並んでいることを利用して、英和ではヒット単語の1行後、和英ではヒット単語の1行前を同時に表示している。
- 画像のように検索単語には色が付く(ので検索対象と結果が上下しても気にならないはず・・・まあ入れ替えてもいいが)。
- `-E`を付けているので正規表現での検索もできる(元ネタのコメントより)。

元ネタの@yubaisさんに感謝しつつ、今回はこれで。

## 修正情報
### 2016/12/14
- バッファサイズを超える行が表示される場合、ページャを起動するように修正
- 特記することも無いが、強いて言えば以下の点がポイント
    - lessにカラー表示を表明するため、grepのオプションに`--color=always`を付加
    - lessでカラー表示を解釈するため、lessのオプションに `-R`を付加
    - バッファ内に収まらない時だけページャを起動するためlessのオプションに `-FX` を付加
今更 vagrantをmacに(LAMP環境で)

##インストール
* Virtual box
https://www.virtualbox.org/wiki/Downloads

* vagrant 
https://www.vagrantup.com/
※インストールすると```vagrant```コマンドのPATHが通る


##インストールされたことを確認

```
~ ❯❯❯ vagrant -v
Vagrant 1.9.0
```

## Box選び
https://github.com/chef/bento#64-bit
http://www.vagrantbox.es/

## Box追加
```
~ ❯❯❯ vagrant box add centos-6.8 https://atlas.hashicorp.com/bento/boxes/centos-6.8/versions/2.3.0/providers/virtualbox.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos-6.8' (v0) for provider:
    box: Downloading: https://atlas.hashicorp.com/bento/boxes/centos-6.8/versions/2.3.0/providers/virtualbox.box
==> box: Successfully added box 'centos-6.8' (v0) for 'virtualbox'!
```

## Box確認
```
~ ❯❯❯ vagrant box list
centos-6.8 (virtualbox, 0)
```
## vagrant用のWork Dirを用意〜起動まで
```
mkdir -p ~/Develop/vagrant
cd ~/Develop/vagrant
vagrant init centos-6.8
vim Vagrantfile
```
```vim:Vagrantfile
 29   config.vm.network "private_network", ip: "192.168.33.10" //コメント外す
```
```
sudo vim /etc/hosts
```
```vim:/etc/hosts
192.168.33.10 ore.com
```

```
vagrant up
```

## vagrantの中身(LAMP)
```
sudo su
yum -y update
```
### PHP
```
yum -y install php php-mbstring php-mysql php-devel  // あ、間違えた
rpm -qa | grep php
rpm -e php-devel-5.3.3-48.el6_8.x86_64... // 全部消す
// php 5.6
rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
sudo yum install -y --enablerepo=remi --enablerepo=remi-php56 php php-opcache php-devel php-mbstring php-mcrypt php-mysqlnd php-phpunit-PHPUnit php-pecl-xdebug php-pecl-xhprof
```

### Mysql
```
yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
yum install -y mysql-community-server mysql-community-devel
chkconfig mysqld on
service mysqld start
mysql_secure_installation
```


### Apache
```
yum -y install vim
yum -y install httpd
chkconfig httpd on
vim /etc/httpd/conf.d/ore.conf
```
```vim:/etc/httpd/conf.d/ore.conf
NameVirtualHost *:80
<Directory "/var/www/html/ore.com">
Options FollowSymLinks
AllowOverride All
</Directory>
<VirtualHost *:80>
ServerAdmin info@ore.com
DocumentRoot /var/www/html/ore.com
ServerName ore.com
ErrorLog /var/log/httpd/ore.com/err.log
CustomLog /var/log/httpd/ore.com/access.log combined env=!no_log
</VirtualHost>
```
```
mkdir -p /var/log/httpd/ore.com
mkdir -p /var/www/html/ore.com
echo "<?php phpinfo(); ?>" > /var/www/html/ore.com/index.php

hostname ore.com
vim /etc/hosts
```
```vim:/etc/hosts
127.0.0.1   ore.com localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
```
```
vim /etc/httpd/conf/httpd.conf
```
```vim:/etc/httpd/conf/httpd.conf
402 DirectoryIndex index.html index.html.var index.php
```
```
service httpd start
```

下記をクリック👇 
http://ore.com

※phpinfo()の出力結果が出たら成功

## おしまい
```
~/D/vagrant ❯❯❯ vagrant halt
==> default: Attempting graceful shutdown of VM...
```

[参照]
php5.6インストール方法を参照させていただきました。
http://qiita.com/pakiln/items/645e8a97cde46b59f9f8
10進から2進変換の様々なアプローチ

#はじめに
整数を2進数に変換して表示する場合、
例えばC言語のprintf関数だと書式指定子だけではint型の値を2進数にフォーマット出来なかったりして苦労するかと思います
ここでは2進数に変換表示する4つのアプローチをC言語を例に紹介します

#ループさせる
全ての桁でループさせて答えを出します

##2で割っていく
```sample_a.c
void print_dec2bin(int n, int digit)
{
    int buf = 0;
    int base = 1;

    printf("0b");
    while(n>0){
        buf += ( n % 2 ) * base;
        n /= 2;
        base = base * 10;
    }

    printf("%d\n",buf);
    return;
}
```
- 最も愚直な考え方,2進数を10進数ととらえて2で割っていきながら右から保存していくやり方
- 答えが入る`buf`や今の桁数`base`が**メモリ効率が悪いので値が溢れる危険**がある
- **0詰め**にするためには`base`の値や`buf`の桁数を測って**追加の処理を書かなければならない**

##マスクを取る
```sample_b.c
void print_dec2bin(int n, int digit)
{
    int mask;
    printf("0b");
    for(mask=(0x1<<(digit-1)); mask>0; mask>>=1){
        printf("%d", mask&n ? 1 : 0);
    }
    printf("\n");
    return;
}
```
- 対応桁だけ1が入っている`mask`という変数でひとつづつ左から出していくよう
- 最上位桁を考えないので**0詰めを消すには最上桁を探す部分が必要**となります

#再帰処理を行う
```sample_c.c
void print_dec2bin(int n, int digit)
{
    if(digit==0){
        printf("0b");
    }else{
        print_dec2bin(n/2,digit-1);
        printf("%d",n%2);
    }
    return;
}
```

- 再帰処理の最後の判定を`digit==0`から`n<=0`にすれば0詰めしないようにもできます
- このプログラムの問題点は**上手く改行文字を挟むことができないこと**です
改行文字を挟みたい場合は呼び出し元の先で改行文字を出力するか
改行する関数を挟んで呼び出すしかないみたいです

#フォーマットライブラリを使う
C言語以外のたいていの言語であれば2進数に変化する"%b"や`parse()`等の基数変換関数を持っていますので
**その他の言語であればそれを使うのが無難だと思います**
Jenkins+Seleniumで非推奨の負荷試験をやってみた

本記事は、[Selenium/Appium Advent Calendar 2016](http://qiita.com/advent-calendar/2016/selenium_and_appium)の5日目です。
普段は、テストエンジニアとしてエンプラ系Webシステムの開発に携わっています。

#はじめに
Seleniumでは負荷試験をはじめとするパフォーマンステストを実施することは非推奨です。
「[Seleniumデザインパターン＆ベストプラクティス](http://amzn.asia/1q8qufw)」にも以下の記述があります。
> 結局のところ、パフォーマンステストにSeleniumを使うのは、とんでもない解決策です。もっとシンプルでより良い解決策があります。

でも、手元にSeleniumしかない状態で、対象のシステムがなかなか複雑でJMeterのシナリオ書く時間もないなと思ったので、物理的に複数台マシンを確保して、原始的な負荷試験をやってみました。

#実現方法
##材料 
1. Selenium Webdriverのプロジェクト・・・ Webページを操作するためのテストコード
2. Jenkins ・・・ Mavenを繰り返し実行するためのツール。プラグインと組み合わせて使う(後述)。

##仕組み
以下のような構成としました。
Jenkinsは本当はマスタースレーブ構成にすれば、台数も減らせるし、SeleniumGridを使えば単一マシンで複数実行もできるのですが、組み上げること最優先だったので以下のようにしました。
（太田さんとか玉川(紘)さんが聞いたら怒られそうですね、すみません。。。）
![図1.png](https://qiita-image-store.s3.amazonaws.com/0/89320/44cc408c-45ef-98c6-0bd7-ec942a9b6371.png)

役割としては、JenkinsがMavenを実行して、実行間隔や繰り返し実行を行いました。
Seleniumでは、画面操作とスクリーンショット取得しました。

Mavenで実行するためには[Java+SeleniumなWebアプリケーションの自動テストプロジェクト構築](http://qiita.com/yacchin1205/items/cadc2a724d433511f0a6)を参考にさせていただきました。
Jenkinsでは、Naginatorプラグインを導入して、失敗したときでも再実行されるようにしました。[こちらの記事](http://qiita.com/oh_rusty_nail/items/18ec73bee3f44c38823e)を参考にしました。

##その他工夫点
1. 入力文字列にタイムスタンプを入れて、繰り返し実行可能とした
システムによっては入力値が重複することによって、バリデーションがかかったり

2. サーバそれぞれのJenkinsの実行間隔をずらした
あえて、同時アクセスの試験が目的ではなかったため、シナリオをずらして実行するようにしました。

#結果
当たり前ですが、台数分の負荷をかけることができました。スケールさせるためには、台数分マシンが必要になるため、あまりお勧めできません。それでも、２台のマシンを同時に実行させて、24h、48h、72hと実行させることでサーバ側のリソースの変化が見れたので、実施して効果はありました。

思いがけぬ収穫としては、特定画面で特定の操作を行った際にSeleniumが落ちるという事象が、見られました。詳しく見てみると、排他制御によるタイミング問題だったことが分かり不具合として報告しました。

#まとめ
負荷試験をはじめとするパフォーマンステストには、JMeterを使いましょう。でも、Web画面からSeleniumを長時間かけてみることで、ユーザの手動試験では検出の難しいタイミング不具合などが検出できるかもしれません。
[Elm]Statefulな親子コンポーネント書いてみました

# (2017/08)全体的に修正しました
久々に昔かいたコードを見てみたら「恥ずかしい!黒歴史！」と思ったので全体的に修正しました。。
再校するに当たって色々説明が面倒になったので全体的に以前書いていたテキストを端折ることにしましたが、とどのつまりは状態付きコンポーネントこんな感じで書いてみましたサンプルです。

公式に推奨されてはいませんが。
https://guide.elm-lang.org/reuse/

Elmのバージョンは0.18です。

# つくったもの

## 概要
インターフェースは下記のような感じで、お父さんと双子のお子さんから構成されます。（親子だけに）
![elm-oyako.gif](https://qiita-image-store.s3.amazonaws.com/0/39330/bb1c8e55-6318-7add-38da-071ae66f5c25.gif)

お子さんたちみんなが気分が良いと、お父さんは癒やされてGoodパパになります。
で、一人でも気分が悪いとお父さんは落ち込んでBadパパになっちゃいます。
うーむ、やっぱり円満家庭がいいですねぇ。

## 操作方法

お子さんをクリックで選ぶと、選ばれたお子さんがアクティブになります。
キーボード上下でアクティブなお子さんの気分を変えます。
二人ともHappyになるとお父さんは自動的にGoodパパになります。
お子さんの選択は左右キーでやっても良かったんですが、フローの種類を多くして複雑さを生むためにこうしてみました。

<img width="473" alt="スクリーンショット 2016-12-04 17.04.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/39330/1c85f4f3-018f-5efb-6120-530b9c7c4d4c.png">

# コンポーネント構成

三種類のコンポーネント、三段構成にしています。
Main.elm -> PapaComponent.elm -> SonComponent.elmの順に入れ子になります。
それ以上のModel/Msg/view/updateの分割やドメインオブジェクト的なレコード作ったりはいったんやっておりませんです。
PapaとSonは構造化してDomainModelsに切り出してみました。Papaほぼ空っぽですが。。なぐさめ程度に名前を持たせてみました。。
いちおう将来的には複数の家庭を管理できるような感じのイメージですw

ブツは[こちら](https://github.com/jshosomichi/elm-oyako)となります

※JSネタもちらちら書いているので[インデックス記事リンク](http://qiita.com/hosomichi/items/ad9a9c99a4fda041a563)しておきます。
phina.jsのShapeを画像として使う

# はじめに

この記事では、phina.jsのv0.2を使用しています。
https://cdn.rawgit.com/phi-jp/phina.js/v0.2.0/build/phina.js

# Shape一つだけのものから画像を出力する

ShapeはCanvasに描画しているので、Canvasを取得できれば後は何とでもできます。
ただしShape系のオブジェクトは、インスタンスを生成した時点では、まだ、Canvasに図形が描画されていないので、update前に画像として使いたい場合は、明示的に描画する必要があります。

## v0.2での一番簡単な方法

```js
var canvas = StarShape().flare('enterframe').canvas.domElement;
```
これで星の描画されたCanvasが取得できます。
このCanvasから別タブで画像を開く場合は、`toDataURL()`でURLを取得して、`open()`で開くと良いです。

サンプル
http://runstant.com/simiraaaa/projects/shapeToImage

この方法は、まず、`StarShape`のインスタンスを生成し、`flare`で`enterframe`イベントを強制的に発火させています。
`Shape`系のクラスはインスタンス生成時に、`enterframe`で描画するように設定されるため、これで描画されます。

ただし、今後仕様が変わってくる可能性があるので、実はあまりおすすめできません。

## 少し面倒だけど、次以降のバージョンでも多分互換性のある方法

少し手間ですが、Shapeの仕様が大きく変わらない限り確実に描画できるものも紹介します。

```js

var heart = HeartShape();
heart.render(heart.canvas);
var canvas = heart.canvas.domElement;

```

明示的に、`render`メソッドを呼んでいます。
renderメソッドは、描画対象の`phina.graphics.Canvas`オブジェクトを引数に指定しないといけないため、このような書き方になります。

imageタグで表示するサンプル
http://runstant.com/simiraaaa/projects/shapeToImage2

ぶっちゃけ、デフォルトで自分のCanvasになるようにすればいいのに、と思ってますが、もしかしたら、今後デフォルトで、自分のCanvasになるかもしれません。

そうなれば、
`var canvas = HeartShape().render().canvas.domElement`;
と書けるので楽ですね。

## Spriteにセットする

別にSpriteにセットしなくてもShapeで使えばいいじゃん。
と思うかもしれませんが、例えば、同じShapeを大量に生成する場合など、生成した分のメモリを消費してしまいます。
全く同じShape(弾幕とか)を使用する場合など一度、画像としてキャッシュしておき、Spriteにセットすることで、画像一つ分のメモリで済みます。

やり方はほとんどさっきと同じで、
`heart.canvas.domElement`の部分の`heart.canvas`をSpriteにセットすれば良いです。

```js

var heart = HeartShape();
heart.render(heart.canvas);
var canvas = heart.canvas;
    
// こんな感じ
Sprite(canvas).addChildTo(this).setPosition(300, 400);

```

サンプル
http://runstant.com/simiraaaa/projects/shapeToSprite


# おわりに

複数のShapeをまとめて出力するやつは!?と思った方がいるかもしれませんが、また再来週ぐらいに書く予定です。
超ざっくり説明したので、質問あれば、気軽にコメントしてください。Qiitaのアカウント作るのめんどくさい場合は、[Twitter](https://twitter.com/simiraaaa)でも答えます。

- エラーが出て動かない!
- こういう時はどうやったらいい？
- なんか思った通りに動かないんだけど？
- 記事に書いてある内容が理解できない
- この処理ってどういう意味があるの？

等ほんとに些細な事でも気軽にコメントしてもらって構いません。
New Relicでめっちゃ簡単にRailsアプリケーションの監視をする

advent calendar5日目です。枠が空いていたので書きます。
2日目に書いた[LinuxサーバーをNew Relicで監視する](http://qiita.com/fujitora/items/d968f74d8804f67a33bb)のRails編について書きます。
これも5分くらいで終わります。

## 

- [https://newrelic.com/](https://newrelic.com/)にログインし、AMPを選択
![スクリーンショット 2016-11-26 15.37.26.png](https://qiita-image-store.s3.amazonaws.com/0/95469/9df4b1eb-c266-9746-d2ae-1ade73c6afdc.png)

- Rubyを選択
- 「Reveal license key」のボタンを押してlicense keyを取得
![スクリーンショット 2016-12-05 23.52.21.png](https://qiita-image-store.s3.amazonaws.com/0/95469/4500663b-62c6-3a01-b56a-99340c3b2579.png)

- RailsのバージョンはRails3でOK
![スクリーンショット 2016-12-05 23.52.27.png](https://qiita-image-store.s3.amazonaws.com/0/95469/c7064630-256c-c7dc-5fe9-126a02515473.png)

- RailsのGemfileにgemを追加してbundle install

```
gem 'newrelic_rpm'
```

- newrelic.ymlをダウンロードしてconfig配下に置く
![スクリーンショット 2016-12-05 23.57.39.png](https://qiita-image-store.s3.amazonaws.com/0/95469/cbf378e2-4a31-9adf-2c86-67e4af6bd50d.png)

- newrelic.ymlのlicense_keyにはじめに取得したkeyをコピペ
- デプロイ

## まとめ
めっちゃ簡単。
![スクリーンショット 2016-12-06 0.03.15.png](https://qiita-image-store.s3.amazonaws.com/0/95469/5d69047a-ee8b-5c1b-8d88-edac688cb095.png)

エラー箇所とかcontrollerのアクションごとのトランザクションが分かったり、 DBのクエリの時間が分かったりetc...
通知設定もできるっぽいのでめっちゃ便利そう
名古屋でSORACOMハンズオンセミナー開催しました

#名古屋でSORACOMハンズオンセミナー初開催

SORACOM Airが出た当初から、吉〇さんのFacebookで楽しそうな写真が流れてきて、気にはなっていたのですが、、、
Software Design誌の付録にSORACOM Airが付いていて、気にはなっていたのですが、、、
結局、試すことなく過ぎ去っていく日々でした。

がっ！

わたしが参加しているIoT ALGYANコミュニティと、SORACOMさんがなぜか交流する機会があり、「名古屋に来て~」とラブコールしたところ、なんと来てくれました！！！

[11/20 [名古屋] SORACOMハンズオンセミナー](https://algyan.connpass.com/event/42871/)

* 主催：ALGYAN名古屋支部
* 協力：株式会社ソラコム
* 場所提供：株式会社Misoca

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/6edbb046-99e9-9347-7518-629eeaf6517a.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/86d51387-e583-508e-4a86-5ba289765f04.png)

#その中身は？

前半は、SORACOM入門の講義。
後半は、SORACOM Airのハンズオン。

講義は、これで入門かよーっていう感じ（わたしだけ？）のボリュームでした。わたしは半分くらいでギブアップ。でも、資料提供いただいたので助かりました。
ハンズオンは、さぼってやっていなかった（ごめんなさい）のでアレですが、手順を見る限りでは、簡単に動かすことができるもののようでした。
えっと、詳しくは資料を(ry

> 資料は[イベントページ](https://algyan.connpass.com/event/42871/)にあります。

#満足度は？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/0fcc017a-a872-725d-25f4-f36f40e62846.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/5eb6ea9e-80ec-aeea-5ca1-eba32de9e1d1.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/63331050-0d4d-be42-39d2-70385d2e4197.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/f1e96f48-0f24-238c-2baa-488c65645db9.png)

不満の方がいなくてよかったですｗ

#戦利品

* SORACOM Air SIM
* SIMサイズ変換アダプター
* Misocaステッカー
* チラシ少々（写真なし）

USBドングルも写っていますが、これはもらえません。（ハンズオン時の貸出品）


![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/6d65f31c-dd0a-0e74-ce47-7ce526124fff.png)
メモリのサイズ

MIPSやARMなどでカーネルがメモリサイズを獲得する方法は以下のようなパターンがあります。

* SOC毎のソースでのハードコード
* FDT(dts)から
* カーネルコンフィグレーションのoptionで
* bootから起動時に引き渡された値
* bootがsocに設定した値をレジスタから拾う

この事で、先日ちょっと困った事がありました。

最近いじっている[Mindspeed/arm](http://qiita.com/yamori813/items/b803ba5c80df600931e1)でdtsに書いた値のちょうど倍の値が起動時のログに出力されるのです。

実メモリよりも大きくカーネルが認識していると、立ち上がったとしてもじきに落ちます。

これはu-bootがメモリ情報をカーネルに引き渡していて、カーネルoptionのLINUX_BOOT_ABIが指定されているとsys/arm/machdep.cのlinux_parse_boot_param()でメモリ情報を拾ってdtsの情報と二重に登録してしまうことが原因でした。

FDT_DTB_STATICでdtsを自前で持っている場合memory項目は無いと起動しません。

```
        /* Grab physical memory regions information from device tree. */
        if (fdt_get_mem_regions(mem_regions, &mem_regions_sz, &memsize) != 0)
                panic("Cannot get physical memory regions");
```

横道にそれますが、このpanicはcninit()の前なので、メッセージを見る事ができないので、やっかいです。熟練してくるとコンソールに出なくてもメッセージが見えてきます。(嘘です)

なので、linux_parse_boot_param()のメモリを拾っているところは

```
#if !defined(FDT_DTB_STATIC)

                case ATAG_MEM:
                        arm_physmem_hardware_region(walker->u.tag_mem.start,
                            walker->u.tag_mem.size);
                        break;
#endif
```

が良いような気がします。freebsd-armなMLにポスとしてみましたが、反応ありません。。。

このopetionや関数名のLINUXという名前は、ubootでも良い気がしますが、今さら直すまでの事もでもないですね。

多くのMIPS SOCは0x80000000からメモリがあるのですが、RT2880は0x88000000からになります。このためdtsには0からではなくオフセットの0x08000000を入れます。

```
        memory@8000000 {
                device_type = "memory";
                reg = <0x08000000 0x1000000>;
        };
```

FreeBSDのmipsなどではブートローダーのメモリコントローラーの初期化を期待していて、FreeBSD自体では初期化はしません。そのためブートローダーの認識しているメモリとFreeBSDが認識するメモリのサイズが違っているとpanicすることがあります。

dtsにmemoryを書く場合はdtsiではなくdtsに入れるべきである。これはdtsiはCPUなどのことを書いていて、ボード固有の設定はdtsにあるべきだからだ。

ブートローダーのメモリサイズの設定は、ビルド時に決め打ちや、自動認識など様々。

dtsにmemoryがあってもそのブロックに以下が書かれていないと認識しないようです。

```
+       #address-cells = <1>;
+       #size-cells = <1>;
```

上の問題はarmの人もまったく関心無いみたいです。これはarmはu-bootのセカンドブートローダーを使って、dtbをSTATICではなくセカンドブートローダーからもらうので、問題にならないためだと思います。STATICのことなどもう忘れてしまったのかもしれません。:(
大きな組織で情報共有するためのOSSつくってみた

この記事は、[Fujitsu Advent Calender 2016](http://qiita.com/advent-calendar/2016/fujitsu)の6日目の記事です。

## はじめに

仕事柄、沢山の人が関わるお仕事の効率化に関心があり、プライベートで研究や開発をしています。システム・インテグレーションをはじめ沢山の人が関わるお仕事は、人海戦術で行なわれる事がよくあります。しかし、経験上ITが関わるお仕事の人海戦術はおすすめできません。効率面、品質面、労務管理の面で問題が発生する事が多いからです。

人海戦術にならないようにするには、「人間的な仕事」と「機械的な作業」を切り分けて、**機械的な作業をIT化**するのが近道ではないかと考えています。

## ITの現場における機械的な作業の例
- 情報を記録する（課題とか、バグとか、更新履歴とか）
- 情報を探索する（あの資料どこだっけ？とか）
- 情報を収集する（進捗どうですか？だめですか？とか）
- 情報を転記する（メールからエクセルとか）
- 情報を伝達する（これやっといてとか）
- 情報を集計・分析する（定例会の前日は徹夜とか）

## 機械的な作業をIT化する際、ツールに求められる要件（経験則）
### サクサク動く事
とにかく速度が重要です。上記のような作業は1日に数百件発生する事がありますので、1つの操作に10秒かかるようなツールでは仕事になりません。
### 汎用性・自由度
特定の業務に特化したツール（ガチガチ）では、仕事の変化や多様性に適合しません。一方、エクセルは汎用ツールの神様ですが、メールやファイルサーバと組み合わせて使うので、量が増えると使いにくくなる事が難点です。

## オープンソースソフトウェアを作ってみた
上記のような課題認識から、大きな組織で情報共有するためのOSSを作ってみました。**プリザンター**といいます。快適とか楽しいとか、そういう意味で名付けました。ASP.NET, C#, jQuery, d3.js等を使用し、約2年くらい継続的に開発しています。ソースコード等はGitHubをご参照ください。

[GitHub](https://github.com/Implem)

プリザンターはタスク管理、案件管理、問い合わせ管理などの業務を短時間でWeb化できます。また、編集項目、表示内容、集計方法等を自由にカスタマイズする事ができます。**サクサク動く事と汎用性・自由度に拘って開発**したので、沢山の人が関わるお仕事を快適に出来ると思います。（詳しくは下記リンク参照）

[簡易な業務のWeb化に使えるOSS「プリザンター」作ってみた](http://qiita.com/Implem/items/39ef5be388f40aa21c04)

## 画面イメージ
### サクサク動く管理ツールで快適に仕事しませんか？
![一覧画面.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/a58109a9-18ee-a120-fc0d-82d02f021fcf.gif)
### 自由に項目をカスタマイズして色んな業務をWeb化しませんか？
![カスタマイズ.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/12a31323-f588-0b92-1db7-a2e6e058cfee.gif)
### 進捗管理表を苦労して作るのもうやめませんか？
![ガントチャート.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/22ea31dc-93ae-196e-315d-976e78862111.gif)
### バーンダウンチャートで進捗の全体感をみたくないですか？
![バーンダウンチャート.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/d52879f1-7061-2b95-b3b4-573f9900b9a3.gif)
### 時間で変化がみたい（:older_man_tone1:上司）とか言われてませんか？
![時系列チャート.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/3d54194d-10c5-29ca-97fd-89f2fb26984f.gif)
### いろんなカンバンでタスクをコントロールしたくないですか？
![カンバン.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/5a6f61bf-8a27-df68-bbd2-0f5c6219ae68.gif)
### インターネットみたいにサクサク検索したくないですか？
![キーワード検索.gif](https://qiita-image-store.s3.amazonaws.com/0/78230/11327031-2f80-7b75-6344-b31ac1454670.gif)

## 目指しているところ
日本のサービス業は生産性が低いと言われています。個人的には、IT活用にも少なからず原因があると考えています。ITは導入しただけでは役に立ちません。**ITの導入と併せて仕事のやり方を大きく変える**必要があります。

プリザンターのような情報共有ツールを導入する場合、お客様を含む関係者全員で仕事のやり方を見直す事が重要です。**「お客様のやり方と合わないから」と諦めてはダメ**です。今こそ強い意思をもって関係者全員が生産性の向上に向き合うべきだと思います。

具体的には、**以下のような仕事のやり方があたりまえになる世界**を目指します。

- 管理資料を全てデータベース化しノータイムでアクセスできるようにする。
- 会議用の報告資料を廃止し画面上だけで報告できるようにする。
- 進捗報告は毎朝短時間で行い、週次の進捗会議を廃止する。
- 徹底的にペーパーレス化を図り、印刷や印刷用資料への転記作業を廃止する。
- 電子メールを廃止しWebでコミュニケーションが完結できるようにする。

もちろん、大きな組織においては一筋縄でいかないと思います。それでも賛同者が増えれば少しずつでも変わっていけるのではないかと思います。

## おわりに
沢山の人が関わるお仕事は苦労が絶えません。それでも工夫の余地がいっぱいあるので、すごくやりがいがあります。この取り組みが世の中の役に立つ日を夢見て、今日もVisual Studioでコードを書きたいとおもいます。皆様、よいクリスマスをお過ごし下さい。

:star:**GitHubにスター**つけてもらえたら嬉しいです。
https://github.com/Implem
GolangからMilkcocoaを使う

GolangからMilkcocoaを利用するサンプルを探しても見当たらなかったので作ってみました。

> MQTTクライアントを使うことで、C言語など様々な言語でMilkcocoaを利用できるようになりました
http://blog.mlkcca.com/iot/milkcocoa-mqtt/


と書いてあるので記事中で紹介されているPahoのGolangクライアントを使って書いてみました。

完成したものがこちらです。
https://github.com/kunihiko-t/milkcocoa-go-mqtt-example


glide installで必要なパッケージをインストールした後にメッセージの送受信ができます。


```送信
$ MILKCOCOA_APP_ID=YOUR_APP_ID go run pub/pub.go

Input text and push enter key.
>milk
{"params":{"text":"milk"}}
>cocoa
{"params":{"text":"cocoa"}}
```


```受信
$ MILKCOCOA_APP_ID=YOUR_APP_ID go run main.go

Topic= catiw22khwl/message/push Payload= {"id":"iw81mznpy6AlQEn","ts":1480698470149,"params":{"text":"milk"}}
Text : milk
Topic= catiw22khwl/message/push Payload= {"id":"iw81n2vgP5lBcZn","ts":1480698474316,"params":{"text":"cocoa"}}
Text : cocoa

```

公式ブログに書かれている通りパラメータを設定すると案外サクッと動いてくれました。
kibanaに合ったAWS Elasticsearch Serviceのアクセスポリシーで迷います

この記事は[dots girls Advent Calendar 2016](http://qiita.com/advent-calendar/2016/dots_girls)の記事です。

# AWS ESのアクセスポリシーで迷ってしまう
AWSは基本的にVPCに入らないServiceに対してポリシー（セキュリティ）を設定出来ますが、AWS Elasticsearch Serviceに関してはLambdaと連携してkibanaで表示するなどの場合、デフォルトで選択できるポリシーだと足りないことが多く、かといって例を検索するととりあえず全部許可していたりしているので、どの設定が一番いいのか絶賛模索中です。

## AWSのデフォルトで選択し入力できるポリシー
セレクトボックスで選択できるポリシーです。ただし、アカウント、ユーザー、IPは一つしか入力欄しかありません。少しひねりたい場合はそこからJsonをいじる必要があります。

### Allow or deny access to one or more AWS accounts or IAM users
AWSアカウントもしくは、IAMユーザーによるアクセス制御

### Allow access to the domain from specific IP(s)
送信元IPアドレスによるアクセス制御

### Allow open access to the domain
全部許可

### Deny access to the domain
全部拒否

### Copy access policy from another domain
以前作ったポリシーのコピー

## ポリシーで選択できるActionリスト
LambdaからbulkAPIを使用してデータをアップロードする場合は、`es:ESHttp*`のみで権限は足りるようです。
kibanaから閲覧する場合、`es:ESHttpGet`だけでは無理でした。たぶんDomain系やTag系が関係してるのかと思います。ひとまず`*`で良いと思います。

* es:ESHttpDelete
* es:ESHttpGet
* es:ESHttpHead
* es:ESHttpPost
* es:ESHttpPut
* es:CreateElasticsearchDomain
* es:DescribeElasticsearchDomain
* es:DescribeElasticsearchDomains
* es:DescribeElasticsearchDomainConfig
* es:DeleteElasticsearchDomain
* es:ListDomainNames
* es:AddTags
* es:ListTags
* es:RemoveTags
* es:UpdateElasticsearchDomainConfig

## 私の思う汎用的なAWS ES向けポリシー
現在の最新バージョンは`2012-10-17`です。
kibanaはIP制限などがいいと思いました。自身のグローバルIPは確認くんなどで確認して下さい。
IPやarnはList（`["", ""]`）で複数渡すことも可能です。

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:*",
      "Resource": "arn:aws:es:リージョン:アカウントID:domain/ES名/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "自分のIP"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::アカウントID:role/Lambdaの実行ロール"
      },
      "Action": "es:ESHttp*",
      "Resource": "arn:aws:es:リージョン:アカウントID:domain/ES名/*"
    }
  ]
}
```

## 懸念点
* kibanaは、IP制限掛けてしまうと使い勝手が悪いのではないか

## 目標
* Actionの役割をちゃんと理解してものすごく細かく設定したい

## 参考
[公式ドキュメント（日本語）](http://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-createupdatedomains.html)

ここまで読んで下さりありがとうございました。詳しい人意見下さい。

# dots.女子部について

インフラ、サーバー、フロント開発から運用ノウハウ、女性エンジニアのキャリアについてなどいろいろな観点から勉強したり、情報共有している女性エンジニアのための部活です。
興味がある方は是非SNSアカウントのフォローしてみて下さい！

[Twitter](https://twitter.com/dotsgirls)
[Facebook](https://www.facebook.com/dots%E5%A5%B3%E5%AD%90%E9%83%A8-457992851057604/)

明日は[きょんさん](http://qiita.com/kyuyonkim)よろしくお願いいたします＼(^o^)／
スラッシュコマンド活用術

# GitLabのスラッシュコマンド

[GitLab slash commands](https://gitlab.com/help/user/project/slash_commands.md)
GitLabのスラッシュコマンドをご存知でしょうか？
GitLabで通常、ボタンやドロップダウンで行えるIssuesまたはMergeRequestの一般的な動作をテキストエリアにコマンドを入力することでショートカットする方法です。

スラッシュコマンドを覚えると非常に便利です。

| Command                    | Action       |
|:---------------------------|:-------------|
| `/close`                   | issue または merge request をclose|
| `/reopen`                  | issue または merge request をReopen |
| `/title <New title>`       | タイトルを変更|
| `/assign @username`        | Assignする |
| `/unassign`                | Assignしない |
| `/milestone %milestone`    | milestoneの設定 |
| `/remove_milestone`        | milestoneを外す |
| `/label ~foo ~"bar baz"`   | label(s)の追加 |
| `/unlabel ~foo ~"bar baz"` | Remove all or specific label(s) |
| `/relabel ~foo ~"bar baz"` | Replace all label(s) |
| `/todo`                    | todoに追加 |
| `/done`                    | todoをdoneへ |
| `/subscribe`               | Subscribe :+1: |
| `/unsubscribe`             | Unsubscribe :-1: |
| <code>/due &lt;in 2 days &#124; this Friday &#124; December 31st&gt;</code> | due dateを設定 |
| `/remove_due_date`         | due dateを外す |
| `/wip`                     | Toggle the Work In Progress status |

## 使い方
とっても簡単です。
IssuesやMergeRequestのcommentsの中にコマンドを打ち込みOSXだと`Cmd + Enter`、Windowsだと`Ctrl + Enter`でcommentするだけ

#### 例えばOpenのIssueをCloseする場合

1. `/`を入れるだけでインテリセンスが聞きます。
<img width="820" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/151648/1ed46877-d1a9-4022-e11c-3180a9f9d123.png">

2. `/Close`を選択後comment
<img width="812" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/151648/66cb78ed-c545-7c6e-2239-a830c0b430b4.png">

3. `Your commands have been executed!`というメッセージが表示で完了
<img width="808" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/151648/2af4c828-548e-63b4-80f4-08743f36b9bd.png">

リロードすれば`Closed`になっているのが確認できます。
<img width="816" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/151648/74943751-67b8-7064-382f-ef4e87216626.png">

非常に簡単なので活用していきましょう。特にLabelはよく使います。
「デザイン」タブが表示できなくなった場合の対処方法

# コードはあるのに「デザイン」が表示されない
確かにコードは書いてあるし、ビルドしたファイルを実行するとコード通りの GUI デザインのアプリケーションが起動するけれども、Visual Studio 上ではそのデザインをどうやっても見ることができない。すなわちデザインに手を加えることがもはやできない。そういう状態に陥ってしまったのでその解決策です。

# 「ソリューション エクスプローラー」の表示
まず「ソリューション エクスプローラー」上の表示が他のフォームと比べると何かおかしいです。

![vb_error_01.png](https://qiita-image-store.s3.amazonaws.com/0/72181/258841dc-0321-3165-57d2-58f75509af6a.png)

`Form1.Designer.vb`がルート部分に存在していて、そこに`Form1`がぶら下がっています。`Form1.Designer.vb`のアイコンが「VB」となっています。

この状態で`Form1`をダブルクリックすると、`Form1.Designer.vb`が表示されてしまいます[^1]。

![vb_error_02.png](https://qiita-image-store.s3.amazonaws.com/0/72181/e57ddd0f-2f97-1997-89d0-16054019d4ce.png)

# `.vbproj`ファイルがおかしい
「デザイン」タブを開くための方法を調べるため、どういうワードで検索したらいいのか四苦八苦しましたが、何とかそれらしきページにたどり着きました。

- [フォームがデザイナで表示できなくなった - QA@IT](http://qa.atmarkit.co.jp/q/1698)

上記に書いてあるように、`.vbproj`ファイルの記述内容が誤っていました。`Form1.vb`に関する記述がありませんでした。以下のように`Form1.Designer.vb`の次に`Form2.Designer.vb`が記述されていました。こう記述されていたならば「ソリューション エクスプローラー」の表示が前掲のようになったことに納得がいきます。

![vb_error_03.png](https://qiita-image-store.s3.amazonaws.com/0/72181/246f694d-6119-7c67-309b-4adfc443236b.png)

下記のように`Form1.vb`の部分を追加しました。

![vb_error_04.png](https://qiita-image-store.s3.amazonaws.com/0/72181/3161cbca-2024-2b76-b687-46ef0851a8df.png)

# まだ表示されない
しかしながらまだ「デザイン」のタブが表示されません。このまま永久に GUI を変更できないのかと絶望しましたが、ファイル群の中にそもそも`Form1.vb`が存在しないことに気づきました。それならば`Form1.vb`を作成すればいいはずです。

# `Form1.vb`を作る
`Form1.vb`を作るにしてもその中身はどうすればいいのでしょうか。フォームのコードは全てすでに`Form1.Designer.vb`に書いてあります[^2]。

それならばと、以下のように書きました。

```vbnet:Form1.vb
Public Class Form1

End Class
```

# 「デザイン」タブが復活
上述`Form1.vb`ファイルを作成した後で再びプロジェクトを開くと、「ソリューション エクスプローラー」の表示が期待通りのものになりました。そして`Form1.vb`をダブルクリックすると無事に「デザイン」タブが開きました。

![vb_error_06.png](https://qiita-image-store.s3.amazonaws.com/0/72181/15bb437c-ca9e-a868-e535-a702c8fcf30e.png)

![vb_error_07.png](https://qiita-image-store.s3.amazonaws.com/0/72181/133565db-3284-d126-0479-394e501092f8.png)

これで GUI の修正や追加、削除ができます。

# 原因は分からない
なぜ上記のような状態に陥ったのかは分かりません。Visual Studio をアップデートしたことが原因かもしれませんが、確証はありません。少なくとも自分と同じ症状になった人がネット上にいたということは、おま環事案ではないようです。

もし同じような状況に陥った場合はこの記事の内容を試してみてください。

[^1]: ツリー構造を考えれば当然ではある
[^2]: こういう作りはとても良くないが、それは置いといて
MailCatcher でメールの送受信をテストしよう

お問い合わせフォームや、 ECの注文完了、サンクスメール、メルマガ機能など、メールの送信機能をテストしたい場合に便利なツールをご紹介します。

メール送信関連の機能を開発する際、大量にメールを送信してメールサーバーに怒られたり、携帯キャリアのドメインへの送信など、通常のメールサーバーでは、テストが難しいことが多いです。

この [MailCatcher](https://mailcatcher.me) というツールは、

- テスト用の SMTP サーバーとして使用可能
- 外部にメールを漏らさない
- MailCatcher の SMTP に送信したメールを受信チェック可能

という便利な機能を持っています。

インストール方法
------------------

- *前提として Ruby1.9.3以降 がインストールされている必要があります*
- *Windows でも動きます。*

```bash
### インストール
gem install mailcatcher

### 起動
mailcatcher
```

docker をお使いの方は、以下のコマンドを使用すると良いでしょう

```bash
docker run -d -p 1080:1080 -p 1025:1025 \
  --name mailcatcher schickling/mailcatcher
```

設定方法
--------------

**SMTP サーバーのポート番号に 1025 を指定するだけです。**

EC-CUBE3系をお使いの場合は、 `app/config/eccube/mail.yml` を以下のように設定します。

```yaml

mail:
    transport: smtp
    host: localhost
    port: '1025'
    username: ''
    password: ''
    encryption: null
    auth_mode: null
    charset_iso_2022_jp: false
```

EC-CUBE2系をお使いの方は、 管理画面→パラメータ設定または、 `data/config/config.php` の以下のパラメータを設定をしてください。

- **MAIL_BACKEND** smtp
- **SMTP_PORT** 1025
- **SMTP_HOST** localhost

メールの確認方法
-----------------

送信したメールをチェックするには、ブラウザから http://localhost:1080 にアクセスします。

![スクリーンショット](https://cloud.githubusercontent.com/assets/14028/14093249/4100f904-f598-11e5-936b-e6a396f18e39.png "本家のスクリーンショット")


これを使えば、携帯キャリアのRFC違反メールアドレスもテスト可能です。
また、メールが外に漏れることはないので、顧客にテストメールを送信してしまう、、などのトラブルも防止できます。


その他
--------------

Web API 経由でもメールチェック可能ですので、EC-CUBE3 では、この MailCatcher をユニットテストで活用しています。

興味のある方は [EccubeTestCase クラス](https://github.com/EC-CUBE/ec-cube/blob/master/tests/Eccube/Tests/EccubeTestCase.php#L323) をご覧ください
既存ログからBigQueryのスキーマをGuessする

# はじめに
既存のログからBigQueryのスキーマを推測してくれるツールを作ったので、それを紹介します。

結構複雑なスキーマのログをひとつのテーブルで扱いたいという要件があったので作りました。

# 使い方
[bq_guess](https://github.com/nownabe/bq_guess)というGemで、READMEに書いてあることがすべてです。

例えば次のようなJSON Linesのログがあったとき、こんな感じでスキーマを出してくれます。

```bash
$ cat existing_log.jsonl
{"required":123,"optional":true,"nested":{"required":1234,"optional":"yes"},"array":[0,1,2,3,4]}
{"required":456,"optional":false,"nested":{"required":1234,"optional":"yes","nested":{"prop":1}},"array":[5,6,7,8,9]}
{"required":789,"nested":{"required":1234,"optional":"yes","additional":"added"},"array":[]}

$ bq_guess existing_log.jsonl
[
  {
    "name": "required",
    "type": "INTEGER",
    "mode": "REQUIRED"
  },
  {
    "name": "optional",
    "type": "BOOLEAN",
    "mode": "NULLABLE"
  },
  {
    "name": "nested",
    "type": "RECORD",
    "mode": "REQUIRED",
    "fields": [
      {
        "name": "required",
        "type": "INTEGER",
        "mode": "REQUIRED"
      },
      {
        "name": "optional",
        "type": "STRING",
        "mode": "REQUIRED"
      },
      {
        "name": "nested",
        "type": "RECORD",
        "mode": "NULLABLE",
        "fields": [
          {
            "name": "prop",
            "type": "INTEGER",
            "mode": "REQUIRED"
          }
        ]
      },
      {
        "name": "additional",
        "type": "STRING",
        "mode": "NULLABLE"
      }
    ]
  },
  {
    "name": "array",
    "type": "INTEGER",
    "mode": "REPEATED"
  }
]
```

インストールはいつもどおりです。

```bash
gem install bq_guess
```

今のところ、JSON Linesに対応してます。

# おわりに
手元の用途だとRECORDとNULLABLEだらけの数千行のスキーマを吐けたのでそこそこ動くんではないかと思います。

ただ、実装がかなり雑なのと自分用にチューニングしてあるのとで、まだまだ何かありそうです。
何かあれば[こちら](https://github.com/nownabe/bq_guess/issues)まで報告していただけると幸いです :sweat_smile:
D3.js　CSVデータを読み込む

### この記事でやること

* D3.jsでCSV形式のデータを読み込みます
    * 元データ：CSVファイル（別ファイルに分割）
    * ファイルはUTF-8で記述しましょう
* 読み込んだデータを一行ずつ表示します

### ソースコード

#### HTML

```html:index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3.js CSVファイルを読み込む</title>
</head>
<body>
<!-- 一覧表の描画先-->
<div id="data"></div>
</body>
<!-- D3.js -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- 本体処理 -->
<script src="main.js"></script>
</html>
```

#### JavaScript
```javascript:main.js
// 読み込みデータファイル
var DATA_FILE_PATH = './data.csv';
// 一覧描画先
var TARGET_ELEMENT_ID = '#data';
// 項目名：漢字表記
var COL_KANJI = 'kanji';
// 項目名：かな表記
var COL_KANA = 'kana';
// 項目名：色ID
var COL_COLOR_ID = 'color';

drawTable();

/**
 * データ一覧の描画
 */
function drawTable() {
    d3.csv(DATA_FILE_PATH, function(error, list){
        // 第2引数のlistの中に読み込んだデータがある
        
        d3.select(TARGET_ELEMENT_ID)
            .append('div')
            .selectAll()
            .data(list)
            .enter()
            .append('div')
            .text(function (dataRow) {
                // 読み込んだデータを参照する場合はコールバック関数を通す
                return dataRow[COL_KANJI]
                + '（' + dataRow[COL_KANA] + '）'
                + '：' + dataRow[COL_COLOR_ID];
            });
    });
}

```

#### データファイル（CSV）
一行目がデータ項目名になり、これをキーとしてスクリプト内で取得を行います。

```text:data.csv
kanji,kana,color
青,あお,blue
赤,あか,red
緑,みどり,green

```

### 結果

読み込んだ内容がテキストで表示され…特に何も面白くないでしょうか？
今は別ファイルのデータを読み込むことができた点を素直に喜びましょう。
Infrastructure as Codeで見えてきたLint Infrastructure

この記事は[Lint Advent Calendar 2016](http://qiita.com/advent-calendar/2016/lint)の6日目の記事です。
本記事では、インフラもLintしませんかという提案と、そのために今作っているツールの紹介をします。

# TL;DR
- Infrastructure as Codeによってソフトウェア開発の良いプラクティスが活用できるようになった
- つまり、Lintの知見もインフラに活用できるはず
- 試しにTerraformのテンプレートをLintする[TFLint](https://github.com/wata727/tflint)を作りました

# Infrastructure as Codeがもたらした恩恵
Infrastructure as Codeは既に広く知られるようになった考え方だと思います。ここまで普及したのは、AWSなどのIaaSの存在ももちろんあったと思いますが、ソフトウェア開発におけるGitによるバージョン管理や、PR駆動開発などの良いプラクティスが広く開発者に受け入れられていたことが背景にあったかなと考えています。
歴史の話や、Infrastructure as Codeの考え方の話は、以前[mizzyさんが書かれていたブログ記事](http://mizzy.org/blog/2016/04/22/1/)がすごくわかりやすいので、そちらを読むと良いです。

# ソフトウェア開発現場におけるLintの活用
一方で、ソフトウェア開発の現場ではCIやバージョン管理ほどスタンダードにはなっていませんが、Lintツールが活用されている現場もあります。
例えば、Rubyで言えば[RuboCop](https://github.com/bbatsov/rubocop)を使って複数人での開発時に共通のスタイルガイドに従うことを保証したり、[Rails Best Practices](https://github.com/railsbp/rails_best_practices)を使って、ベストプラクティスに従わないコードを予め検知したり、大まかに言えば、人が確認するまでもない問題や、細かなチェックを自動化するという試みに使われています。

個人的な話をすると、最近、React+Redux+ES2015を使ったフロントエンドの開発を行なう機会があって、社内にあまり知見を持ったエンジニアがいなかったのですが、[ESLint](https://github.com/eslint/eslint)を定期的に回しながら開発することで、ある程度バッドプラクティスを回避することができました。

ただ、Lintには大多数（または一部の開発者）が良いと思う思想や哲学を元に指摘するものが多いので、Lintが嫌い、肌に合わないという人も結構いらっしゃいます。この辺はまだまだ解決するべき問題が眠っているかなと思います。

## InfrastructureをLintする
前述したように、Infrastructure as Codeはソフトウェア開発のプラクティスをインフラに取り込むものです。つまり、きっとLintも適用できるはずです。インフラの構成や使用方法などのベストプラクティスを集約して、誰でもよりよい構成を作ることができるのでは！？と考えました。

そうして生まれたのが[TFLint](https://github.com/wata727/tflint)です。

## TFLint
名前の通り、TerraformのテンプレートをLintするものです。テンプレートはHCLという独自言語で書かれているのですが、パーサーが公開されているので、これを使いました。パーサーがGo言語で実装されているので、TFLintもGo言語で書かれています。

使い方はREADMEを読んでいただければなんとなくわかると思うのですが、大雑把に言えば、Terraformを実行するディレクトリ下で実行することで、Terraformが読み込むテンプレートをチェックして、問題があれば指摘を出します。

```
$ tflint
template.tf
        WARNING:3 "t1.micro" is previous generation instance type.

Result: 1 issues  (0 errors , 1 warnings , 0 notices)
```

上記の例だと、非推奨になっている旧世代のインスタンスを選択していることが問題として指摘されています。
他にも存在しないインスタンスタイプが選択されていることを検知したり、`terraform apply`時にエラーになるような問題を弾くための指摘もあるのですが、詳しくはドキュメントを見てもらえればと思います。

### 生まれた背景
なぜTerraformなのか、というと、実はTerraform独自の事情としてDry-runとして機能する`terraform plan`があまり厳しくないという背景があります。例えば、AWSで存在しないようなインスタンスタイプを起動しようとしても、`terraform plan`ではエラーにならず、`terraform apply`時に初めてエラーになります。

これが結構辛いなぁと感じていて、本家での解決も難しそうだったので、何か静的解析でチェックするツールを作ろうと思い立ちました。加えて、ベストプラクティスに従わないものも弾けるようになるといいね、という感じで今作っています。

## 今後
しばらくTerraformのGoogle Groupsとか覗きつつ、良さそうなものを追加していきたいなぁと思っていますが、どのくらい効果的に機能するかは全然わかりません。ソフトウェアと大きく違うのは、ベストプラクティスに従っていないからといって、すぐに直すのが難しいというのがあるかなと思っているので、その辺は微妙かもしれません。しばらくはTerraformでエラーになるような記述をちゃんと検知できるものを目指していけるといいかなぁと思っています。

Terraformに限って言えば、知見がなかなか集まっている場所が無いにも関わらず、みんな一度は何らかのハマった経験があると思うので、そういったものを集約できる何かがあるといいなーと漠然と思っています。
Vim 8.0 Advent Calendar 6 日目 パッケージ

この記事は [Vim 8.0 Advent Calendar](http://qiita.com/advent-calendar/2016/vim8) の 6 日目の記事です。

Vim のパッケージ機能を使うことで、簡単なプラグインの管理を行うことができます。

## パッケージとは

まず、パッケージ機能におけるパッケージとはどんなものかについて説明します。
1 つのパッケージは、複数のプラグインを含んでいます。また、プラグインはそれぞれ、Vim 起動時に読み込まれるか、あとから指定して読み込まれるかに分けられます。
パッケージは以下のようなディレクトリ構造になっています。

```
package/
|- start/
|  |- plugin1/
|  |- plugin2/
|  `- plugin3/
`- opt/
   |- plugin4/
   |- plugin5/
   `- plugin6/
```

`start/` ディレクトリ以下にあるものが Vim 起動時に読み込まれるプラグインで、`opt/` ディレクトリ以下にあるものがあとから指定して読み込まれるプラグインです。
`plugin1` `plugin2` などがプラグイン名になります。この名前は後から読み込む際に指定する名前になります。

## パッケージを配置する

パッケージは、`'packpath'` オプションで指定されたディレクトリの中の `pack/` ディレクトリ内から探されます。
`'packpath'` の初期値は `'runtimepath'` の初期値と同じです。

具体例を挙げて見ていきます。
`~/.vim` などが `'packpath'` の 1 つとして登録されています。
この中の `pack/` ディレクトリ内の、パッケージ名のディレクトリにパッケージを配置します。
つまり、パッケージ名を `pack1`、`pack2` とすると、以下のようになります。

```
~/.vim/
|- pack/
|  |- pack1/
|  |  |- start/
|  |  `- opt/
|  |- pack2/
|  |  |- start/
|  |  `- opt/
:  :
```

このようにパッケージ、およびその中のプラグインを配置しておくことで、Vim は起動時、vimrc ロード後のプラグイン読み込み前に、各パッケージの `start/` ディレクトリ内のプラグインを `'runtimepath'` に自動的に追加し、その後プラグインを読み込みます。

## オプショナルなプラグインのロード

`opt/` 以下のプラグインは、`:packadd` Ex コマンドを使うことでロードできます。

```
:packadd plugin4
```

プラグイン名(=プラグインのディレクトリ名)を指定することで、未ロードだった場合はロードされます。プラグインは `'runtimepath'` に追加され、プラグイン内の `plugin/**/*.vim` ファイルがロードされます。

また、vimrc 内からロードする場合は `:packadd!` を使います。`!` を付けると、`'runtimepath'` への追加のみが行われ、ロードはスキップされます。vimrc 内の場合、その後で別途ロード処理があるため、その場ではロードしないようにこちらを使用します。

## パッケージの用途について

パッケージは Vim に標準で入った簡易プラグイン管理システムです。標準であることが強みでしょう。あまり多くのプラグインを使っていない人などは、この機能で十分な人もいるでしょう。
また、パッケージは見た限りだと、パッケージ単位でのプラグインの配布なども想定されていそうです。ディストリビューションなどでの配布や、関連したプラグインをまとめたものをパッケージにする用途が考えられます。

一方で、パッケージ機能はロード周りの世話はしてくれますが、昨今のプラグインマネージャプラグインが行ってくれるような、プラグイン自体のインストールや更新は行ってくれません。このレベルでプラグインを管理したい人は、やはりプラグインマネージャプラグインを利用するのが良いと思います。
CData Software が対応している製品のリスト（2016/12現在）

CData のデータドライバーの対応データソースリスト(2016/12現在）
詳細はこちら：[CData Driver リスト](http://www.cdata.com/jp/drivers/)

#CRM/SFA/Marketing#
1. Salesforce
2. Microsoft Dynamics CRM
3. NetSuite
4. SugarCRM
5. OracleCRM**
6. Highrise CRM**
7. Zoho CRM
8. Google Analytics
9. Google AdWords
10. Oracle Eloqua
11. HubSpot
12. Marketo
13. MailChimp*
14. SendGrid*
15. YouTube*
16. YouTube Analytics*
17. Magento*

#Accounting#
18. Microsoft Dynamics GP
19. Sage 50
20. Xero Accounting
21. Exact Online
22. FreshBooks
23. QuickBooks
24. Money Forward*
25. Freee
26. Reckon*
27. Intacct*
28. ServiceNow*
29. JIRA*
30. Smartsheet.com*
31. Microsoft Project*

#Groupware & ERP#
32. Microsoft SharePoint
33. SharePoint Excel Service
34. Google Apps
35. Basecamp**
36. WordPress**
37. Kintone**
38. Microsoft Dynamics GP
39. Microsoft Dynamics NAV
40. Microsoft Dynamis AX
41. NetSuite CRM & ERP
42. SAP NetWeaver

#DB#
43. Amazon DynamoDB
44. Amazon SimpleDB
45. Google BigQuery
46. Azure Table
47. Apache Cassandra
48. HPCC ECL Queries
49. MongoDB
50. Couchbase
51. Microsoft SQL Server
52. Oracle**
53. MySQL
54. SQLite
55. Microsoft Access
56. Microsoft Active Directory
57. HBase*

#REST Services#
58. OData
59. JSON
60. XML

#Document & File Formats#
61. Microsoft Excel
62. Google Sheets
63. CSV/TSV*
64. xBase*

#SNS#
65. Force.com*
66. Twitter
67. Facebook
68. LinkedIn**

#Networking & Auth#
69. LDAP
70. OFX Transactions*
71. Email
72. RSS

#Financial & E-Commerce#
73. Authorize.NetSuite*
74. Square*
75. eBay*
76. PayPal*
77. Stripe*
78. E*TRADE*
79. OpenExchangeRate**
80. Quandl*

#Uncategorized Sources#
81. Twilio*
82. Gmail
83. PowerShell**
84. Bing Search**
85. Bullhorn CRM**
86. Microsoft Exchange
87. Google Search**
88. Oracle Sales Cloud**

**は、CData Software （米国）のみの取り扱い
***はComing Soon。
Zabbix での簡易温度監視-その2

昨日 Windowsで温度データを取得しZabbixに送ることが出来ました。
今日はそれを使って何かしてみたいと思います。

# 高温時の対応・対処（ここからが本題ぉ）
温度の取得が出来たら、次は高温に成った場合に警報を管理者に送らないといけません。
そう無ければZabbixで値を取得しても意味が余り有りませんからね (^.^)v

先ず基本の基本、トリガーを作成します。
![警報.png](https://qiita-image-store.s3.amazonaws.com/0/150917/c12b2775-feed-0f6c-1006-46d26ac83df9.png)
今回トリガーに使うキーはケース内温度を使います。
こちらが50度を超えた場合に重度の障害として管理者にアラートを送るようにしました。
又家には物理Serverが2台あるので勿論トリガーも2台分作成することを忘れてはいけません。

トリガーが発動するには勿論アクションも必要なので登録しましょう。
![アクション.png](https://qiita-image-store.s3.amazonaws.com/0/150917/1732e5b3-60b4-6d40-dfe3-6172c210a268.png)
Server本体の温度が上がるのは負荷が高まった状況が続くか室内の温度が上昇した場合ですね?
正常な負荷が続くなら止める訳に行きませんから室内の温度を下げるしかありません。
とは言えデータセンターのように24365で空調が効いている所なら困りませんが
個人宅でそんな高コストをブチかます余裕が無いので、必要に応じて室内温度を冷やす必要があります。
と言うことでケース内温度が50度を超えたら室内を冷却するようにします。

何やら「室内の熱開放」と言うアクションが二つありますね。
気が付きましたか?
そうです今回も「お約束の」管理者の手を煩わせず **自動化をやってる訳です。**
自分が会社に居ながらにしてServerを置く部屋の温度を下げる事が出来る様にしています。

この時に頑張ってもらうのが、いつも家に居るうちの**ミクさん（嫁）**という訳です。


そしたらアクションの中身はと言いますと・・・・・
![アクション-admin.png](https://qiita-image-store.s3.amazonaws.com/0/150917/c73c445e-d732-49a5-a940-c4f6c7c68236.png)
自分にはこの様にトリガー発動時とリカバリーメッセージをセットにして
室内が冷えてケースの温度が冷えた事まで確認が出来るようにしてます。
（最悪の場合、電話でミクさん（嫁）を呼び出す必要も有りますからｗ）

続いて実際に動いてもらうミクさん（嫁）には・・・・
この様にしてみました。
![アクション-ミク.png](https://qiita-image-store.s3.amazonaws.com/0/150917/531d77b7-19a2-638d-0303-9f9b4110d7bb.png)
はい、シンプルにお願いを上げてるだけですw
目的が達せらたら良いので穏便&シンプルにお願いするのです。
勿論、お気づきの方はミクさん（嫁）のアクションを作った後で自分へのアクションを作ったのか良く分かります・・・
自分の分は後回しでも良いのです、目的を達成することが第一ですから（ｷﾘｯ

![アクション-ミク2.png](https://qiita-image-store.s3.amazonaws.com/0/150917/099829fc-e03b-162d-d8ee-2fe7e90e4884.png)
しかし、室内が冷えて貰わねば意味がありません！
ですから穏便なメールを10分間隔で3回送る事で、確実に行動して貰うようにしてます。

![メール.png](https://qiita-image-store.s3.amazonaws.com/0/150917/0c2876a3-b62c-2ff2-dfb9-3ec539f2e9d0.png)
勿論メール配信時刻も注意します。
朝早くや夕方には必要が無いので昼間だけ配信出来るように
そしてその他のエラーメッセージは届かないように注意しました！

彼女に拗ねずにやってもらう為にここまで気を使う管理者（夫）って一体・・・・・・


#結果は?
ここまで準備しまくってますが、実際に今年の夏はどうだったかと言うと
5ヶ月分のグラフを見返します・・・・・
![TEMP.png](https://qiita-image-store.s3.amazonaws.com/0/150917/f4f8f969-ec75-2099-972c-0ca40834b10b.png)
最大47℃
 **残念ながら発動していません！　今年はギリギリで乗り越えています、残念！！！**
今年はリアルでは発動する事がありませんでした。
逆に言えばそれだけ無事に夏を乗り越えられた訳ですけど
日中35度に達する度、メールが来るかどうか楽しみにしてたのに一度も届かないので
設定が失敗したかとVPNで自宅に接続し何度も設定を確認してました。

そろそろ秋がやって来そうな9月に一度テストはするべきだろうと言う事で
アイテムの中に有る「乗数を使用 0.01」のチェックを外してみました。
表示温度は4200度と太陽の表面温度みたいな値が出てきますw
結果トリガーは正常に発動！　勿論自分にもミクさんにメールが届きました。 
ミクさんには **3回** きっちりと送られてます。
届いたメールを見たミクさん曰く
「昼間変なメールが届いた～～　だけど送り主も分からず、文面も訳が分からないので無視してた。」と言うオチに・・・
この話を聞いた後、俺は改めてメールの重要性を延々と話し納得してもらいました。
来年こそは正常に発動して部屋の温度が下がるのを見てみたいです。
（そもそもそこまで温度が上がらないようにしなさいって！）

明日は7日目 再び池田さんです。
宜しお願いします。
FileMaker API for PHP を利用する準備（インストール）

# FileMaker API for PHP を実際に利用する
すでに「カスタム Web 公開 with PHP」などの設定は済んでいるとします。その上で、「FileMaker API for PHP」を利用するための準備をしましょう。

# 「FM_API_for_PHP_Standalone.zip」をコピーする
「FileMaker API for PHP」の実体（ライブラリ）である「FM_API_for_PHP_Standalone.zip」をまずは入手しましょう。[公式ドキュメント](http://filemaker-jp.custhelp.com/app/answers/detail/a_id/9119)によれば、以下の場所に保存されています。

> ●IIS（Windows）の場合：
>    <ドライブ>:\Program Files\FileMaker\FileMaker Server\Web Publishing\FM_API_for_PHP_Standalone.zip
>     * <ドライブ>は、FileMaker Server の展開時にWebサーバコンポーネントが配置されたドライブとなります。
> 
>   ●Apache（Mac OS）の場合：
>     /ライブラリ/FileMaker Server/Web Publishing/FM_API_for_PHP_Standalone.zip

この「FM_API_for_PHP_Standalone.zip」を、利用するディレクトリにコピーします。ちなみにこの中のコードは、ここ最近のバージョン内では変更が無いようです。

# 解凍して配置する
zip ファイルを解凍し、適切な場所に配置しましょう。例えば`/opt/fm_api/`で利用するならば、このディレクトリに直接か、あるいはさらに一つディレクトリを作って`/opt/fm_api/lib/`などに展開してもいいでしょう。

# PHP で require してコードを書く
あとはコードを書くだけです。ライブラリのルートにある`FileMaker.php`を`require`すれば、全てのクラスやメソッドが使えます。以下は`require`の例です。

```php
<?php
require_once('./lib/FileMaker.php');
```
デッドロック対策

2PLでもS2PLでもロックを獲得・開放する順序の話を規定しているだけで、そのままカジュアルに走らせると悲惨な問題に直面する。デッドロックである。

Tx1: Write(x) Write(y)
Tx2: Write(y) Write(x)

という2つのトランザクションは、**2PL**に沿ってロックを記述すると

Tx1: **Lock(x)** Write(x) **Lock(y)** Write(y) Unlock(x) Unlock(y)
Tx2: **Lock(y)** Write(y) **Lock(x)** Write(x) Unlock(y) Unlock(x)

このようにLockがそれぞれ書き込みの前に追加される。
この二つのトランザクションが並行して走ると、無事にどちらも完走する場合もあるが、停止して動かなくなることもある。

Tx1: **Lock(x)** Write(x) **Lock(y)**
Tx2: **Lock(y)** Write(y) **Lock(x)**

それぞれのトランザクションがここまで進んだ段階で、Tx1はLock(x)を握りしめたままLock(y)が獲得可能になるのを待ち、Tx2はLock(y)を握りしめたままLock(x)が獲得可能になるのを待つ事になる。これが典型的な**デッドロック**である。

## Dead Lock Prevention

デッドロックが起きる際には必ずロック獲得待ちが発生している。
なので獲得待ちが発生した瞬間にアボートしてしまえば、デッドロックは起きなくなる。
その一方で、本当はあと1クロック待てばロックが取れたかも知れない場合であっても構わずアボートしてしまうため、常に最善かというとそうでもないが、実用上馬鹿にできない速度が出ることも多い。
有名なものはWait-DieとWound-Waitで、これらはそれぞれ「ロックを取りながら走るが、取ろうとしたロックがすでに専有されていた場合にどうする」という挙動を表している。トランザクションがそれぞれ開始時にタイムスタンプを獲得するという前提を置いている事が多い。

### Wait-Die

進行中のトランザクションが獲得しようとしたロックが既に他のトランザクションによって専有されていた場合、そのロックを握っているトランザクションのタイムスタンプと自分のタイムスタンプを比較し、自分のタイムスタンプのほうが古い（≒完了までの優先度が高い）場合に **該当ロックが解放されるまで待つ** プロトコル。そうでない場合、つまり自分のタイムスタンプのほうが若かった場合は**即座にアボート**する。
注意して欲しいのは、これはデッドロックが起きていなくてもアボートするという事である。
単純に全体がこのルールに従って動けば、全員が待つという状態に陥らないという事を保証してくれる。
ちなみに実測した感覚で言うとアルゴリズムとして簡単に記述できるお陰かベンチマークによってはもう全部これで良いんじゃないかと言える程度に優秀な成績を残すこともある。

### Wound Wait

進行中のトランザクションが獲得しようとしたロックが既に他のトランザクションによって専有されていた場合、そのロック握っているトランザクションのタイムスタンプと自分のタイムスタンプを比較し、自分のタイムスタンプのほうが古い（≒完了までの優先度が高い）場合に **相手トランザクションをアボートさせる** プロトコル。そうでない場合、つまり自分のタイムスタンプのほうが若かった場合は**開放されるまで待機**する。
「撃っていいのは撃たれる覚悟のある奴だけだ」の言葉にもあるように、自分以外のトランザクションをアボートさせる、ということは自分自身も突然アボートさせられる可能性もあるので適宜自分の状態を監視しながらトランザクションを実行させる必要があり、実装がこっちはやや面倒である。

Wait-DieとWound-Waitは混在させて使う事ができない。もし混在させた場合、タイムスタンプの古いトランザクションT1が若いトランザクションT2が抱えたロックをWait-Dieに従って待つ一方で、トランザクションT2が年上のトランザクションT1の抱えたロックが解放をWound-Waitに従って待ってしまいデッドロックが発生する。

ちなみに上記の2つの説明ではタイムスタンプを用いたが、亜種として「より多くのロックを抱えているトランザクションが優先」「より多くのアボート回数を重ねてきたトランザクションが優先」などなど様々な優先度の基準があり、それらを適当な割合で組み合わせた亜種なども存在しうる。

### No-Wait

ロックを獲得しようとtry-lockした際にロックが取れなかったら即アボートするというスキームである。実装が単純ゆえか割と侮れない性能が出て新しいデッドロック回避プロトコルを開発する研究者を困らせる事がある。これはWait-DieやWound-Waitと混在させて使ってもデッドロックを引き起こさない。

## 待ちグラフ

よくデータベースの教科書に出てくるデッドロック回避手段である。
僕はこれに関して詳しくないので詳しくは書かないが、自分が獲得したいロックが何なのかを他スレッドから見れるようにする必要があるのでオーバーヘッドはそれなりにありそうである。詳しく調べて書きたくなったら追記するかも。

## DreadLocks

[2008年の論文](http://dl.acm.org/citation.cfm?doid=1378533.1378585)で提案された技法である。(Dreadlocksという言葉自体は髪型の一種で、それに引っ掛けた名称と思われる）

- 基本的にはSpin-Lockだが、ロックを獲得した際にビットを立てるのではなく自スレッドのロック情報へのポインタへとロックを書き換える。
- 確保済みロックを後から獲得しに来た別のスレッドは、ロックが獲得されているのを見て、ロック情報ポインタを辿る。
- 辿ったロック情報ポインタの中に自分が所有済みのロックが含まれていたらabort

という手順で、Spin-Lockに多少の追加コストで可能としている。
基本がTATAS-Lockなのでマルチスレッド向けにスケーラブルにするのは大変そうである。
ロックの種類についての話を書きそびれていた事に気づいたのでそのあたりは後日のアドベントカレンダー記事にする。

## Conservative Two Phase Lock

トランザクション開始時にそのトランザクションが必要とするロックをすべて獲得してしまう作戦。獲得すべきロックがすべて明らかになっているならば、その獲得したいロック群から何らかの順序で（例えばメモリ上でのアドレス順とか）でロックを獲得すれば、全トランザクションが同じ順序でロックを獲得することになるのでデッドロックは発生しない。
とはいえ、トランザクション開始時に必要なロックが全てわかっている状況というのはあまり一般的ではない上、開始時から握る手前ロック獲得期間が間延びしがちで並列度があまり上がらない欠点もある。
後述するOptimistic Concurrency Controlでも同様の作戦を取る事でデッドロックを回避することがあるが、長くなるので後日記述する。