Go言語の関数とループ
A Tour of Goを進めてたのでその備忘
問題:
関数とループを使った簡単な練習として、 ニュートン法 を使った平方根の計算を実装してみましょう。
ニュートン法は、開始点 z を選び、以下の式を繰り返すことによって、 Sqrt(x) を近似します:
最初は、その計算式を10回だけ繰り返し、 x を(1, 2, 3, ...)と様々な値に対する結果がどれだけ正解値に近づくかを確認してみてください。
次に、ループを回すときの直前に求めたzの値がこれ以上変化しなくなったとき (または、差がとても小さくなったとき)に停止するようにループを変更してみてください。 この変更により、ループ回数が多くなったか、少なくなったのか見てみてください。 math.Sqrt と比べてどれくらい近似できましたか?
回答:
gist.github.com
docker toolboxで作成したdocker0のアドレス帯の変更
デフォルトでは 172.17.0.0/16 が使用されているが、社内ネットワークの都合でこれを変更したかったのでその方法です。
docker toolboxを利用する場合、docker-machineを利用して、boot2dockerのVMが起動していると思います。
docker-machine ssh
でdocker daemonが起動しているサーバにログインして以下の作業を行います。
まずdockerを停止
docker stop
既存のbridgeを削除します。
ifconfig docker0
で、docker0インタフェースに172.17.0.0/16が設定されていることがわかります。
この設定を残したまま、dockerの起動時オプションに別にアドレス帯を指定してもエラーになってしまうので、まず削除します。
ip link del docker0
で削除。
あとはdocker daemonをbipオプションを渡して起動する。
あまりよい方法ではないですが、
boot2docker/docker at master · boot2docker/boot2docker · GitHub
の
/usr/local/bin/docker daemon -D -g "$DOCKER_DIR" -H unix:// $DOCKER_HOST $EXTRA_ARGS >> "$DOCKER_LOGFILE" 2>&1 &
を
/usr/local/bin/docker daemon -D --bip=192.168.42.1/24 -g "$DOCKER_DIR" -H unix:// $DOCKER_HOST $EXTRA_ARGS >> "$DOCKER_LOGFILE" 2>&1 &
として、dockerを起動すると、 192.168.42.1/24 が適用されます。
ifconfig docker0
で結果が確認可能
mackerel-agentをchefでamazon-linuxにインストールするとエラーになった件
公式の手順にあるようにchefのcookbookを利用してインストールすると、サービスの起動時にエラーになる。
エラーの内容は以下
Starting mackerel-agent:/etc/init.d/mackerel-agent: 36 行: 7214 Trace/breakpoint trap $BIN ${APIBASE:+--apibase=$APIBASE} ${APIKEY:+--apikey=$APIKEY} --pidfile=$PIDFILE --root=$ROOT $OTHER_OPTS >> $LOGFILE 2>&1
結論:
最新版(v1.2.1)を利用する
cookbook 'mackerel-agent', tag: 'v1.1.0'
ではなく
cookbook 'mackerel-agent', tag: 'v1.2.1'
以下調べた履歴
mackerel.io
で、Amazon Linux AMI 2016.03での不具合が報告されているものの、修正済みのはず。
試しにchefではなく公式の手順で手動でインストールしてみると問題なくインストールできる。
手順は下記の内容
mackerel.io
この手順で入るってことは、何か別のものをインストールしているのかも?ってことで公式の手順にある "https://mackerel.io/file/script/amznlinux/setup-yum.sh"の内容を確認してみると
# import GPG key gpgkey_path=`mktemp` curl -fsS -o $gpgkey_path https://mackerel.io/assets/files/GPG-KEY-mackerel rpm --import $gpgkey_path rm $gpgkey_path # add config for mackerel yum repos rpm -ivh http://yum.mackerel.io/amznlinux/latest/x86_64/mackerel-repo-1-0.noarch.rpm
となっていて、amazon linux用のレポジトリを用意している様子。
一方chefのrecipeは
if platform?('centos') or platform?('redhat') or platform?('amazon') ~ yum_repository "mackerel" do gpgkey gpgkey_url if yum_cookbook_ver >= Gem::Version.new('3.0.0') description "mackerel-agent monitoring" url "http://yum.mackerel.io/centos/$basearch" action :add end
となっていて、これが原因だった。
"http://yum.mackerel.io/centos/$basearch"を"http://yum.mackerel.io/amznlinux/$releasever/$basearch"に書き換えたところ問題なく動作した。
そしてここまでたどり着いたところで、最新のレポジトリでは対応済みなことに気づいた。。
Support Amazon Linux repo · mackerelio/cookbook-mackerel-agent@499d779 · GitHub
PhoenixでHTTP Headerを利用した認証を行う
PhoenixでAPIを実装するときに、http headerを利用して簡易な認証を行う時の方法。
http headerで認証を行うplugを作成します。
/web/plugs/api_auth.ex
defmodule App.Plug.APIAuth do import Plug.Conn def init(default), do: default def call(conn, auth_header) do {key, value} = auth_header header = Enum.find(conn.req_headers, &elem(&1, 0) == key) if header && elem(header, 1) == value do conn else send400 conn end end defp send400(conn) do conn |> put_resp_content_type("text/plain") |> send_resp(400, "Bad Request") |> halt end end
Phoenixの場合、http headerはconn.req_headersで取得できるのでそれを利用します。
{key,value}のtupleのリストになっています。
Plug.Conn – Plug v1.1.6
作成したPlugをRouterに設定すれば完了です。
web/router.ex
pipeline :api do plug :accepts, ["json"] plug App.Plug.APIAuth, {"x-sample-key", "xxxxx"} end
環境毎に変更する場合は、configに追記して、Application.get_env で取得すればok
phoenix以外からphoenixのchannelを利用する
Rails + node.js(+socket.io) で作ったアプリの、node.jsの部分をphoenixに置き換えてみたときに必要だった。
phoenixのchannelのclientは
github.com
にあり、このファイルを利用すればよい。
es6で書かれているが、他のファイルに依存はしていないので、babelでコンパイルしたものを配置すればok。
phoenix.jsを読み込んでしまえば、phoenixのチュートリアルにあるように
var phoenix = require("phoenix"); socket = new phoenix.Socket("/socket", {params: {token: window.userToken}});
のようにして利用できる。
別のwebアプリケーションからphoenixのchannel使いたいケースって結構ありそうだけど、現状はこれしか方法なさそう。
(とはいえ、socket.ioほど分厚い仕様があるわけではないので、client自作してしまうのあり)
ちなみに、他の言語のクライアントは現在以下の3つらしい。
emberのfastbootについて調べた
前からちょっと気になっていたのだけど、時間がとれたので調べてみました。
↓の動画で説明されてます。
vimeo.com
fastbootとは、emberが用意しているSSR(サーバーサイドレンダリング)の仕組みで、nodejsでemberアプリを動かしている。
つまり、サーバサイドアプリとemberアプリはそれぞれ独立しているのが前提。
たとえば、Railsでwebアプリを作っていた場合、fastbootを利用するには、unicornなどのアプリケーションサーバとは別にnodejsが必要です。
jQueryなど、ブラウザのAPIに依存した処理があると、当然エラーになります。($.ajax('xxxx')みたいな)
ember-networkのようにemberがplolyfilを用意していて、ここは開発者が気を付けて開発する必要あり。
あと、クライアントMVCのSSRで気になるのは、DOMの生成ですが、
emberの場合は、htmlbarsというemberで利用しているテンプレートエンジンがhtmlのサブセットを理解できて、それを利用しています。
HTMLBars: The Next-Generation of Templating in Ember.js
手元で確認してみたところ
<div> <span>welcome to ember</span> <div> {{outlet}} </div>
がfastboot用にビルドを行ったところ
buildFragment: function buildFragment(dom) { var el0 = dom.createDocumentFragment(); var el1 = dom.createElement("div"); var el2 = dom.createTextNode("\n"); dom.appendChild(el1, el2); var el2 = dom.createElement("span"); var el3 = dom.createTextNode("welcome to ember"); dom.appendChild(el2, el3); dom.appendChild(el1, el2); var el2 = dom.createTextNode("\n"); dom.appendChild(el1, el2); var el2 = dom.createElement("div"); var el3 = dom.createTextNode("\n "); dom.appendChild(el2, el3); var el3 = dom.createComment(""); dom.appendChild(el2, el3); var el3 = dom.createTextNode("\n"); dom.appendChild(el2, el3); dom.appendChild(el1, el2); var el2 = dom.createTextNode("\n\n"); dom.appendChild(el1, el2); dom.appendChild(el0, el1); var el1 = dom.createTextNode("\n"); dom.appendChild(el0, el1); return el0; }
に変換されていました。
ReactとJSXの関係に近いですね。JSXは結構制約が強いイメージだったけど、htmlbarsは自由度高そうな雰囲気。
webのフロントエンドは日々複雑になっているし、スマホアプリにAPIを提供するみたいに、サーバーサイドアプリはAPIに徹して、webのフロントエンドはクライアントMVC(SSR出来ればなおよし)で構築するのもよいんじゃないかなという気もしてきました。
emberそんなに悪くないと思うんだけど、日本語リソースが少ないのが気になるところ。
複雑なwebアプリ作るときには結構現実的な選択肢だと思うんですけどね。