読者です 読者をやめる 読者になる 読者になる

とっしぃのTech Memo

PHPとかサーバとか他色々言語のメモ的な。あとはたまにガジェットとか。

AWS Route53でRate for operation ChangeResourceRecordSets exceeded

業務でAWSのRoute53を使ってるんですが、このレコードセットを変更しようとした際に出た下記のエラー

Rate for operation ChangeResourceRecordSets exceeded

f:id:tossy_yukky:20170314184014p:plain

何度Save Record Setボタン押しても出てきちゃって何がまずいねんと思ってたんですが、
まぁやっぱりStack Overflow先生ですよね。
stackoverflow.com

ココ見ろよと。
https://status.aws.amazon.com/


思いっきり出てますね。

Amazon Route 53    Slow propagation times

f:id:tossy_yukky:20170314183855p:plain
これはNorth Americaリージョンの画面ですが、案の定他のリージョンも同じように出てました。

つまりこれはもう待つしかないってことですね。

追記
ちなみに載っていた情報をgoogle翻訳先生に見てもらったらこんな感じ。

Mar 14, 1:50 AM PDT Record changes are slowly propagating, while we work through the backlog of pending changes that have accumulated. We still expect full recovery to take several more hours. We are continuing to throttle ChangeResourceRecordSets API calls. Queries to existing DNS records remain unaffected.
蓄積された保留中の変更のバックログを調べながら、記録の変化はゆっくりと伝播しています。まだ完全回復にはさらに数時間かかることが予想されます。私たちは、ChangeResourceRecordSets APIコールを抑制し続けています。既存のDNSレコードへのクエリは影響を受けません。

PDTなのでJSTだと 3/14 17:50 ですね。

Laravel5.2でパスワードリセットのメールをテキストで送りたい

なんでデフォルトがHTMLなんや。

でもテキストで送れないとなるとトークン自分で作ったりその認証したりめんどいので なんとかソースコード追って設定(+override)でどうにかしたい。

まずはRouting

Laravelは5.2からartisanコマンドにmake:authが出来て、ルーティングやらなんやらを一気にやってくれるようになったみたいですね。 5.1以前をやったことないので前は知らないけど(´・ω・`)

とりあえずphp artisan make:authを打ってみて、ルーティングを見てみる。

Route::post('password/email', 'Auth\PasswordController@sendResetLinkEmail');

PasswordControllerのsendResetLinkEmailメソッドでメールを発行しているらしい。

じゃあそのメソッド見れば解決やん。

・・・

ない(´・ω・`)

そんなメソッド書いてない(´・ω・`)

ということでPasswordControllerの上の方を見てみると

    use ResetsPasswords;

という記述が。

Laravelはこういったtrait機能をふんだんに使った書き方がされているみたい。

んでそのtraitは

use Illuminate\Foundation\Auth\ResetsPasswords;

とのことなのでそちらを見てみるとありましたねsendResetLinkEmail

    /**
     * Send a reset link to the given user.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function sendResetLinkEmail(Request $request)
    {
        $this->validate($request, ['email' => 'required|email']);

        $broker = $this->getBroker();

        $response = Password::broker($broker)->sendResetLink(
            $request->only('email'), $this->resetEmailBuilder()
        );

        switch ($response) {
            case Password::RESET_LINK_SENT:
                return $this->getSendResetLinkEmailSuccessResponse($response);

            case Password::INVALID_USER:
            default:
                return $this->getSendResetLinkEmailFailureResponse($response);
        }
    }

この中でメールを送っているらしき部分は

        $response = Password::broker($broker)->sendResetLink(
            $request->only('email'), $this->resetEmailBuilder()
        );

なので、今度はそこをvendor/laravelの中で探すと vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.php にそれっぽいのを発見。

    /**
     * Send the password reset link via e-mail.
     *
     * @param  \Illuminate\Contracts\Auth\CanResetPassword  $user
     * @param  string  $token
     * @param  \Closure|null  $callback
     * @return int
     */
    public function emailResetLink(CanResetPasswordContract $user, $token, Closure $callback = null)
    {
        // We will use the reminder view that was given to the broker to display the
        // password reminder e-mail. We'll pass a "token" variable into the views
        // so that it may be displayed for an user to click for password reset.
        $view = $this->emailView;

        return $this->mailer->send($view, compact('token', 'user'), function ($m) use ($user, $token, $callback) {
            $m->to($user->getEmailForPasswordReset());

            if (! is_null($callback)) {
                call_user_func($callback, $m, $user, $token);
            }
        });
    }

見事にsendしてる。

んでここの$view、その前を見ると$this->emailViewを、テキストメールの送り方である['text' => 'view_name']にできればおっけー。

その$this->emailViewはどうやらコンストラクタで設定されているようなので、PasswordBrokerをnewしてるところを探せばいけるんじゃないかね。

するとnewしてるのはvendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBrokerManager.phpと判明。

その中のresolveメソッドでnewしてた。

    /**
     * Resolve the given broker.
     *
     * @param  string  $name
     * @return \Illuminate\Contracts\Auth\PasswordBroker
     *
     * @throws \InvalidArgumentException
     */
    protected function resolve($name)
    {
        $config = $this->getConfig($name);

        if (is_null($config)) {
            throw new InvalidArgumentException("Password resetter [{$name}] is not defined.");
        }

        // The password broker uses a token repository to validate tokens and send user
        // password e-mails, as well as validating that password reset process as an
        // aggregate service of sorts providing a convenient interface for resets.
        return new PasswordBroker(
            $this->createTokenRepository($config),
            $this->app['auth']->createUserProvider($config['provider']),
            $this->app['mailer'],
            $config['email']
        );
    }

どうやら$config['email']がそれっぽい。

んで$this->getConfig($name);はというと

    /**
     * Get the password broker configuration.
     *
     * @param  string  $name
     * @return array
     */
    protected function getConfig($name)
    {
        return $this->app['config']["auth.passwords.{$name}"];
    }

これっすねー。

Laravelのconfigファイルは、configディレクトリ以下にファイルを置くだけで使えるので、 この記述からはconfig/auth.phpファイルのpasswords['email']を見ている、と。

ということで、上記を['text' => 'auth.emails.password']に変えてみたら見事にテキストメールで送られました。

ふぅ(´・ω・`)

