OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsでの型比較について

https://msdn.microsoft.com/ja-jp/library/7wkd9z69(v=vs.94).aspx


javascriptでは　String Number Boolean　の3つのプリミティブなデータ型があると書いてあったが、比較する時にどういう挙動をするのか実際にソースに書いて試してみた

```app_1.js
 'use strict';
 
 var main = function(){
     var type_number = 123;
     var type_boolean = true;
     var type_string = 'abc';
     console.log(typeof(type_number));
     console.log(typeof(type_boolean));
     console.log(typeof(type_string));
     
     console.log(typeof(type_number)  ==  'number' );    // true
     console.log(typeof(type_number)  ==  'Number' );    // false
     console.log(typeof(type_number)  === 'number' );    // true
     console.log(typeof(type_number)  === 'Number' );    // false
     console.log(typeof(type_number)  === Number   );    // false
     console.log(typeof(type_number)  === number   );    // error
     console.log(typeof(type_boolean) ==  'boolean');    // true
     console.log(typeof(type_boolean) ==  'Boolean');    // false
     console.log(typeof(type_boolean) === 'boolean');    // true
     console.log(typeof(type_boolean) === 'Boolean');    // false
     console.log(typeof(type_boolean) ==  Boolean  );    // false
     console.log(typeof(type_boolean) === boolean  );    // error
     console.log(typeof(type_string)  ==  'string' );    // true
     console.log(typeof(type_string)  ==  'String' );    // false
     console.log(typeof(type_string)  === 'string' );    // true
     console.log(typeof(type_string)  === 'String' );    // false
     console.log(typeof(type_string)  ==  String   );    // false
     console.log(typeof(type_string)  ==  string   );    // error
 };  
 main();
```
> number
> boolean
> string
> true
> false
> true
> false
> false
> true
> false
> true
> false
> false
> true
> false
> true
> false
> false

typeofしたものは'string'とか'number'とか'boolean'とか、頭が小文字になるようにしないと一致しないらしい。


ついでに変数に入るObjectとArrayとFunctionも試してみた

```app_2.js
'use strict';

var main = function(){
    var type_object = {key1 : 123, key2 : true, key3 : 'abc'};
    var type_array = [12, 34];
    var type_function = function(){
        console.log('nice boat');
    };
    console.log(typeof(type_object));
    console.log(typeof(type_array));
    console.log(typeof(type_function));

    console.log(typeof(type_object)   ==  'object'   );    // true
    console.log(typeof(type_array)    ==  'object'   );    // true
    console.log(typeof(type_function) ==  'function' );    // true
};
main();
```
> object
> object
> function
> true
> true
> true


なるほど、Arrayは'object'と認識されるのかと理解。さらにFunctionは'function'になるらしい。

まぁ型の比較がわかったところでどうしたというわけでもないが・・・
ムーコのフォントでコードを書いてみる

