2016年12月3日土曜日

Buffaloの無線LAN経由で、Beta By Crashlyticsのアプリダウンロードが失敗する

いつもお世話になっているCrashlyticsですが、
アプリのダウンロードがエラー(Timeout)になることが多かったんですが、
いろいろ試した結果、Buffaloの無線LANの設定を変更したところアプリのダウンロードが成功するようになりました。
毎回途中まで(20%~60%くらい)ダウンロードできるだけに切り分け難しかったんですが。

「Multicast Rate」の値を1Mbpsから24Mbpsに変更した。

これが原因ということは言い切れないわけですが、うちではうまくいきました。
そういうこともあるようです。

2016年9月29日木曜日

macOS SierraにアップグレードしたらSSHエージェント転送できなくなったよ

El CapitanからmacOS Sierrraにアップグレードして前回のアップグレードと違って問題ないなと思っていたら・・・ SSHエージェント転送できないじゃないですか。

sshのバージョンが変わったのか設定が変わったのかまでは調べてませんが、
次の設定を追加して無事完了です。

.ssh/config
AddKeysToAgent yes
いつもクリーンインストールしてますが、今回はこのまま次のバージョンまで使うかな。

追記

ssh -V
OpenSSH_7.2p2, LibreSSL 2.4.1
バージョンを確認したところ7.2だったので、おそらくこのバージョンからのオプション(新機能)が必要になったようです。
http://www.openssh.com/txt/release-7.2
New Features
------------

 * ssh(1): Add an AddKeysToAgent client option which can be set to
   'yes', 'no', 'ask', or 'confirm', and defaults to 'no'.  When
   enabled, a private key that is used during authentication will be
   added to ssh-agent if it is running (with confirmation enabled if
   set to 'confirm').
ただの新機能あるあるでした。失礼いたしました。

2016年8月3日水曜日

Windows 10 Anniversary UpdateしたのでBashを試す

Windows 10 Anniversary Updateをさっそくインストールしました。
時間かかるので作業しない時にやるのがおすすめです。

参考 アップデートの所要時間

  • ダウンロード 30分
  • インストール(再起動)20分
  • Bashインストール 10分

Windows Subsystem for Linux (Beta)を有効化する

まだbeta版なんですね。
有効化してPCを再起動します。

コマンドプロンプトからbashを起動する

>bash
-- ベータ機能 --
これにより Windows に Ubuntu がインストールされます。Ubuntu は Canonical によって配布される製品であり、
次のサイトに示される条件に基づいてライセンスされています。
https://aka.ms/uowterms

この機能を使用するためには開発者モードを有効にする必要があります。
ベータ版なので、開発者モードが必要なのかな?

開発者モードに変更する

  1. Windowsキー + Iキーで「Windowsの設定」画面を開く
  2. 「更新とセキュリティー」をクリック
  3. サイドメニューの「開発者向け」をクリック
  4. 「開発者モード」をクリック
  5. 「はい」をクリック
  6. 念のため再起動(おそらく不要)

コマンドプロンプトからbashを起動する

>bash
-- ベータ機能 --
これにより Windows に Ubuntu がインストールされます。Ubuntu は Canonical によって配布される製品であり、
次のサイトに示される条件に基づいてライセンスされています。
https://aka.ms/uowterms