ES6でReact使ってたらsetStateがundefinedとか怒られた件

急に寒くなってきたこの頃、いかがお過ごしでしょうか。

鼻水やらくしゃみやら頭痛やら止まらなくて調べたら「寒暖差アレルギー」なんじゃないかと思い始めました。

とっしぃです。

Uncaught TypeError: Cannot read property 'setState' of undefined

ところで、業務に関係ありそうでなさそうな適当なツールChromeのextensionで作ってみようと思い、 どうせ外に出すわけでもないツールだし以前から興味のあったReactで書いていたわけです。

更にどうせならES6で書かない理由もないということで、

var CommentBox = React.createClass({
...

ではなく

class CommentBox extends React.Component {
...

って感じ。

でもそこで

class CommentBox extends React.Component {
    
    constructor(props) {
        super(props);
        let data = localStorage.getItem('data_key');
        this.state = {
            data: data
        }
    }

    changeData(e) {
        this.setState({data: e.target.value});
    }

    save(e) {
        e.preventDefault();
        localStorage.setItem('data_key', this.state.data);
        return false;
    }

    render() {
        <form>
            <Input type="text" value={this.state.data} onChange={this.changeData} label="DATA" />
            <button onClick={this.save}>SAVE</button>
        </form>
    }
}

的に書いてみたところ、developer toolのコンソールに

Uncaught TypeError: Cannot read property 'setState' of undefined

とか出てるじゃないですか。

色んなチュートリアル見ながらその通りやったのに(´・ω・`)

調べてみると

qiita.com

facebook.github.io

どうやら

var CommentBox = React.createClass({

で書いた場合はthisが勝手にbindされるけど、ES6で

class CommentBox extends React.Component {

って書いた場合はthisがbindされないとのこと。

なのでコンストラクタで明示的に

class CommentBox extends React.Component {
    constructor(props) {
        super(props);
        let data = localStorage.getItem('data_key');
        this.state = {
            data: data
        }

        this.changeData = this.changeData.bind(this);
        this.save = this.save.bind(this);
    }

とbindしてあげないといけないらしい。

まとめ

Reactもbabelもちょこちょこバージョン上がってるので npm install して落ちてきたバージョンが新し目だったらちゃんとリリースノート(の翻訳でもいいので)を見といた方がいいですね。 ReactなんてrenderメソッドがReactクラスじゃなくてReactDOMクラスのメソッドになってたし。

AWS EC2にt2.nanoインスタンスができた

おはようございます。 とっしぃです。

朝メールを見たらAWSからのお知らせメールで、EC2にt2.nanoインスタンスができたとのこと。

Introducing t2.nano: the Smallest, Lowest Cost Amazon EC2 Instance

スペック見た感じだとGoogleGoogle Conpute Engine f1-microインスタンスと同じくらいですかね。

メモリ vCPU 料金
EC2 t2.nano 512MB 1 4.75 USD/月(0.0065 USD/時間)
GCE f1-micro 0.6GB 1 5.00 USD/月(0.007 USD/時間(平均)

GCEの場合は月の稼働時間で若干変わるみたいなので平均値で。

今までは、適当に作って捨ててっていう遊びではf1-microで十分なのでGCEでやってたんですが t2.nanoができるとこれでもいいかもしれないですね。

ちょっとこっちでもやってみようかと思います。

PHP7を軽くいじってみる

とっしぃです。

もうすぐ2015年も終わってしまうということで駆け込み投稿です。

リリースされましたねPHP7。

PHP: News Archive - 2015

ということでちょっとばかり触ってみようと思います。

まずはインストール

なにはなくともインストールしないことには始まりません。

とりあえずいつも使っているさくらのVPSでやってみます。

yumにはあるのかな?

ありますね。さすがremi。仕事が速い。

blog.remirepo.net

適当に書いてある通りに入れてみます。

$ sudo yum-config-manager --enable remi-php70
$ sudo yum update php\*
$ sudo yum install php70

でもこのままやるとデフォルトでremi-php70リポジトリが有効になっちゃうので、 嫌な人はこっちの記事のやり方の方がいいかも。

blog.remirepo.net

$ sudo yum --enablerepo=remi update remi-release
$ sudo yum --enablerepo=remi-php70 update php\*

これで入ったと思うのでバージョン確認。

$ php -v
PHP 7.0.0 (cli) (built: Dec  5 2015 07:17:51) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies

おっけー☆

Let's try

一番の目玉は速度改善ではあるんですが、とりあえずは新しい文法というか記法ですかね。

ちなみにPHP7で追加・変更された文法・記法的なものは下記が詳しいですね。

d.hatena.ne.jp

このうち簡単に試せそうですぐに取り入れられそう、かつ有効性が高そうなものだと - スカラ型のタイプヒンティング - 関数・メソッドの戻り値についてのタイプヒンティング - ??(Null Coalesce)演算子 とかですかね。

引数のスカラ型タイプヒンティングはまぁ普段書いてる関数・メソッド定義に少々加えるだけなので ほんとにすぐに使えますね。

戻り値のタイプヒンティングも。

??(Null Coalesce)演算子は、今まで

$a = isset($b['index']) ? $b['index'] : '';

とか書いてたのが

$a = $b['index'] ?? '';

って書けるのはでかいですよね。

なんで同じ値を2回も書かなきゃならんのかと常々思ってましたし。

あとは無名関数とかはだんだん流行りの(?)関数型への道を進み始めてるって感じでしょうか。

$func = function($a) {
    return $a * 2;
}

とか

(function() {
    echo 'hoge';
})();

とか、一歩間違うとjavascriptかと思っちゃいますよね。

感想

まぁPHP7の恩恵のメインは速度だと思うので、とりあえずはWordpressとかCakePHP、Laravel辺りで実感するとして、 実際にある程度の規模のサイト、プログラムを書く時にはこれらの書き味的なものがじわじわと実感できそうな気がします。

業務でしばらく5.1とか使ってた後に、違うプロジェクトで5.4系とか使ったらarray()が[]で書けて無性に嬉しかったりそういうやつですねw

あとはそのうちASTで色々やってくれるツールとかもガンガン出てくると思うしその辺も期待ですかね。

以上です。

boot2dockerのポートフォワードで一瞬ハマる

ご無沙汰しております。 とっしぃです。

ホントにブログ続けられてる人ってすごいと思います。

こんな適当な、ぐぐればそこら中に転がってそうなネタでも 書かないことには続けられそうにないのでメモがてら書いておきます。

まぁDockerもboot2dockerもだいぶ今更感のあるネタではあるんですが、 今更感があるだけにちゃんと触ったことないのもどうかと思ってやりはじめたというのがきっかけです。

boot2dockerとは

とりあえず前提から。

  • macとかwindows上で、virtualboxVM使ってその上でDockerを動かすためのクライアント
    • 公式
    • 参考 qiita.com

Dockerとは

コンテナ技術による仮想環境ツール

VMみたいなサーバまるごと仮想化ではなく、コンテナという単位で動作するので色々サクサク。

Docker - Wikipedia

ちなみに言語はgoで書かれてるらしい。

本題

ポートフォワーディングのこと

本題です。

このboot2dockerを使ってDockerのコンテナをローカルのmac上で構築、httpサーバを動かした時に、 いくらやってもローカルのmacからhttpでアクセスできない、と。

Dockerのポートの設定としては、

  • Dockerfileに書く

EXPOSE 80 443

  • docker runする時に-pオプションでホストとバインドする
 $ docker run -p 8080:80 image_name

があるんですが、とりあえず上記設定をしてローカルのterminalから

$ curl localhost:8080

とやっても一向に取得できない(´・ω・`)

調べてみると、boot2dockerはVirtualBox上のVMで走ってるので、 VMのポートフォワード設定もしないといけないらしい。

なんかCLIからもいけるみたい。

$ VBoxManage controlvm "boot2docker-vm" natpf1 "nginx,tcp,127.0.0.1,8080,,80"

GUIコンソールから見てみても確かにできてるぽい。

もっかいチャレンジ。



.
.
.


取得できない(´・ω・`)

なんでやねん(´・ω・`)





ん?そういえばVM上でboot2dockerが走ってるってことは、

コンテナのポート -> VMのポート -> ローカルのポート

って3段階(2段階?)のポートフォワーディングかましてるってことか

つまり現状だと

コンテナ:80 -> VM:8080 -> ローカル:8080

になっちゃってるわけか。

さっきVirtualBoxでやった設定は、VM:80 -> ローカル:8080だから、

コンテナ:80 -> VM:80 -> ローカル:8080

にしないとダメってわけね。納得。



ということでdocker runのオプションを

docker run -p 80:80 image_name

にしてみたら見事に取得できた。

多分これがLinux上とかだと コンテナ:80 -> ローカル:8080 だけでいいんだろうな。

とりあえず解決したのでこれからDocker使ってAPIサーバとWebサーバとDBサーバ立てて フロントはReactでAPIはgoでとかやろう。

夏だしgolang始めてみました

ご無沙汰してます。

とっしぃです。

一度書くの止まっちゃうともう無限に止まっちゃうんですよねブログ。

その円環の理を破るためにもたまには更新します。

まえがき

最近の業務的には特にネタになるようなものがなく、淡々と改修やらなんやらやってたんですが、 プライベート、というかtwitter界隈でよく目にしていたgolang(GO言語)がなんか良さそうってんで ちょっとやってみっかと思ったのでその話でも。

なんでgolang

そもそもなんでgolangかっていうとこなんですが、理由は何点か。

  • 就職した時から転職するまではずっとjavaだったけど最近はphpjavascript、たまにbashくらいしか触ってなくて、もっかい静的な言語やりたいと思った
  • ちょっとしたサービス作りたくて、バックエンド・フロントエンドと考えたらバックエンドはAPIサーバ、フロントエンドはjsでのSPAが理想型(個人的には)だなーと思った
  • APIサーバだったらViewとか要らなくて、CakePHPやらLaravelやら、RoRやらDjangoやら、Expressやらは要らない、つまりphpとかrubyとかpythonじゃなくていい
  • だったら静的言語にしよか
  • でも今更Javaもなー。記述量は多かったしモダンさはないよね。仕事ならともかく趣味なら趣味に走ろう
  • js界隈、python界隈の人がgolanggolang言ってて気にはなっていた
  • 同じく名前よく聞いていたのはRustだけど、これはホントに文献なくて困った
  • んじゃもうgolangかなぁ

てな感じ。

調べてたらあのカヤックさんもgolang推進派ぽくて、これは今後やっといて損はないのかなとも。

www.kayac.com

golangてどんな言語やねん

ものすげーざっくりと、

  • 静的型付け言語
  • C系言語、Python辺りに影響を受けたらしい Go (プログラミング言語) - Wikipedia
  • セミコロン要らない
  • スライスっていう便利な配列みたいなのがある
  • ループはforだけ
  • switchで式が使える
  • switchでbreakいらない
  • runeなんていう厨二心をくすぐる型がある(int32と同じらしい)
  • 例外(Exception)がない
  • 構造体(struct)がある
  • 型定義ができる(type)
  • 継承がない
  • interfaceはある
  • 変数定義と代入を同時にやる:=って演算子がある
  • 並列処理が得意らしい
  • goルーチンてのがある

とりあえず何すりゃいいんだろう

まずはここと

golang-jp.org

ここ見ながら、

golang.jp

この演習やればよさそう

A Tour of Go

あとWeb系やるなら

qiita.com

とか

Atom(エディタ)の設定

qiita.com

とかって感じすかね。

今後

サービスの進捗とかgolangの発見とかあったらまた都度書いていきます。