6月5日は『ムーコの日』ということで、期間限定でムーコフォントなるものが無料ダウンロード出来るようになっています！ムーコ好きの私は、即行でダウンロード。
[ムーコフォント](http://mksd.jp/muco.html)

ひらがな・カタカナ・アルファベット・数字と、あとは簡単な記号のみで、商用利用も不可ということで、そこまでガツガツ使いこなすものでも無く、あくまでイベント用というカンジなのですが！
これでコードを書いてみると・・・
<img width="1102" alt="スクリーンショット 2015-11-01 19.09.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/59687/4a9d72ce-35cb-af47-c368-c8cbcc3613eb.png">

カワイイ… :heart::heart: 
これは萌えるっ・・・！
Module のメソッドオーバーライドに Module#prepend を使う

Module のメソッドをオーバーライドする場合、クラス内に定義することもできますが、オーバーライドしていることを分かりやすくさせるため Module#prepend を使ったりします。加えて prepend であればメソッド呼び出しの優先順も高いため確実にオーバーライドしたメソッドが呼び出されることも保証されます。

## Module#include

prepend に入る前に include について。
例えば以下のような Module があった場合

```rb:base_module.rb
module BaseModule
  def self.included(base)
    base.extend(ClassMethods)
  end

  def instance_method
    puts 'included_instance_method'
  end

  module ClassMethods
    def singleton_method
      puts 'included_singleton_method'
    end
  end
end
```

ここで、self.included で ClassMethod を extend しないと、この Module を include したクラスで singleton_method を呼び出した時に NoMethodError となります。base.extend することで Module のメソッドを特異メソッド（クラスメソッド）として使えるようにしてくれて、include したときにインスタンスメソッドとクラスメソッドも追加できます。
この Module を使いたいクラスで、

```rb:current_class.rb
class CurrentClass
  include BaseModule
end
```

と include すれば

```rb
# instance
current_class_obj = CurrentClass.new
current_class_obj.instance_method  #=> "included_instance_method"

# singleton
CurrentClass.singleton_method  #=> "included_singleton_method"
```

インスタンスメソッドもクラスメソッドも期待通りに呼び出すことができます。


## Module#prepend

上記の Module クラスの特異メソッドである singleton_method をオーバーライドしたい場合、base_module.rb 内に singleton_method を定義しても良いのですが、Module#prepend 使ったほうが「Module のメソッドをオーバーライドしてるよ」というのがわかりやすくて良い気がしています。

```rb:base_module_extention.rb
module BaseModuleExtention
  def self.prepended(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def singleton_method
      puts 'prepended_singleton_method'
    end
  end
end
```

今回のようにオーバーライドしたいメソッドがクラスメソッドだった場合、self.prepended で extend を呼び出す必要があります。

```rb:current_class.rb
class CurrentClass
  include BaseModule
  prepend BaseModuleExtention
end
```

オーバーライドできているか確認します。

```rb
# instance
current_class_obj = CurrentClass.new
current_class_obj.instance_method  #=> "included_instance_method"

# singleton
CurrentClass.singleton_method  #=> "prepended_singleton_method"
```

ちゃんと prepend した BaseModuleExtention のメソッドが呼ばれてます。
ancestors を見ても、

```
BaseModuleExtention
CurrentClass
BaseModule
Object
Kernel
BasicObject
```

BaseModuleExtention から探索されることが分かるので期待通りの動きになることも保証されます。
PHP7.0.1をUbuntu 15.10にインストールする

# PHP7.0.1をUbuntu 15.10にインストールする

先日リリースされた**Ubuntu 15.10**に、先日リリースされた**PHP7.0.1**をインストールして、**Apache2.4**で使えるようにしてみます。
手順としては下記のようになります。

0. Ubuntu 15.10を普通にインストールする
0. 必要なパッケージをインストールする
0. ライブラリ関係でちょこっとオマジナイをする
0. PHP7.0.1のパッケージを取得し展開する
0. configureを実行する
0. make/make installを実行する
0. Apacheの設定を行う

## Ubuntu 15.10を普通にインストールする

[Ubuntuのサイト](http://www.ubuntu.com/download/server)から、**Ubuntu Server 15.10**をダウンロードし普通にインストールします。
インストールパッケージ選択でSSHだけを選んでインストールします。

## 必要なパッケージをインストールする

下記のパッケージをインストールします。
私の作った「apt-install」を使うと一気にインストール出来ます。

```
libxml2-dev
pkg-config
libbz2-dev
libcurl3-dev
libjpeg-dev
libpng12-dev
libxpm-dev
apache2
libfreetype6-dev
libgmp3-dev
libmcrypt-dev
mysql-server
libmysqlclient-dev
libpspell-dev
librecode-dev
apache2-dev
openssl-dev
```
## ライブラリ関係でちょこっとオマジナイをする

GMP関係でライブラリの配置がよろしくないのでオマジナイをします。

```bash
# ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h 
```
## PHP7.0.1のパッケージを取得し展開する

ググると、githubからcloneするという記事がいくつかひっかかりますが、サイズがデカいので、[PHPのサイト](http://www.php.net/downloads.php)からPHP7.0.1をダウンロードします。

## configureを実行する

私が使ったconfigureは下記のようになります。

```
./configure \
    --enable-mbstring \
    --enable-zip \
    --enable-bcmath \
    --enable-pcntl \
    --enable-ftp \
    --enable-exif \
    --enable-calendar \
    --enable-sysvmsg \
    --enable-sysvsem \
    --enable-sysvshm \
    --enable-wddx \
    --with-curl \
    --with-mcrypt \
    --with-iconv \
    --with-gmp \
    --with-pspell \
    --with-gd \
    --with-jpeg-dir=/usr \
    --with-png-dir=/usr \
    --with-zlib-dir=/usr \
    --with-xpm-dir=/usr \
    --with-freetype-dir=/usr \
    --enable-gd-native-ttf \
    --enable-gd-jis-conv \
    --with-openssl \
    --with-pdo-mysql=/usr \
    --with-gettext=/usr \
    --with-zlib=/usr \
    --with-bz2=/usr \
    --with-recode=/usr \
    --with-mysqli=/usr/bin/mysql_config \
    --with-apxs2=/usr/bin/apxs2 \
    --with-tsrm-pthreads
```

## make/make install を行う

**configure**が正常に終了していたら、**make/make install**を行います。
必要であれば、**make**の前に**make test**を行ってもいいでしょう。

## Apacheの設定を行う

インストールが終わると自動的に**Apache**が再起動していますが、一旦**Apache**を停止し、PHP7をオフにします。

```bash
# service apache2 stop
# a2dismod php7
```
そして、「**/etc/apache2/mods-available/php7.conf**」を下記の内容で生成します。

```apache
AddType application/x-httpd-php .php
DirectoryIndex index.php
```
そして、**Apache**を**prefork**モードで動作させるためのオマジナイをします。

```bash
# a2dismod mpm_event
# a2enmod mpm_prefork
```
最後に再びPHP7と、ついでに**UserDir**を有効にし、**Apache**を再起動します。

```bash
# a2enmod php7
# a2enmod userdir
# service apache2 restart
```
これで、**PHP7.0.1**が有効になった**Apache**が起動すると思います。

----
React Native メモ


[React Native Getting started](https://facebook.github.io/react-native/docs/getting-started.html#content)

# ハマったとこ

- `Port 8081 already in use`
	- [stackoverflow](http://stackoverflow.com/questions/30216417/react-native-port-8081-already-in-use-packager-is-either-not-running-or-not-r)
	- `sunproxyadmin`を一度殺して、Xcode側でproject/cleanして再実行 -> いけた

- watchmanが `Failed to identify PDU` とか言って、Xcodeプロジェクトのビルドは成功するけど赤画面でServerにつながらない
	- watchmanを再起動
	- ちゃんと立ち上がった (´∀｀∩)

![Kobito.bCWnNC.png](https://qiita-image-store.s3.amazonaws.com/0/5950/b3be4c49-d6f4-15d9-c312-3c375074344c.png "Kobito.bCWnNC.png")

# Tutorial

[tutorial](https://facebook.github.io/react-native/docs/tutorial.html#content)

- Command + R でSimulatorのリフレッシュ。SyntaxErrorがあったらSimulator上の画面が赤くなってErrorメッセージを表示してくれます。

![Kobito.xGMZRb.png](https://qiita-image-store.s3.amazonaws.com/0/5950/f944d5c3-241f-c676-4d35-da8c66e44e76.png "Kobito.xGMZRb.png")
でた～(´∀｀∩)


# iOSコード

```ios/{ProjectName}/AppDelegate.m

  jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
```

こんな感じでjsが読み込まれる。

# 感想

- 検証用のアプリさくっと作るには良さそう
- どこまでNativeと橋渡ししてくれるかは、よくわからん
google-api-ruby-clientを用いて、Google Calendarにアクセスしてイベントを取得する


# バージョン

- google-api-ruby-client: 0.9.pre3

# 事前に必要なもの

- [Google Developers Console](https://console.developers.google.com)でクライアントID、クライアントシークレットを取得して、Google Calendar APIを有効にしておく
- 何かしらの方法でリフレッシュトークンを取得しておく
- 取得したいカレンダーのカレンダーIDを用意する


```ruby
require 'google/api_client/client_secrets'
require 'google/apis/calendar_v3'

client        = Google::Apis::CalendarV3::CalendarService.new
authorization = Google::APIClient::ClientSecrets.new(
  'web' => {
    client_id:     [クライアントID],
    client_secret: [クライアントシークレット],
    refresh_token: [リフレッシュトークン]
  }
).to_authorization
client.authorization = authorization

events = client.list_events([カレンダーID])
```

試してないので断言できませんが、Google Calendar以外の場合も似たような方法でAPIにアクセスできると思います。
AndroidでToDoアプリを作ってみた


## はじめに
Yarulist for Todo.lyはAndroid版のTodo管理アプリです。[Todo.ly](http://todo.ly/)はTodo管理するサービスです。Todo.lyはWeb,iOSアプリ,Androidアプリ(非公式)があります。また、Web APIが公開されており、アプリからWeb API経由でTodoを閲覧、追加、更新、削除等を行うことができます。

![screenshot_yarukoto.png](https://qiita-image-store.s3.amazonaws.com/0/17437/bcbe3a07-ec2c-bd1e-b9d8-bf462b6f216b.png "screenshot_yarukoto.png")


つまり、Yarulist for TodolyはTodo.lyのWeb APIを使用したAndroidアプリです。また、ソースはGitHubの[ここ](https://github.com/suzukaze/YarulistForTodoly)にあります。

## アカウント作成
Todo.lyのWebページからe-mail,フルネイム,パスワードを入力し、アカウント作成していください。

##  ビルド
JDK 1.7, Android Studio 1.0以上が必要になります。ビルドツールにはgradleを使用しています。インストールするAndroid端末をMacにつなげ、ターミナルから次のコマンド実行してください。

```
$ ./gradlew installDebug
```

ビルド後、Android端末にインストールします。

## ログイン
アプリを起動するとemailとパスワード入力画面になります。emailとパスワードを入力後、ログインボタンをタップして下さい。認証が完了するとやることが表示されます。

![screenshot_login.png](https://qiita-image-store.s3.amazonaws.com/0/17437/75dac48a-f6ec-0bcf-8f0b-09b65a895f32.png "screenshot_login.png")

## やることの閲覧

Todo(やること)はプロジェクト毎に管理されています。タブでプロジェクトを切り替えることができます。完了したやることはチェックボックをタッチすることにより、完了することができます。
また、「完了したやることを表示」により完了したやることを表示することもできます。

![screenshot_yarukoto.png](https://qiita-image-store.s3.amazonaws.com/0/17437/bcbe3a07-ec2c-bd1e-b9d8-bf462b6f216b.png "screenshot_yarukoto.png")

## やることの追加

画面上部のやることをタップします。ソフトキーボードからやることを入力し、エンターをタップするとやることが選択中のプロジェクトに追加されます。

## やることの編集

やること一覧から編集するやることをタップします。編集画面に遷移します。例えば、トマトをタップするとトマトの名称を編集することができます。

![screenshot_edit_item.png](https://qiita-image-store.s3.amazonaws.com/0/17437/4a490097-e469-2db1-103f-0cb602cdc3d6.png "screenshot_edit_item.png")


## プロジェクトの追加

画面上部の[+]アイコンをタップします。プロジェクト追加画面に遷移します。プロジェクトの追加は、Webサーバにプロジェクトの追加を通知し、プロジェクトを追加します。

## 同期

画面右上の同期アイコンをタップします。アプリとサーバのデータを同期します。内部では、やることの操作を変更履歴として管理し、同期時に変更履歴をWebサーバに通知後、やること情報を再度取得します。

## 使用ライブラリ
使用しているライブラリについて説明します。

* OkHttp HTTPの通信に使用しています。
* Retorofit REST操作に使用しています。
* RxJava 通信などの非同期処理に使用しています。
* ButterKnife Viewのインスタンスの割当に使用しています。
* Gson JSONへの符号化と復号化をします。
* Material-design-icon アイコンに使用しています。 

## 終わりに

Todo.lyにはプロジェクト以外に本日、週などフィルター、期限設定などの項目があります。これらの実装していない機能をYarulist for Todo.lyに拡充していけたらと思います。
デッドロックの対策

#デッドロック事象
ここ数年聞かなかったけれど、身近なところで、立て続けにデッドロックが発生。事象は次のように簡略化して書くと、本当によくある典型的な事象。

|トランザクションA|トランザクションB|
|:--|:--|
|Key=1をUPDATE。||
||Key=2をUPDATE。|
|Key=2をUPDATE<br>==>トランザクションB待ち||
||Key=1をUPDATE<br>==>デッドロック‼！|

しかし、何でだろう？と思い、もう少し聞いてみたら、そうだねぇと思うところもあったので、注意喚起を込めて書いています。

#デッドロック具体的例
これまでは、jsp+servletでしたが、最近、リッチクライアント化したアプリ。クライアント側のグリッド上で自由にソートしてデータを並べかえられるようになりました。その結果、

1):トランザクションAは、グリッドを昇順ソートした後で更新。
2):トランザクションBは、グリッドを降順ソートした後で更新。

のために、ロックがたすき掛けになって、デッドロックとなりました。
解ってしまえば、そりゃそうだよねだし、何で気がつかなかった、気づいてあげられなかったんだろうと。
ということで、教訓。
#教訓
**グリッドで自由にソートできるとするなら、更新順番には気を付けろ！**
です。

#最後に、私の場合のデッドロック対策。

設計に入る前のプロジェクトキックオフで、この手のよくある不具合(nullの扱いとか)について、
こんな事例があってとか、このプロジェクトではどうするとかを話します。
いつも同じメンバならよいのですが、そうじゃないときもあるので。
これでメンバの心のどこかに引っ掛かりができると思っています(思いたい)。

あとは、設計時、実装時の「レビュー」による、回避策です。

```text:レビュー時の問いかけフレーズ
Aさん、Bさんと複数の人が、その画面からの更新が並列して行えるとして、
　その画面から一回の指示で複数レコードを更新するとしたら、その順序は？
　その画面から一回の指示で複数テーブルを更新するとしたら、その順序は？

オンライン処理とバッチ処理が並列して行えるとして、
　オンライン処理とバッチ処理で複数レコードを更新するとしたら、その順序は？
　オンライン処理とバッチ処理で複数テーブルを更新するとしたら、その順序は？
```

##デッドロック回避策の定義：
回避：複数のトランザクションで、同じ資源のロックが必要なら、同じ順序でロックを取得する。
この順序は、人力に委ねられているため、設計時のミス、実装時のミスをしたら、デッドロックしてしまう。
　
受容：タイムアウトを指定。デッドロックが検知され、負けた方が、ABEND、もしくはもう一度トランザクションをやり直す。＝＝＞トランザクションのやり直しができるということは、そこでデッドロックが起きるとわかっているので、回避に向けた実装ができる。ABENDは、運用保守チームからすると、Noooo、受け入れたくないです。

軽減：トランザクション内の処理時間を短くすることで、デッドロックを起きにくくする。＝＝＞どんだけ早くするば？！

転嫁：思い付かない。あるのかな？

#参考:mysqlでデドロックを試す
トランザクションAが倉庫ID=1の商品ID=1234567-01、商品ID=1234567-02の順でロックを取得し、トランザクションBが倉庫ID=1の商品ID=1234567-02、商品ID=1234567-01の順でロックを取得するようなたすき掛けで、デッドロックが発生する様子を見る。

##テーブルの初期状態

```mysql:初期状態
mysql> SELECT
    ->  *
    -> FROM
    ->  T_STOCK
    -> WHERE
    ->  STOCKHOUSE_ID='1'
    -> ;
+---------------+------------+--------+--------+---------------------+
| STOCKHOUSE_ID | ITEM_ID    | AMOUNT | VER_ID | UPD_DTTM            |
+---------------+------------+--------+--------+---------------------+
|             1 | 1234567-01 |    123 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-02 |    600 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-03 |    702 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-04 |    395 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-05 |    903 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-06 |    679 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-07 |      2 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-08 |    158 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-09 |    518 | 1      | 2015-09-23 16:33:52 |
|             1 | 1234567-10 |    456 | 1      | 2015-09-23 16:33:52 |
+---------------+------------+--------+--------+---------------------+
10 rows in set (0.00 sec)
```

## トランザクションA、Bでそれぞれたすき掛けのロックを取得したときの挙動
![image](https://qiita-image-store.s3.amazonaws.com/0/76786/f39b3183-5d27-021d-4fa8-5bba8a1f5dcc.png)
Sublime Text 3 でプロジェクトディレクトリをお手軽grep

[SearchInProject_SublimeText](https://github.com/leonid-shevtsov/SearchInProject_SublimeText) は Sublime Text 3 で外部grepツールを使用してプロジェクトディレクトリを手軽に検索できるパッケージ。

Readmeに書いてあることと基本変わりないけど自分用にメモ。Macが前提。

## 使用できる外部コマンド

どれを使ってもよい。

- [The Platinum Searcher (pt)](https://github.com/monochromegane/the_platinum_searcher) -- おすすめ
- [The Silver Searcher (ag)](http://geoff.greer.fm/ag/) -- おすすめ
- [ack](http://beyondgrep.com/)
- [git grep](http://git-scm.com/docs/git-grep)
- [grep](https://en.wikipedia.org/wiki/Grep)
- [find str](https://technet.microsoft.com/en-us/library/Bb490907.aspx)

自分は[The Platinum Searcher (pt)](https://github.com/monochromegane/the_platinum_searcher)にした。

なおBashでは色の美しさでいつも[The Silver Searcher (ag)](http://geoff.greer.fm/ag/)を使っている。

## インストールと設定

`Ctrl+Shift+P`でいつものコマンドパレットを表示して`install`と入力し、`Search in Project`を検索してそれをインストール。

Preferences > Package Settings > Search in Project > Settings - User を開き、以下を貼り付け、保存。

> { "search_in_project_engine": "the_platinum_searcher" }

デフォルトのキーバインドは`Command+Option+Shift+F`（Macの場合）だけど、押しにくいのでキーバインドを変更することにした。Preferences > Key Bindings - User を開いて以下をどこかに追加する。

> { "keys": ["super+ctrl+f"], "command": "search_in_project" }

以上。
整数と不動小数点数の違い. 改(改ってネオジオっぽい)

ネオジオ面白いですよね＾＾

```
多くのプログラミング言語では「0」「0.0」は違う値です。
プログラミング言語によっては、整数型のない言語も存在し、そういう言語では「0」と書いても「0.0」と書いたものとみなされます。

「0」「0.0」を区別する多くの言語においても、「0」「0.0」を比較する場合は整数の「0」は実数の「0.0」に自動変換されて「0.0」になる、それと「0.0」を比較するので比較結果は等しいということになります。
```

##Rubyにおいては、「0」「0.0」は同値です。


```
2.0.0-p643 :001 > 0 == 0.0
 => true 
2.0.0-p643 :001 > 0 === 0.0
 => true 
2.0.0-p643 :002 > 1 == 1.0
 => true 
2.0.0-p643 :003 > 

Rubyでは、==と===は同じです。
```

##同値と同一って何が違うのか。

```
オブジェクトの同値性

オブジェクトが同じでも、別々でも良く、ただ値が等しい事を意味する。

str1 = str2 = String.new"hoge"
str3 = String.new"hoge"
str4 = String.new"fuga"

str1 == str2 #=> true オブジェクトが等しい場合
str1 == str3 #=> true 値のみが等しい場合
str1 == str4 #=> false 値が異なる場合　"hoge" == "fuga"
```

```
equal?メソッド

Rubyでは、Objectクラスのメソッドに属する。
オブジェクトの同一性を確かめるメソッド
```


```
オブジェクトの同一性

オブジェクト"同士"が等しいことを意味する。
str1= str2 = String.new"hoge"
str3 = String.new"hoge"
str4= String.new"fuga"

str1.equal? str2 #=> true オブジェクト同士が等しい場合
str1.equal? str3 #=> false 値のみが等しい場合
str1.equal? str4 #=> false 値が異なる場合

```
AndroidエミュレータからPCに立てたサーバのテスト

##サーバサイドのAPIとAndroidアプリを同時に開発している時に､自分のPCをに立てたAPPサーバにリクエストを送る方法

Androidアプリで指定しているAPIのURLのホスト名を`10.0.2.2`に設定してリクエストする｡  例えばローカルに立てたサーバのURLが`http://localhost:8080/hoge`なら`http://10.0.2.2/hoge`のように指定する｡

エミュレータから見たローカルサーバのIPアドレスが上記のうようになっているためみたいです｡
CentOS 7.1 のvirt-cloneでディスクが誤ったフォーマットでクローンされる

CentOS Linux release 7.1でvirt-cloneをして仮想ディスクをクローンしようとすると、誤ったフォーマットでクローンされてしまう問題がある。例えばQCOW2で作られた仮想マシンイメージも、クローンするとRAWのイメージになっていまう。

問題が起きているvirt-managerおよびvirt-cloneのバージョンは1.1.0。

調べてみると、[バグ](https://bugzilla.redhat.com/show_bug.cgi?id=1177099)として計上されている。

virt-managerのレポジトリ上では[このコミット](https://github.com/virt-manager/virt-manager/commit/86682c8c5464c27c3f5e86d3a2dc87d7a4adfd0f)で修正されている。

なので、virt-managerを1.2.0以降にすればよいんだけど、現時点(2015年11月)ではCentOSには取り込まれていないようなので、yum updateしてもまだアップデートすることはできない。

仕方ないので、[virt-managerのレポジトリ](https://github.com/virt-manager/virt-manager)から最新のソースコードをもってきて使うしかなさそう。

仮想ディスクをちゃんとクローンできないとか、結構困るバグだと思うんだけど、優先度はMEDIUMなのよね～ (T_T)
LambdaでAppStoreのレビューを拾ってSlackに流し込む

前回は[twitterのつぶやきをSlackに流し込むLambda Function](http://qiita.com/sparkgene/items/ff04c493dea3bbd162a7)を作ってみてたけど、今回はAppStoreのレビューを拾ってSlackに流し込むものを作ってみた。

https://github.com/sparkgene/lambda_review_checker

node module版はすでにあったので、レビューを取得するURLはそこを参考にしています。
https://github.com/jcoynel/app-store-reviews

いろいろ調べていると、レビューの情報を情報を取ってくるのは、[Search API](https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html)をベースにしているけど、レビューの情報を取得するURLはちゃんと公開されていないのが気になる。。。

レビューIDを保持するためにDynamoDBを利用しています。
<img width="481" alt="lambda_review_check.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/a40768eb-258c-2d9f-059d-bc728c3b4ad6.png">

取得したレビューはこんな感じでSlackに投稿されます。
<img width="259" alt="slack_post_image.png" src="https://qiita-image-store.s3.amazonaws.com/0/36184/5c4aa2dc-46af-9a14-d6b2-97cd5b9f23b8.png">
C++ で restclient-cpp を使う準備

# 概要

C++ の [rest client(restclient-cpp)](https://github.com/mrtazz/restclient-cpp) を使用する準備

- Ubuntu14.04
- gcc version 4.8.4

# install

使用するライブラリ

```
$ sudo apt-get install autoconf
$ sudo apt-get install libtool
$ wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
$ tar xzvf curl-7.45.0.tar.gz 
$ cd curl-7.45.0/
$ ./configure
$ make
$ sudo make install
```

restclient の install

```
$ git clone https://github.com/mrtazz/restclient-cpp
$ cd restclient-cpp
$ ./autogen.sh
$ ./configure
$ sudo make install
```

# Compile

```
$ g++ file_name.cpp -lrestclient-cpp
```

# run

```
$ ./a.out -L/usr/local/lib
```

or

```
$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
$ export LD_LIBRARY_PATH
$ ./a.out
```

参考

- [C++用のRESTクライアント restclient-cpp を試してみる] (http://yasuharu519.hatenablog.com/entry/2015/01/08/100825)
MATLABからScalaのコードを呼び出す

こんな感じで、JVMのバイナリをMATLABから呼べる。

```scala

package nebuta.matlablib

object Main {
	def hello: Unit = {
		println("Hello.")
	}
	def main(args:Array[String]):Unit = {
		hello
	}
}
```

```matlab
public Polygon(int xpoints[], int ypoints[], int npoints)
poly = java.awt.Polygon([14 42 98 124], [55 12 -2 62], 4);
poly.xpoints
poly.ypoints

javaclasspath
javaaddpath 'Main.class'
javaaddpath 'Main$.class'
javaaddpath 'scala-library-2.9.1.jar'
javaclasspath
nebuta.matlablib.Main.hello
```
[Rails] field_error_proc を使ってバリデーションエラーの表示をいい感じにする

## 背景

- Rails では、バリデーションエラーのあった項目はデフォルトで `<div class="field_with_errors">` で囲まれる
- この挙動は、 `config/application.rb` に `config.action_view.field_error_proc` を指定することで変更できる
    - 意図しない `<div>` が入ることでデザインが崩れるとか、 Bootstrap を使っているときに `.has-error` をつけたいとか気になったら動作を変えたくなってくる
- `config.action_view.field_error_proc` と検索すると「 `<div class="field_with_errors">` をつけないようにする」とか「class名を `field_with_errors` から変える」ようなものばかりがヒットする。
    - → 実はもっといろんなことができる！

## やりたいこと

ということで、バリデーションエラーがあったらテキストフィールドのすぐ下にエラーメッセージを表示するようにしてみましょう。

この例では Bootstrap を使っているので、

- フィールド全体を `.has-error` で囲む
- エラーメッセージは [Validation states](http://getbootstrap.com/css/#forms-control-validation) のように `.help-block` を使って表示する

という方針で実装しました。

## 結果

`config/application.rb` に実装するだけで期待通りに動きます：

```rb:config/application.rb
    config.action_view.field_error_proc = Proc.new do |html_tag, instance|
      if instance.kind_of?(ActionView::Helpers::Tags::Label)
        # skip when label
        html_tag.html_safe
      else
        "<div class=\"has-error\">#{html_tag}<span class=\"help-block\">#{instance.error_message.first}</span></div>".html_safe
      end
    end
```

View にはエラーメッセージの表示について一切実装する必要はありません：

```haml:view/hoges/new.html.haml
.form-group
  = f.label :name
  %span.label.label-danger 必須
  = f.text_field :name, placeholder: '例：あべ　しんぞう', class: 'form-control', required: true
```

こんなかんじで表示されるようになります：

![Kobito.72t7QU.png](https://qiita-image-store.s3.amazonaws.com/0/19478/526ca533-6dbd-1ea9-d492-0735ba95ceac.png "Kobito.72t7QU.png")

## 解説

- `instance` は `ActionView::Helpers::Tags::Base` のサブクラスになるっぽい
- `instance` のクラスを調べることによって、ラベルの場合には何もせずそのまま返す
- `instance.error_message` にバリデーションの内容が入っているので、取り出す

## 参考文献
- http://qiita.com/kawahiro311/items/e48c53c978d27a9192cc
- http://getbootstrap.com/css/#forms-control-validation
- http://www.rubydoc.info/docs/rails/ActionView/Helpers/Tags/Base
- http://www.rubydoc.info/docs/rails/ActionView/Helpers/ActiveModelInstanceTag
chef備忘録


## やること
- chefを使ってec2にnginxを導入する

## 事前準備
- ec2インスタンス作成して`% ssh nginx-test`でログインできるように設定しておく
- 作業マシンにchefとknife-soloをインストール

```Gemfile
source 'https://rubygems.org'

gem 'chef'
gem 'knife-solo'
```

## リポジトリ作成
```
% be knife solo init chef-repo
% cd chef-repo
% be knife solo prepare nginx-test
```
- `knife solo init`でリポジトリを作成。以降はそこで作業を行う
- `knife solo prepare`で対象サーバにchef-soloを実行できるようにする
	- nodesディレクトリにnginx-test.jsonが作成される

## cookbook作成
cookbook作成
`% knife cookbook create nginx -o site-cookbooks`

やることをレシピに記述する。
今回の目的はyumでnginxをインストールさせて、nginxを起動させること。
そのためには[リポジトリを追加する必要がある](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/)ので、ファイルを作成して配置するレシピも記述しておく。
各コマンドについは[chefのdocument](https://docs.chef.io/)を参照

```chef-repo/site-cookbooks/nginx/recipes/default.rb
cookbook_file '/etc/yum.repos.d/nginx.repo' do
  source 'nginx.repo'
end

yum_package 'nginx' do
  action :upgrade
end

bash 'run' do
  code '/usr/sbin/nginx'
end
```

```chef-repo/site-cookbooks/nginx/files/default/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/rhel/7/$basearch/
gpgcheck=0
enabled=1
```

## cookbook適用
先ほど書いたレシピをnginx-test.jsonのrun_listに追加する。

```chef-repo/nodes/nginx-test.json
{
  "run_list": [
    "recipe[nginx]"
  ],
  "automatic": {
    "ipaddress": "nginx-test"
  }
}
```

以下のコマンドを実行すると、リポジトリファイルを配置 -> nginxのインストール -> nginx実行とレシピが走るはず。
`% be knife solo cook nginx-test`

ブラウザから動作していることを確認。

![スクリーンショット 2015-11-01 15.43.13.png](https://qiita-image-store.s3.amazonaws.com/0/31121/1e251873-f810-3ce0-4615-87360fe876ce.png "スクリーンショット 2015-11-01 15.43.13.png")
UNCSSことはじめ

grunt-uncss

- CSSとhtmlを比較して、使っていないプロパティを削除してくれるプラグイン
- htmlから使用しているcssを一つにまとめてくれる
- リポジトリ https://github.com/addyosmani/grunt-uncss

# インストール

```bash:
npm install grunt-uncss --save-dev
```

# テスト
- 不要なプロパティを含むCSSを作成

```css:test.css
h1 {
  background-color: red;
}

.temp {
  font-size: 30px;
}

.test {
	float: left
}
```

```html:test.html
<html>
<head>
	<title>test</title>
	<link rel="stylesheet" type="text/css" href="test.css">
</head>
<body>
	<h1>title</h1>
	<p class="temp">p tag</p>
</body>
</html>
```

test.htmlではtestというクラスは使われていないので不要になります

## Gruntfile.js

```javascript:Gruntfile.js
module.exports = function(grunt) {
	// config
	grunt.initConfig({
		uncss : {
			dist : {
				files : {
					'test.css' : ['test.html']
				}
			}
		}
	});

	// plugin
	grunt.loadNpmTasks('grunt-uncss');

	// task
	grunt.registerTask('default', 'uncss');
}
```

## 実行

```bash:
$ grunt default

> Running "uncss:dist" (uncss) task
> File src/test.css created: 242 B → 219 B

> Done, without errors.
```

## 結果
testクラスが消えました

```css:test.css
/*** uncss> filename: src/test.css ***/

h1 {
  background-color: red;
}

.temp {
  font-size: 30px;
}

```

このように不要なプロパティを削除してくれます
一つのcssを複数のhtmlで共有している場合でもGruntfileのタスクを書き換えることで対応できます

```javascript:Gruntfile.js
files : {
	'test.css' : ['test.html', 'test2.html'] // ここを追加していく
}
```
Python3でmecabを使う

公式サイトに書いてあったsetup.pyを使う方法がうまく行かなかった。  
ダメ元で`pip search`してみたらパッケージが見つかって、使ってみたらとりあえず動いたので共有。

* Python 3.4.3 :: Anaconda 2.3.0
* mecab 0.996
* mecab-ipadic 102

```bash
$ pip install mecab-python3
```

インタープリターで確認

```bash
$ python3
>>> import MeCab
>>> mecab = MeCab.Tagger("-Ochasen")
>>> print(mecab.parse("今日はいい天気ですね。"))
今日	キョウ	今日	名詞-副詞可能
は	ハ	は	助詞-係助詞
いい	イイ	いい	形容詞-自立	形容詞・イイ	基本形
天気	テンキ	天気	名詞-一般
です	デス	です	助動詞	特殊・デス	基本形
ね	ネ	ね	助詞-終助詞
。	。	。	記号-句点
EOS
```

できた。
401HW > LEDの動作 > 起動時 / 電源OFF時 / 動作確認時

Y mobileの401HWは取説(p15 LEDの見かた)を見てもLEDの点灯状態がよくわからない。

http://cdn.ymobile.jp/lineup/401hw/data/401HW_manual_V1_00.pdf

使用しているうちにわかったのは以下の通り

- 起動する時 (電源ボタン2秒以上押す)
  - 4つ(全部)のLEDが点灯する (*1)
  - 左側の3つのLEDが点灯する
  - アンテナ型のLEDが緑色になると接続完了

[*1]において何もしなくていい。3つのLED点灯に自動的に遷移する。

.

- 電源OFFする時 (電源ボタン2秒以上押す)
  - 左側の3つのLEDが点灯する
  - すべてのLEDが消灯する

.

- 動作確認時 (電源ボタンを押す)
  - 電源ON済: 左側3つのLEDが点灯する
  - 電源OFF時: いずれのLEDも点灯しない
特定のキーストロークで同じ文字列が勝手に入力される(Mac)

"a"キーを二回叩くと、何故か以前コピーしたことがあるような気もする、とあるmavenのコマンドが入力されるという怪現象が発生。あらゆるテキスト入力コンポーネント（ブラウザの検索窓やフォーム、テキストエディタ etc.）で起こるので参ってしまった。
ちなみに、IMEの入力モード（英数・ひらがな）に関係なく発生する。

自分の環境は以下のとおり:

* OS: Mac OS X Yosemite (Mac Book Pro Retina, 13-inch, Early 2015)
* IME: Google日本語入力
* キー操作に関連しそうなツール: Karabiner

切り分けのために以下のことを試した。

* マシンの再起動: なぜか再起動しても発生する。
* IMEの切り替え: ことえりでも発生する。
* Karabinerの停止: 変化なし。
* スペル自動変換（システム環境設定>キーボード>ユーザー辞書）のOFF: 変化なし。

キーロガーなどの存在も疑ったがesetでスキャンしても検出されず…。
最終的には、PRAM(NVRAM)のクリアで解消された。

根本的な原因が不明で気持ち悪いけど…。 
"a"を2回叩いたとき、一瞬メニューバーの「編集」がクリックされたように反転するのがヒントのような気はする。
mecabで "input-buffer overflow. The line is split."のエラーが出てしまう時 

## エラーでた

PHPの`file_put_contents()`で、生成したテキストファイル`hoge.txt`を`exec()`でmecab実行してみたら、結果が二重に出てしまう。

```
array(14) {
  [0]=>
  string(61) "我輩	名詞,一般,*,*,*,*,我輩,ワガハイ,ワガハイ"
  [1]=>
  string(40) "は	助詞,係助詞,*,*,*,*,は,ハ,ワ"
  [2]=>
  string(43) "猫	名詞,一般,*,*,*,*,猫,ネコ,ネコ"
  [3]=>
  string(54) "で	助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ"
  [4]=>
  string(75) "ある	助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル"
  [5]=>
  string(37) "。	記号,句点,*,*,*,*,。,。,。"
  [6]=>
  string(3) "EOS"
  [7]=>
  string(61) "我輩	名詞,一般,*,*,*,*,我輩,ワガハイ,ワガハイ"
  [8]=>
  string(40) "は	助詞,係助詞,*,*,*,*,は,ハ,ワ"
  [9]=>
  string(43) "猫	名詞,一般,*,*,*,*,猫,ネコ,ネコ"
  [10]=>
  string(54) "で	助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ"
  [11]=>
  string(75) "ある	助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル"
  [12]=>
  string(37) "。	記号,句点,*,*,*,*,。,。,。"
  [13]=>
  string(3) "EOS"
}
```
コマンドラインから直接`mecab hoge.txt`を実行してみると、以下のエラーが。  
**input-buffer overflow. The line is split. use -b #SIZE option.**

んじゃあ、`mecab -b 81920 hoge.txt`で…ってまた同じエラーでるじゃん。

## 改行コードが原因??

`file hoge.txt`してみたら、
`hoge.txt: UTF-8 Unicode text, with no line terminators`と出る。  
試しに、PHP_EOLを追加したら、エラーが解消されました。

```php:mecab.php
$source = './tmp/hoge.txt';
$text = '我輩は猫である。';
$text .= PHP_EOL;
file_put_contents($source, $text);
```

よくわからん…
[廃版] Windows > 更新プログラムを確認していますから進まない > 「更新プログラムを自動的にインストールする(推奨)を選択して1日放置 > インストール時刻も設定するとよさそう

```txt:動作確認
Windows 7 pro 32bit
```

<font color=red>以下に記載の方法は2016年8月現在、うまくいかないようです。</font>

### 症状
リカバリしたWindows7に関してWindows Updateをしても「更新プログラムを確認しています」の画面から30分待っても進まない。

### 対策
Stackoverflowやgoogleなどで対策を調べて、クリーンブートを使う、Windows Update用ツールを使う、など色々やったが、だめだった。

結局有効だったのは以下の方法だった。

- 「更新プログラムを自動的にインストールする(推奨)を選択
- ネットにつなげた状態でPCを1日放置する

Stackoverflowなどでもこの方法が有効だったというのがあった。ただし、急ぎの時には使えない。

いったんWindows Updateが適用されると「更新プログラムを確認しています」の画面から短時間で次の画面に移るようになる。実際にPC二台で確認したところ、今のところは短時間で処理されるようになっている。


関連 http://freesoft.tvbok.com/tips/windows_update/not_proceed_update.html


## 対策 v0.2
(追記 2016/02/22)

- 「更新プログラムを自動的にインストールする(推奨)を選択
- ネットにつなげた状態でPCを1日放置する

という対策では時間がかかる。1時間30分待っても進展なし。
以下とすると早くなった気がする。

- 「更新プログラムを自動的にインストールする(推奨)を選択
- 新しい更新プログラムのインストール
  - 毎日
  - 時刻は次の正時 (9:30なら10:00、など）
- ネットにつなげた状態でPCを放置する
 
上記の設定では、10:15分頃にUpdateのメッセージが表示されるようになった。
この後、再起動して更新を適用したら、Updateの確認が短時間でできるようになった。

### (追記 2016/06/30)
v0.2の対策で本日試したところ、うまくいかなかった。
11:30分に設定を変更して、12:20まで待ったが失敗。
これまで7台実施して1台失敗。

代わりに以下の方法がいいかもしれない。
http://qiita.com/taka379sy/items/1b1f1eb0e2b4594dc561
1台のPCで実施したところ、4つのパッチ適用後に「更新プログラムの確認」では12分で確認作業が完了した。

### (追記 2016/08/08)

Windows 7 pro (32bit)のPC二台セットアップした。

上記リンク先の4つのパッチ適用後、Windows updateを開始して30分しても更新は進まず。

本記事の対策v0.2を試しても更新は進まず。20:00に更新するように設定して、19:45に再起動。20:20まで待ったが更新される気配がなく、あきらめた。

更新を00:00にするように設定し、20:30に再起動した状態で二台を放置した。翌日の08:30に確認したところ、二台のうち一台では更新プログラムのダウンロードが完了し、もう一台はまったくダウンロードしてなかった。

ダウンロードした方のPCで更新プログラムを適用したところ、7時間かかっても適用が完了しない。更新を一気に適用すると失敗しやすい、という情報もある。
Ubuntuにnpmをインストールしました。

Ubuntuにnpmをインストールしました。VagrantのUbuntu14.04です。

# npmコマンドが入っていません。
npmコマンドを確認します。

```bash:
npm

The program 'npm' is currently not installed. To run 'npm' please ask your administrator to install the package 'npm'
```
npmコマンドが入っていないようです。

# npmコマンドをインストール

```bash:nodejs、npmをいれます。
sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install npm
```

# 再びnpmコマンドを確認
再度npmコマンドがインストールされたか確認します。

```bash:
npm

Usage: npm <command>

where <command> is one of:
    add-user, adduser, apihelp, author, bin, bugs, c, cache,
    completion, config, ddp, dedupe, deprecate, docs, edit,
    explore, faq, find, find-dupes, get, help, help-search,
    home, i, info, init, install, isntall, issues, la, link,
    list, ll, ln, login, ls, outdated, owner, pack, prefix,
    prune, publish, r, rb, rebuild, remove, repo, restart, rm,
    root, run-script, s, se, search, set, show, shrinkwrap,
    star, stars, start, stop, submodule, tag, test, tst, un,
    uninstall, unlink, unpublish, unstar, up, update, v,
    version, view, whoami

npm <cmd> -h     quick help on <cmd>
npm -l           display full usage info
npm faq          commonly asked questions
npm help <term>  search for help on <term>
npm help npm     involved overview

Specify configs in the ini-formatted file:
    /home/vagrant/.npmrc
or on the command line via: npm <command> --key value
Config info can be viewed via: npm help config

npm@1.3.10 /usr/share/npm
```
今度は入ったみたいです(^o^)


# 参考
http://qiita.com/TsutomuNakamura/items/7a8362efefde6bc3c68b
VBA フォルダ、ファイル移動に関する関数

毎度毎度、思い出すのも面倒なので。ファイル操作でよく使うマクロ一式です。

#####【フォルダ削除】
myFol=引数はフルパスにします

```
Function FolderDelete(ByVal myFol As String)
    Set objFile=CreateObject("Scripting.FileSystemObject")
         If objFile.FolderExists(myFol) Then
             objFile.GetFolder(myFol).Delete
         End If
    Set objFile=Nothing
End Function
```

#####【ファイルコピー】  
srcFile,dstFileもフルパス指定

```
Function FileCopy(ByVal srcFile As String, ByVal dstFile As String)
    Set objFS=CreateObject("Scripting.FileSystemObject")
        objFS.CopyFile srcFile, dstFile
    Set objFS=Nothing
End Function
```

#####【ファイル移動】

```
Function FileMove(ByVal srcFile As String, ByVal dstFile As String)
    Set objFS=CreateObject("Scripting.FileSystemObject")
        objFS.MoveFile srcFile, dstFile
    Set objFS=Nothing
End Function
```

#####【フォルダ作成】 
深いネストまで一気に作成(親フォルダが存在しなければ作る）

```
Sub myMkDir(ByVal sPath as String)
    Dim iStart  As Integer
    Dim aDirs   As Variant
    Dim sCurDir As String
    Dim i       As Integer
   
        If sPath <> "" Then
            aDirs=Split(sPath, "\")
            If Left(sPath,2)="\\" Then
                iStart=3
            Else
                iStart=1
            End If

            sCurDir=Left(sPath,InStr(iStart,sPath,"\")
                For i=iStart to UBound(aDirs)
                    sCurDir = sCurDir & aDirs(i) & "\"
                    If Dir(sCurDir, vbDirectory)=vbNullString Then
                        MkDir sCurDir
                    End If 
                Next
         End If
End Sub
```

#####【フォルダ内のサブフォルダ数を取得する】
もちろん、サブフォルダ名も取得できます

```
Function FolCnt(ByVal myFol As String) As Integer
    Dim objFSO As Object
    Dim objRoot As Object

    Set objFSO=CreateObject("Scripting.FileSystemObject")
    Set objFolder=objFSO
    Set objRoot=objFSO.GetFolder(myFol)

    myCnt=0

    For Each Fol In objRoot.SubFolders
        Debug.Print Fol
        If Fol.Name Like "*ほげほげ*" Then
            myCnt = myCnt + 1
        End If
   Next Fol

   FolCnt = myCnt

End Function
```

#####【ファイルのタイムスタンプを取得する】

```
Sub GetFileTimeStamp()

Dim objFileSys As Object
Dim strScriptPath As String
Dim strFilePath   As String
Dim objFile       As Object

Set objFileSys = CreateObject("Scripting.FileSystemObject")
    strScriptPath="C:\aaa\bbb\"
    
    strFilePath=objFileSys.BuildPath(strScriptPath, "aaa.xlsx")
    Set objFile = objFileSys.GetFile(strFilePath)

    Debug.Print "作成日:" & objFile.DateCreated
    Debug.Print "最終アクセス:" & objFile.DateLastAccessed
    Debug.Print "最終更新日:" & objFile.DateLastModified

Set objFile = Nothing
Set objFileSys = Nothing

End Sub
```
aws VyOSを使用したPPTP接続

#aws vpc間通信時の設定メモ

##やりたいこと
・VPCに対してクライアント（windows）からPPTP接続を行う

##環境
####VPCを用意

```bash:準備
VPC 10.0.0.0/16
```

####VPC内にサブネットを用意
```bash:準備
publicサブネット
　10.0.100.0/24
privateサブネット
　10.0.200.0/24
```
####publicサブネットにVyOS(ver1.05)を用意
```bash:準備
VPC のpublicサブネットにあるVyOSを用意
※マーケットプレイスからlaunch
```

####VyOSにはeniを２つをアタッチしておく。
```bash:準備
VyOS
　public：eth0　10.0.100.123/24　
　private：eth1　10.0.200.123/24

※eniのsource dest.をすべて「無効化」にしておく。
```

####VyOSのPublicのeni(eth0)にEIPを付与する
```bash:準備
VyOS - eth0：XXX.XXX.XXX.XXX
```

####privateサブネットに疎通確認用のEC2（なんでもよい）を用意
```bash:準備
AmazonLinux　10.0.200.10
```

####SecurityGroup
```bash:準備
VyOS A
　・SSH ※source：自分の端末からのSSH接続
　・GRE (IP Protocol 47) ※source:0.0.0.0/0
　・UDP port500 ※source:0.0.0.0/0

AmazonLinux　（疎通確認用なのでざっくり）
　・ALL traffic ※source：10.0.0.0/16（VPC）
```

####RouteTable
```bash:準備
privateサブネットのroutetableに
PPTPクライアントのアドレスプールに指定したIPへの通信はpublicサブネットのVyOSのeth1(eni-XXXXXXXX)を通る様、指定
```

#ここからVyOS内の設定
##eniを認識させる

```bash:VyOS-A_/etc/network/interfaces
以下追記
auto eth1
iface eth1 inet static
address 10.0.200.123
netmask 255.255.255.0
```

networkingを再起動

```
$sudo service networking restart
```

（EC2を再起動するとEIPに接続できなくなる？事象が発生したので、rc.localに以下を追記した。どなたか、詳しい方がいらっしゃいましたら仕組みを教えてください。）

```bash:/etc/rc.local
service networking restart
```

##PPTP 設定

```bash:config
configure

#事前準備
MY_USER_NAME1=myuser1
MY_USER_PASSWORD1=myuser1
MY_USER_NAME2=myuser2
MY_USER_PASSWORD2=myuser2
MY_START_POOL_IP=10.0.100.1
MY_STOP_POOL_IP=10.0.100.100
MY_OUTSIDE_ADDRESS=10.0.100.123

set vpn pptp remote-access authentication mode local
set vpn pptp remote-access authentication local-users username $MY_USER_NAME1 password $MY_USER_PASSWORD1
set vpn pptp remote-access authentication local-users username $MY_USER_NAME2 password $MY_USER_PASSWORD2
set vpn pptp remote-access client-ip-pool start $MY_START_POOL_IP
set vpn pptp remote-access client-ip-pool stop $MY_STOP_POOL_IP
set vpn pptp remote-access outside-address $MY_OUTSIDE_ADDRESS
set vpn pptp remote-access dns-servers server-1 8.8.8.8
set vpn pptp remote-access dns-servers server-2 8.8.4.4

commit
save
```

windowsクライアントからPPTP接続を行い、
ローカルから接続確認用のec2に疎通が確認できればOK
[tvOS]AppStoreのリリースに関するTIPS

11/1にAppleTV向けのTwitterクライアントNightFoxSHOWをリリースしました。
![0x0ss.jpg](https://qiita-image-store.s3.amazonaws.com/0/24979/94f06f3d-eeae-2e1c-451c-9b19a2c2733b.jpeg)

その際に気がついたTIPSを紹介します。

#アプリURL機能を持たない
https://itunes.apple.com/us/app/nightfoxshow-for-twitter/id1054640195?l=ja&ls=1&mt=8
このようなアプリURLを発行してくれるのですが、URLに飛んでもアプリの紹介ページには飛ばずにAppStoreに飛ばされてしまいます。
しかも、AppStoreではtvOSのアプリが表示できないので意味なし。

#AppStoreがうんこ
tvOSのAppStoreはカテゴリ分けも出来ず、オススメ・購入済み・検索しか出来ないです。
つまり、アプリはオススメに乗らない限り検索から探すしかないわけです。

#URLも発行できない。AppStoreから検索するしかないってことは…
悪くも「TV」のCMのように「hogehogeで検索！」みたいな宣伝をしないといけない。
MacやiPhoneから概要くらい見れてもいいのにね。
**ちなみにNightFoxSHOWは「twitter」で検索すればでてきます**

#WebAccessについて
AppStore申請時にレーティングの設定で「無制限のWebアクセス」という項目があるが、これは当然NOを選択する。
アプリがWebブラウザなら話は別だけど…

#スクリーンショットの撮り方
AppleTVをMacに接続してXcodeからDevicesを選択してTake ScreenShotを押すとデスクトップにスクリーンショットが作られる。
シミュレータの場合は⌘+Sで撮れる。

#Bitcode自動再コンパイル
これはオフにした。
tvOSをターゲットにするとそもそもビルドセッティングにEnable BitCodeがでてこない。
世界初 (?)のiOSアプリがリリースされるまで

![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/63235/fe509722-13ae-69ea-f59b-4586ae84f6aa.png)

[6500円で作るスマートロック](http://qiita.com/toshi-saito/items/ef7fd9a2154f7db92831) のiOSアプリが無事Appleの審査を通りリリースすることができました。

- [6500円でつくるスマートロック メカ作成編](http://qiita.com/toshi-saito/items/ef7fd9a2154f7db92831)
- [6500円でつくるスマートロック 電子工作編](http://qiita.com/toshi-saito/items/87c507350941a95cc660)

名前はLadybugにしました。
オレンジのユニバーサルアームがなんかてんとう虫っぽいでしょ？

ファームウェア配信と作り方の説明サイト
http://toshi-saito.github.io/Ladybug/
アプリ
https://itunes.apple.com/us/app/ladybug/id1045005224?l=ja&ls=1&mt=8

おそらく世界初であろう自作前提デバイスの操作アプリなのでリリースまでの遍歴をシェアしたいと思います。
審査を通るまでに4度ほどリジェクトされました。
個人で外部デバイスと連携するアプリをリリースしたい人の参考になれば。

リリースまで
---
申請しても審査通らないだろうと思ってたんですが、
[リモコンNKとIRKit対応アプリの申請方法](http://maaash.jp/2014/03/howto-submit-irkit-app-to-appstore/)
で、そうでもなさそうだ。ということを知り、やってみようか。というのがそもそもの動機です。
(記事にある通り、操作している動画を審査に出したらばっちり通りました。)

ちょうどXCode7がリリースされた頃だったので、ついでにアプリをSwift2で書き直して審査に出しました。

審査に出すまでにやったことは、

- 操作動画の作成
 - iPhoneで動画を撮って、iMovieで動画をつないだり字幕を付けました。
- アプリのスクリーンショットをiPhone4,5,6,6plusのシミュレータで取る。
- ファームウェアダウンロードと作り方のページを作成
 - こちらです -> http://toshi-saito.github.io/Ladybug/
 - サポートURLが入力必須なので、そのためにも何かしら作る必要がありました。

作った動画はこちら。
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/XMRJUkiPGHQ/0.jpg)](http://www.youtube.com/watch?v=XMRJUkiPGHQ)
自宅位置設定の場面は、申請した動画はちゃんと写してますが、今回のものは諸事情で黒背景にしてあります。

最初の申請
---

「App Review に関する情報」のメモ欄には以下を書き込み申請しました。
>このアプリはBLE端末の操作アプリになります。
>対象のBLE端末は、自作を前提にしており、以下でファームウェアと作成手順及び材料とその入手経路を公開しております。
>http://toshi-saito.github.io/Ladybug/index.html
>
>ほぼ同じ内容ですが、以下でも作成手順を公開しております。
>http://qiita.com/toshi-saito/items/ef7fd9a2154f7db92831
>http://qiita.com/toshi-saito/items/87c507350941a95cc660
>
>上記記事では、iOSアプリのソースコードも公開しておりますが、そのアプリは一般公開用のバージョンで、今バージョンとは別のものです。
>
>アプリの動作の様子は以下動画で確認いただけます。
> (Youtubeリンク)

ファーストコンタクト
---
約1週間後にIn ReviewになってすぐiTunes Connect経由で連絡が来ました。
YouTubeの動画にアクセスができないとの内容だったので、
素直にDropboxに同じ動画を上げて、そのURLを送りました。

数日後にCoreLocationとCoreBluetoothは自動解錠のために使ってるのか？
という旨の質問がきました。
CoreLocationとCoreBluetoothはこういう使い方をしています。
という内容を返信しました。

最初のリジェクト
---
その数日後にすべての機能を説明するスクリーンショットを追加しなさい。
という内容で、リジェクトされました。
(この時は起動時のロゴが出ているスクリーンショットしか載せてなかった)

画像の作成
---
[MockUPhone](http://mockuphone.com/)ではめ込み画像を作って、
GIMPでちょろっと編集して作りました。

作った画像は2つで
- アプリで施錠・解錠をしているもの
- ロック画面に自動解錠の通知が来ているもの
を作って、再度申請しました。
 
2度目のリジェクト！
---
また約1週間後、
バックグラウンドでGPSを使ってるなら、
免責事項としてバックグラウンドでGPSを使うので、バッテリーをかなり食う旨を明記しなさい
ということでした。
バックグラウンドでGPSを使うアプリは一律で書かないといけないんでしょうね。
早速書き加えて申請をしました。

3度目のリジェクト
---
また約1週間後、
スクリーンショット画像がAppleのガイドラインに違反しているとのことで、リジェクトされました。
返信の内容をよく読むと、ロック画面の「スライドでロック解除」が画像に入っているのがダメということでした。
前回のリジェクトはまたっく別の内容だったので、まさかのリジェクトでした。

他のアプリはどうしてるのかと気になったので、AppStoreで検索して見てみたら、通知センターのスクリーンショットをつかってるじゃないですか！
なるほど、それならいいんだ！！
ということで、早速通知センターのスクリーンショットをとり、画像を作り直しました。
で、また申請。


4度目の正直！
---
またまた1週間後、ついに申請が通りました。
最初に申請したのが10月の頭だったので、まるまる1ヶ月ほどかかっての承認となりました。

電話連絡や確認のためにデバイス送ってとかあるかなと思ってたんですが、そういうことは一切なかったです。
先人が各種デバイスを出してくれたおかげですかね。

ということで、iPhoneは持ってるけど、Macは持ってないという人でも、
Ladybug使えますので、ぜひとも自作して楽しんでもらえればと思います！
Androidアプリはpriori3買ったら作り始めますー
MacにMongoDBをインストールする

若干今更ながらMacにMongoDBをインストールしたのでその時の手順をメモ。

# 環境
Mac：10.10.5（Yosemite）
MongoDB：3.0.7

# 参考サイト
https://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/

# インストール手順

## Homebrewのパッケージをupdate
```
$ brew update
```

## mongoDBインストール
```
$ brew install mongodb
```

# MongoDB実行

## データ格納用ディレクトリ作成
```
$ sudo mkdir -p /data/db
$ sudo chown ${ユーザ名} /data/db
```

## 起動
通常であればmongodへのパスが通っているはずのため、以下のコマンドで実行可能
```$ mongod```

パスが通ってない場合はmongodの場所をwhichで確認し、パスを通すかフルパスで実行

### /data/db以外のパスをデータ格納用ディレクトリに使う場合
以下のコマンドでディレクトリを指定する
```$ mongod --dbpath ${dir path}```

## 終了
Control + Cにて終了させる

# 設定等
## 設定ファイル置き場
/usr/local/etc/mongod.conf

## クライアント側起動コマンド
```
mongo
```

# 終わりに
SpringでAPI作るにあたって、RDBじゃなくてNoSQLにしたいなーということで
試しにMongoDB入れてみた。
特にそちらの方が向いてるとかではなくて、ただ使いたかったから。手段の目的化。
cron

＜cronが動いてるか見る＞
`service crond status`

＜cron設定ファイル /etc/crontab＞
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

SHELL→cronで使用されるシェル
PATH→cronに教えるパス。ここにあるコマンドはcronが実行できる。それ以外はフルパス指定しないとダメ。

＜cronの書式＞
`分 時 日 月 曜日 実行ユーザ 実行コマンド`
`５ ＊ ＊ ＊ ＊   root      logger crontab-test`
毎時5分に、loggerコマンドで/var/log/messagesにログを書き出す

分(0-59),時(0-23),日(1-31),月(1-12),曜日(0-7) ※曜日は0または7が日曜

＜cron設定方法＞
`# crontab -u root -l`
rootの設定したcrontabを見る（-u root でユーザ指定している）

`# crontab -u root -r`
rootの設定したcrontabを削除（※全て削除されるので注意！！）

`# crontab -u root -e`
rootの設定したcrontabを編集
crontabコマンドで編集するのが通常だが、
本体は、/var/spool/cron/ユーザ名 に置いてある


＜cron実行時間指定方法＞

|time|mean|
|:--:|:--|
|0,10,20,30|リスト方式<br>カンマで区切って、0分、10分、20分、30分 に実行出来る|
|1-5|範囲方式<br>月フィールドで指定した場合、1〜5月に実行される|
|*/10|間隔<br>分フィールドで指定すると、10分間隔に実行される|

その他の表記方法
`01 * * * * root run-parts /etc/cron.hourly`
run-partsは引数で指定したディレクトリに置かれたプログラムを実行するコマンドなので
「/etc/cron.hourlyに置かれたコマンドが毎時1分に実行される」

`11 4 1 * * root run-parts /etc/cron.hourly`
毎月1日、4:11に実行

＜crontab -rとやってしまったとき＞
/var/log/cron にcronが実行したコマンドのログがあるよ！（ここから戻すの大変だけど）

または、
/var/spool/cron/userの中に、ユーザごとのcron設定ファイルがあるよ
（バックアップ取ってないと意味ないけど）

＜cronを動かしてみる＞
なんでもいいからとりあえずcronを動かしてみたいとき

1.ホームディレクトリにファイルを作って、パーミッションを666に
`$cd`
`$touch aaa.txt`
`$chmod 666 aaa.txt`

2.cronを編集する
`$crontab -e`
`* * * * * echo "test" >> /home/user/aaa.txt`
保存して閉じる

3.ぼーっとしてると、毎分aaa.txtにtestの文字が追加されます
[サービス終了] GoogleドライブでiPhoneアプリをOver The Air(OTA)配信する方法

#注意: 本記事の方法は現在利用できません
Google のサービス終了に伴い、本記事で説明している無いようは現在利用できなくなっています。そのため、OTA には別の方法をご検討下さい。当記事は記録として削除はしない方針とさせて頂きます。

> Google Apps のお客様は 2016 年 8 月 31 日までの 1 年間はこの機能を引き続き使用できますが、それ以降は googledrive.com/host/doc id 経由のコンテンツ提供は、サポートを終了します。
-- [Google ドライブにおけるウェブ ホスティング機能の廃止について](https://gsuiteupdates-ja.googleblog.com/2015/09/google.html)

2017/11/2 追記

----


iOSアプリ開発の際にOTA配信したいことがあります。
自身でサーバーを立ててもいいのですが、クラウドサービスを利用する手もあります。
今回はGoogleドライブで公開する方法を紹介します。

# 用意する物
- index.html
- manifest.plist
- ipaファイル

# 手順
## 1. Google Driveで公開用ファルダを作成
Googleドライブを開き、`新規＞フォルダ＞作成`から公開用のフォルダを作成します。
フォルダ名はなんでもいいので`Public`などにしておきましょう。

`「Public」を共有＞詳細設定＞変更＞オン - ウェブ上で一般公開＞保存`を選択しPublicフォルダを公開します。

Publicフォルダを開き、ブラウザのURLを確認してください。
URLの最後の英数の羅列がフォルダIDになり、公開したサイトにアクセスするために必要になります。

`https://drive.google.com/drive/folders/0B1NXXXXXXXXXXXXXXXXXXXXXXXX`←これ

## 2. 公開用フォルダにファイルを配置
Publicフォルダ内にXcodeで作成した`manifest.plist`と`ipaファイル`、自身で作成した`index.html`をアップロードします。

公開フォルダにアクセスした際、`index.html`というファイル名のファイルが自動で読み込まれます。
そのため以下のURLに、IDを書き換えてからアクセスすると`index.html`のページが表示されます。

**`https://googledrive.com/host/0B1NXXXXXXXXXXXXXXXXXXXXXXXX`**


## 3. index.htmlの記述
index.html内で、ダウンロードリンクは以下の様に設定しておきましょう。

```html:index.html
<a href="itms-services://?action=download-manifest&url=https://googledrive.com/host/0B1NXXXXXXXXXXXXXXXXXXXXXXXX/manifest.plist">Download</a>
```

`manifest.plist`が別フォルダにある場合は、以下の様に指定できます。

```html:index.html
<a href="itms-services://?action=download-manifest&url=https://googledrive.com/host/0B1NXXXXXXXXXXXXXXXXXXXXXXXX/some_folder/manifest.plist">Download</a>
```

## 4. manifest.plistの書き換え
`index.html`同様に、URLの値を以下の様に設定しておきましょう。
ipaファイルが別フォルダにある場合も、`index.html`同様に指定できます。

```xml:manifest.plist
<key>url</key>
<string>https://googledrive.com/host/0B1NXXXXXXXXXXXXXXXXXXXXXXXX/App.ipa</string>
```


## 参考
[Google ドライブにWEBページを作成する方法](http://matome.naver.jp/odai/2139351957366008801)
新しいRubyのFile Uploader「Shrine」の登場


[Shrine](https://github.com/janko-m/shrine)は[@janko-m](https://github.com/janko-m)によって書かれた新しいFileUploaderです。
先日からGithubのトレンドに入っており気になっていましたが、日本語の情報が見つからないので試しに使ってみました。

同じようなgemには下記のようなものがあります。
しかし、これらのgemはコードが複雑すぎたり、拡張が難しかったりする問題点があります。

- [CarrierWave](https://github.com/carrierwaveuploader/carrierwave)
- [PaperClip](https://github.com/thoughtbot/paperclip)
- [Refile](https://github.com/refile/refile)

Shrineの特徴は、既存のgemのような複雑なコードベースから脱却して、pluginの設計を取り入れたシンプルなコードベースです。
その上、非同期処理や並列処理などの非常に便利な機能もサポートしています。

新しいgemを作ろうとされたモチベーションは@janko-mの書かれた記事が参考になります。[Introducing Shrine – A file upload toolkit](http://twin.github.io/introducing-shrine/)

```ruby
require 'shrine'
require 'shrine/storage/file_system'

Shrine.storages = {
  cache: Shrine::Storage::FileSystem.new(Dir.tmpdir),
  store: Shrine::Storage::FileSystem.new('public')
}

class AttachmentUploader < Shrine
  # 必要な機能だけpluginとして読み込む
  plugin :store_dimensions
end

class Attachment
  attr_accessor :file_data
  include AttachmentUploader[:file]
end

attachment = Attachment.new
attachment.file = File.open('path/to/file.jpg')
puts attachment.file_url #=> '/var/folders/l3/2qbqhkws59gd7ts5g98zslxr0000gn/T/f19ea7f8b06fa1361d999eb596d9a0c8089400fdfe7c4bf30992009cba1a.jpg'
puts attachment.file.height #=> 275
puts attachment.file.width #=> 275
```

### 良い点

- 設定が簡単で導入が楽(s3なども扱える)
- 最低限必要な機能がデフォルトでサポートされている
- 非同期処理や並列処理がサポートされており、先鋭的
- 必要なpluginだけ選択して読み込むため処理が速い
- 機能が細かくpluginに分けられており、シンプルなコードベースを保っている
- CarrierWaveはバグを踏んだ時にデバッグが非常に大変だけれど、Shrineはpluginを絞ることができるのでデバッグが容易

### 悪い点

- 全体的に設計やコードの書き方がイマイチ。
- クラスにuploaderを組み込む際に、データを保存するための変数名(DBのカラム名)が固定されている(`#{name}_data`)
- pluginと違って、Shrineクラスはなぜか分割されておらずやや複雑になっている
- 個人的にはvalidationと、`Shrine.[]`のメソッド名と実装が気に入らない。

ちなみに、やや不思議であるがActiveRecordをサポートしているのに、なぜかドキュメントにきちっとした使い方が記述されていない。

```rb
# 下記の実装で動くはず。

# migration
create_table :images do |t|
  t.text :file_data
end

# uploader
class ImageUploader < Shrine
  plugin :activerecord
end

# model
class Image < ActiveSupport::Base
  include ImageUploader[:file]
end
```

なかなか面白そうですが、まだお仕事で使えるクオリティではないのでもう暫く様子を見てみます。
http2/quic meetup メモ

meetup行ってきたのでメモ。
殴り書きなので、自分で理解しきれていないところもある。

前田さんのTwitterからかなり引用させてもらってます。
https://twitter.com/mad_p


# QUIC (Jana Iyengar)

UDPでHTTP2と同じことを実現する。
HTTP/2のプロトコル部分を置き換え、セマンティスクスはそのまま。
常時暗号化、0-RTT/1-RTT、コネクションの輻輳制御、セッションのフローコントロール、CPU最適化などがある。
http://src.chromium.org/viewvc/chrome?revision=162259&view=revision


# http2　(Mark Nottingham)

https://http2.github.io

apacheもnginxも対応しつつある。
Service Workerでプライオリティーヒントをリクエストごとにサーバーに送ることができるかもしれない。

プライオリティについてはsummerwindさんのこのスランドが素晴らしい。
http://sssslide.com/speakerdeck.com/summerwind/2-prioritization

HTTP2へのOriginフレームの追加
http://d.hatena.ne.jp/ASnoKaze/20151029/1446136493

接続をオリジンにまたがって同じconnectionに相乗りすることを考えている。サーバーからこのconnectionでこのoriginを送りたくないという表現もできるように。


HTTP/2の後継としては多くの拡張が考えられている。

HTTPヘッダのJSON表現
https://tools.ietf.org/html/draft-reschke-http-jfv-00
https://github.com/HTTPWorkshop/workshop/blob/gh-pages/presentations/reschke-headers/index.html

encrypted content-encodingヘッダの追加。

Blind caching
中身を見ないでもキャッシュを共有する方法。


# webpush (Martin Thomson)

https://datatracker.ietf.org/wg/webpush/documents/

webpushはサイトを閲覧していない時に送る4K程度のメッセージ。
通常はemailやchatの通知に使われる。「更新があります」「パケットが届きました」など。

GCM, APNS, WNS…、これらの標準化がAPI(W3C)、プロトコル(IETF)で検討されている。

100人以上の人が同時に同じことをしようとしても、単にバッテリーを使うだけ。3つのアプリで2時間分のバッテリーを食うことになってしまう。2分間だけネットに接続してまたスリープみたいなことをやりたい。

overview: app内のブラウザがsubscriptionをapplication serverに送る。app serverはpush messageをpush serviceに送る。service workersがウインドウなしに処理

UAからPush serviceにHTTP/2のGETを送る。これは何も返事を期待しないが、これによってpush serverがPUSH PROMISEフレームを送れるようになる。このstreamはロングポーリングの空リクエストと同様の働きをする。

![CSoWLDqVEAAzRrI.jpg-large.jpg](https://qiita-image-store.s3.amazonaws.com/0/33116/87f38910-15d4-5436-760c-3c9baf4bc351.jpeg)
PUTはPOSTの間違い。


# Let's Encrypt  (Richard Barnes)

無料でSSL証明書を使用できる仕組み。
https://letsencrypt.org

無料。自動。透明、オープン、協力的

ACME(アクメ) Automated Certificate Management Environment
自動で証明書を更新する仕組み。

domain validationはチャレンジを送り、DNSにそのチャレンジに対応したレコードを入れることで行う。正しいドメインオーナーだけがDNSを変更できることを利用。

Acmeではauthorizationの申請から、チャレンジの取得、検証まで全部を仕様化。このループには人が介在しない。標準化によってツール化することができる


# TLS1.3  (EKR)

圧縮(サイドチャネル攻撃(CRIMEとか)に耐えるものが必要。HTTP/2でHPACKを作ったのも同じ理由)。
TLS 1.3 1-RTTハンドシェーク。これが初めて話す相手との基本的なフローになる。最初のメッセージでDH shareをいくつかの(固定の?)群上で送る。サーバーからはサーバー設定とサーバーkey shareを返す。
サーバーがpassiveになることで攻撃に強くなる。
初のサーバーからの通信でいきなりアプリケーションデータを送ってしまえる。これは最初のパケットに相乗りしてすぐに届く。HTTP/2のSETTINGSフレームやPUSH PROMISEをここで送ってしまえる。
WGはいつでもclient authを要求できる仕様を検討中。
https://tools.ietf.org/html/draft-ietf-tls-tls13-10


# cache aware server push  (kazuho oku)

h2o v1.5
http://blog.kazuhooku.com/2015/09/h2o-version-150-released.html?m=1

ブラウザがリソースを保持しているかどうかをクッキーで判断する。
それによってHTTP2のサーバープッシュを積極的に使えるようになるという話。
mnotが興味を示していたので、これは本格的に採用されそう。

サーバープッシュが難しいことについては、rebuild.fmのエピソード99参照。
http://rebuild.fm/99/


# 雑感

QUICのサンプル実装をやってみたい。
時間を見つけてService Workerとhttp2のウェブプッシュを試してみたい。
h2oのクッキーも。

隣にMark Nottinghamが座っていて少し緊張した。