続行するには、"y" を入力してください:
Windows ストアからダウンロードしています... 100%
ファイル システムを展開しています。この処理には数分かかります...
ストアからダウンロードなんですね。
UNIX ユーザー アカウントを作成してください。ユーザー名は、Windows のユーザー名と一致する必要はありません。
詳細: https://aka.ms/wslusers を参照してください
新しい UNIX ユーザー名を入力してください:
Windowsとは別世界のようですので、ユーザー名を設定しました。
Microsoftアカウントとは別に扱えるので、私にとってはこの仕様は助かります。
新しい UNIX ユーザー名を入力してください: 
新しい UNIX パスワードを入力してください:
新しい UNIX パスワードを再入力してください:
passwd: password updated successfully
インストールが正常に終了しました
環境が間もなく開始されます...
ドキュメントを参照できる場所: https://aka.ms/wsldocs
***@DESKTOP:/mnt/c/Users/username$
おおおおお、そのまま使える。すこし感動
$ uname -a
Linux DESKTOP 3.4.0+ #1 PREEMPT Thu Aug 1 17:06:05 CST 2013 x86_64 x86_64 x86_64 GNU/Linux
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          224G   46G  178G  21% /
tmpfs           224G   46G  178G  21% /run
none            224G   46G  178G  21% /run/lock
none            224G   46G  178G  21% /run/shm
none            224G   46G  178G  21% /run/user
$ ls -la /
合計 141
drwxr-xr-x 2 root root     0  1月  1  1970 .
drwxr-xr-x 2 root root     0  1月  1  1970 ..
drwxr-xr-x 2 root root     0  8月  3 08:24 acct
drwxr-xr-x 2 root root     0  3月 24 05:45 bin
drwxr-xr-x 2 root root     0  3月 24 05:54 boot
drwxrwx--- 2 root root     0  1月  1  1970 cache
drwxrwx--x 2 root root     0  1月  1  1970 data
drwxr-xr-x 2 root root     0  8月  3 08:21 dev
drwxr-xr-x 2 root root     0  8月  3 08:21 etc
drwxr-xr-x 2 root root     0  1月  1  1970 home
-rwxr-x--- 1 root root 38896  1月  1  1970 init
drwxr-xr-x 2 root root     0  3月 24 05:54 lib
drwxr-xr-x 2 root root     0  3月 24 05:42 lib64
drwx------ 2 root root     0  3月 24 05:46 lost+found
drwxr-xr-x 2 root root     0  3月 24 05:41 media
drwxr-xr-x 2 root root     0  1月  1  1970 mnt
drwxr-xr-x 2 root root     0  3月 24 05:41 opt
dr-xr-xr-x 1 root root     0  8月  3 08:21 proc
drwx------ 2 root root     0  1月  1  1970 root
drwxr-xr-x 2 root root     0  8月  3 08:21 run
drwxr-xr-x 2 root root     0  3月 24 05:45 sbin
drwxr-xr-x 2 root root     0  3月 24 05:41 srv
dr-xr-xr-x 1 root root     0  8月  3 08:21 sys
drwxrwxrwt 2 root root     0  8月  3 08:19 tmp
drwxr-xr-x 2 root root     0  3月 24 05:41 usr
drwxr-xr-x 2 root root     0  3月 24 05:45 var
気になるエディターは?
$ sudo update-alternatives --config editor
alternative editor (/usr/bin/editor を提供) には 4 個の選択肢があります。

  選択肢    パス              優先度  状態
------------------------------------------------------------
* 0            /bin/nano            40        自動モード
  1            /bin/ed             -100       手動モード
  2            /bin/nano            40        手動モード
  3            /usr/bin/vim.basic   30        手動モード
  4            /usr/bin/vim.tiny    10        手動モード
vimにしました。
$ screen
Cannot make directory '/var/run/screen': 許可がありません
screenはそのままでは起動せずディレクトリを作成した。
sudo mkdir /var/run/screen
sudo chmod 777 /var/run/screen
tmuxは問題なく起動した。
sudo: ホスト HOSTNAME の名前解決ができません
sudoコマンドは毎回名前解決で失敗するので/etc/hostsにコンピュータ名を登録した。

細かいところはいろいろありそうですが、使えそうな予感です。
Insider previewの不具合を恐れてこれまで使えなかったのですが、しばらくこれで遊んでみます。
この手軽さ・・・、今までのWindowsはなんだったのか・・・
最後に、
Windowsメニューに表示される名前は「Bash on Ubuntu on Windows」という長い名前でした。



2016年7月31日日曜日

Windows10にアップグレードしたのですぐに開発で使えるようにした

Windows10の無料アップグレード終了前にWindows7, 8.1を駆け込みでアップグレードしました。

Windows7はアップグレードで、Windows8.1はクリーンインストールでWindows10構築しました。


これまでも何回かアップグレードにチャレンジしましたが、デバイスドライバやソフトが未対応で使えなかったので見送っていましたが、最後のチャレンジだと思って試したところ問題ありませんでした。ぎりぎりまでアップグレード見送ろうと思っていましたがやってよかったです。

ちなみに、未対応だったソフトやデバイスドライバは、ここでご紹介するものではありません。


すぐに仕事で使えるようにしたかったので、次の3つをすぐにインストールしました。

ただ、VSC以外はリリース版ではないので導入は自己責任になります。

  • win-sshfs
  • Rlogin
  • Visual Studio Code

Dokany 1.0.0-RC4

stableではないのですが、バグフィックスも進んでいるようです。

DokanSetup.exeをダウンロードしてインストールしました。

https://github.com/dokan-dev/dokany/releases

win-sshfs 1.6.0 RC2

https://github.com/Foreveryone-cz/win-sshfs/releases

release-1.6.0-rc2.zipをダウンロードして解凍、保存しました。


RLogin (2.20.6)

ターミナルはRloginを試してみました。

こちらも今のところ問題なく動作しています。

http://nanno.dip.jp/softlib/man/rlogin/

Visual Studio Code

エディターは、VSCを試しています。

https://www.visualstudio.com/ja-jp/products/code-vs.aspx

これいいですね。

昔はVisual Studioが最高だと思っていたこともあったので、そのクオリティーで今後もアップグレードされるのを期待します。


2016年3月5日土曜日

Amazon SESを使ったLumen(Laravel)のメール送信

Lumen(5.1)では、Laravelのメール機能が標準では含まれていないので、追加して試してみました。

参考

https://laravel.com/docs/5.1/mail

追加するパッケージ

composer.jsonのrequireに以下のパッケージを追加してcomposer updateします。
 "illuminate/mail": "5.1.*",
 "aws/aws-sdk-php": "~3.0",

設定ファイルの追加

config/mail.phpとconfig/services.phpファイルの作成(デフォルト設定ファイルmail.phpをコピーする)
// configディレクトリが無い場合は作成する
cp vendor/laravel/lumen-framework/config/mail.php config/mail.php

// services.phpは空ファイルを作成して設定値を自分で記述した
touch config/services.php

config/mail.phpの修正

// デフォルト値をsesと書き換える。または環境変数MAIL_DRIVERを設定する
driver' => env('MAIL_DRIVER', 'ses'),

config/services.php

awsで作成した値を設定します。
<?php
return [
    'ses' => [
        'key'    => 'keyの値',
        'secret' => 'secretの値',
        'region' => 'リージョンの値',  // e.g. us-east-1
    ]
];

テンプレートの作成

// テンプレートファイルを作成
touch resource/views/emails/example.blade.php
テンプレートには、通常のviewと同様に変数を渡せます。

HTMLメールの送信

Mail::send('emails.example', ['user' => $user], function ($m) use ($user) {
    $m->from('hello@app.com', 'Your Application');
    $m->to('メールアドレス', '名前')->subject('テストメールの件名');
});

テキストメールの送信

// テンプレートの値を配列にしてキーをtext、値にテンプレートのパスを指定する
Mail::send(['text' => 'emails.example'], ['user' => $user], function ($m) use ($user) {
    $m->from('hello@app.com', 'Your Application');
    $m->to('メールアドレス', '名前')->subject('テストメールの件名');
 });

// 配列でhtmlメールを指定する場合
Mail::send(['html.view', 'text.view'], $data, $callback);

まとめ


Laravelのドキュメントを確認した限りでは、送信オプションもいろいろ網羅されているので細かい調整もできそうです。標準以上の機能が必要なケースはあまりないかもしれませんが、もっとカスタマイズが必要な場合は、コアのソースを確認して調査する必要がありそうです。
あと、Amazon SESはデフォルトで送信制限があるので、テスト用のメールアドレスはあらかじめSES側で設定とverify(メールアドレスの有効性の確認)しておく必要があります。制限解除済みであれば登録不要です。

2016年2月14日日曜日

Laravel, LumenのSELECT文いろいろ

Laravel, LumenでSELECT文に慣れていないのでメモ。

参考

https://laravel.com/docs/5.1/eloquent#retrieving-single-models

SELECTもいろいろある

find

  • プライマリーキーでマッチした1レコードを取得する
  • 戻り値はモデルのインスタンス(stdClass)
  • 0件の場合は、null
$flight = Flight::find(1);

first

  • 条件にマッチした最初の1レコードを取得する
  • 戻り値はモデルのインスタンス(stdClass)
  • 0件の場合は、null
$flight = Flight::where('active', 1)->first();

get

  • 条件にマッチした全てのレコードを取得する
  • 戻り値は、配列(各レコードはstdClassオブジェクトのインスタンス)
  • 0件の場合は、オブジェクトが返る
$flight = Flight::where('active', 1)->get();

all

  • 全てのレコードを取得する
  • 戻り値は、配列(各レコードはstdClassオブジェクトのインスタンス)
  • 0件の場合は、オブジェクトが返る
$flight = Flight::all();

0件の場合の評価の違い

$flight = Flight::find(1);
if (!$flight ) {
  // 通る
}

$flight = Flight::where('id', 1)->first();
if (!$flight ) {
  // 通る
}

$flight = Flight::where('id', 1)->get();
if (!$flight) {
    // 通らない (オブジェクトが戻り値のため)
}
if (!count($flight)) {
    // 通る Countableインターフェース
}

$flight = Flight::where('id', 1)->get()->toArray();
if (!$flight) {
    // 通る (オブジェクトを配列に変換したため)
}
if (!count($flight)) {
    // 通る
}

$flight = Flight::all();
if (!$flight) {
    // 通らない (オブジェクトが戻り値のため)
}
if (!count($flight)) {
    // 通る Countableインターフェース
}

まとめ

  • get(), all()の場合は、0件の場合もオブジェクトが返る。
  • Objectはtrueということと、1件または複数レコード(get()を使うか)を意識して書けばよさそう。
  • Illuminate\Database\Eloquent\Collectionは、継承しているクラスがCountableインターフェースを実装していてcount()でitemsの件数が取れる。
Illuminate\Database\Eloquent\Collection Object
(
    [items:protected] => Array
        (
        )
)


2016年2月4日木曜日

Lumenのタイムゾーン設定

Lumenを検証していたところ、時間がUTCになっていたのでメモ

Lumen5.1で時間を表示させたところUTCとなっていました。
echo date('Y-m-d H:i:s e P'); // 2016-02-04 09:00:23 UTC +00:00
Asia/Tokyoとなってほしいのですが、
アプリ側では何も設定していないので、lumenのソースを確認したところ見つかりました。

lumen-framework/src/Application.php

    public function __construct($basePath = null)
    {
        date_default_timezone_set(env('APP_TIMEZONE', 'UTC'));
        $this->basePath = $basePath;
        $this->bootstrapContainer();
        $this->registerErrorHandling();
    }
この場合、環境変数APP_TIMEZONEは設定していないのでUTCになるわけですが、
デフォルト値をphp.iniの設定にしてほしいのは私だけでしょうか。

Dotenvを使っている場合は、.envに追加
使っていない場合は、bootstrap/app.phpに設定を追加することにしました。

.env

APP_TIMEZONE=Asia/Tokyo

bootstrap/app.php

// Dotenv::load(__DIR__.'/../');
putenv('APP_TIMEZONE=Asia/Tokyo');
軽量フレームワークなので、かゆいところは自分で対応する必要があるわけですが、
これはドキュメントに書いてほしいですね。

2016年1月18日月曜日

LaravelとLumenでベンチマークやり直し

前回の「LaravelとLumenのHello Woldを試す」は実用的な計測ではないので、
もう少し通常の動的サイトに近い処理を追加して計測してみました。

テスト環境

前回の記事を参照

LaravelとLumenで以下のファイルを追加

  • ルーティング設定でHomeコントローラを指定する (app/Http/routes.php)
  • データベース設定を追加する (config/database.php)
  • コントローラーにデータを取得する処理を追加する (app/Http/Controllers/HomeController.php)
  • モデル追加する (app/Page.php)
  • ビュー追加する (resources/views/home/index.php)
  • ビュー上でデータをforeachで20件ほど表示する
  • セッション機能はfileを使用する
  • Lumenは、機能(DotEnv, Facade, Eloquent)を削る毎にHomeControllerを修正する

Lumenは機能の有無で4パターン計測

機能の切り替えは、bootstrap/app.phpを修正する
  • DotEnv, Facade, Eloquentを使用する
  • DotEnv, Facadeを使用する
  • DotEnvを使用する
  • DotEnv, Facade, Eloquentを使用しない

Lumen5.2ではなく5.1も対象している理由

Lumen5.2ではAPI Tokenの利用を前提にしているようでsession機能が削除されました。
独自にsession機能を追加すると別のものになってしまうので、できるだけLumenをLaravelに近づけるため5.1の計測をしてみました。
ちなみに、sessionを利用したい場合は、Laravelがおすすめとのこと。

結果

framework req/sec
Laravel 5.2692.81
Lumen 5.1 (DotEnv, Façade, Eloquent)1,341.92
Lumen 5.1 (DotEnv, Façade)1,523.70
Lumen 5.1 (DotEnv)1,632.32
Lumen 5.2 (DotEnv)1,663.94
Lumen 5.11,769.84

前回の結果ほど差はありませんが、1.9〜2.5倍程度Lumenの処理性能が速い結果となりました。
DotEnv, Facade, Eloquentを使っても約2倍近い性能を得ることができるので、パフォーマンス重視の方は選択肢の1つとなるのではないでしょうか。
ソースの書き方によってはLaravelに近づけることや移植もできると思うので、良い派生プロジェクトではないでしょうか。

2016年1月15日金曜日

LaravelとLumenのHello Woldを試す

バルス待機中に気になったので確認してました。
「The stunningly fast micro-framework by Laravel.」と公言しているLumenですが、
Laravelとどの程度の差があるかHello Worldで計測してみました。

テスト環境

Intel Core i7-4790K
メモリー 16GB
Ubuntu 15.10
PHP 5.6.11
nginx/1.9.3

  • 特別なチューニングはしていません
  • nginxとphp-fpmの設定もインストールした時のデフォルトのままです。
  • LaravelとLumenはcomposerインストールした状態です
  • どちらもroute.phpで文字列"Hello World!"を返すように修正しました。
  • abコマンドで計測しました

結果

Laravel 5.2     928.19 req/sec
Lumen 5.2     5589.13 req/sec
予想以上に差が出てしまいました。約6倍
機能の数が違うので、検討すべきことは多いですが、LumenはAPIサーバとかに向いているかも。オーバーヘッドの少ないWAFですね。
なかなか悩ましい結果となりました。

以上、簡易的なベンチマークでした。


Laravel 5.2

ab -c 100 -n 10000 http://laravel.local/
This is ApacheBench, Version 2.3 <$Revision: 1638069 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking laravel.local (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx/1.9.3
Server Hostname:        laravel.local
Server Port:            80

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   10.774 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      2580000 bytes
HTML transferred:       120000 bytes
Requests per second:    928.19 [#/sec] (mean)
Time per request:       107.737 [ms] (mean)
Time per request:       1.077 [ms] (mean, across all concurrent requests)
Transfer rate:          233.86 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     4  107  10.0    105     130
Waiting:        4  107  10.0    105     130
Total:          5  107  10.0    105     130

Percentage of the requests served within a certain time (ms)
  50%    105
  66%    113
  75%    114
  80%    115
  90%    117
  95%    125
  98%    128
  99%    128
 100%    130 (longest request)

Lumen 5.2

ab -c 100 -n 10000 http://lumen.local/
This is ApacheBench, Version 2.3 <$Revision: 1638069 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking lumen.local (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests


Server Software:        nginx/1.9.3
Server Hostname:        lumen.local
Server Port:            80

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   1.789 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      2110000 bytes
HTML transferred:       120000 bytes
Requests per second:    5589.13 [#/sec] (mean)
Time per request:       17.892 [ms] (mean)
Time per request:       0.179 [ms] (mean, across all concurrent requests)
Transfer rate:          1151.67 [Kbytes/sec] received

Connection Times (ms)
             min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       2
Processing:     1   18   2.7     17      25
Waiting:        1   18   2.7     17      25
Total:          2   18   2.7     17      25

Percentage of the requests served within a certain time (ms)
 50%     17
 66%     18
 75%     18
 80%     19
 90%     22
 95%     24
 98%     24
 99%     24
100%     25 (longest request)