[app]fuse

ちょうど、 https://www.fusetools.com/ というツールを見つけたので触ってみた。

期待としては、やっぱり簡単にアプリの雛形を作ることができ、その雛形を参考にAndroid/iOSの各プラットフォームでプロダクトを開発することができる状態でしょうか。

少し触った感じ、previewがうまく動かなかった…
マシンスペックも関係するのか。。。
まだBetaなので、もう少ししたらまた触ってみよう。

こういうのを試してみようとした。
https://www.fusetools.com/examples/circle-menu

Advertisements

[Elixir]Registerを覗く

key-value processとしてElixir1.4に入れる予定の Register というものが公開されました。

付属のベンチマークによると、以下のように高い性能が出ていることがわかります。

このベンチマークの内容は以下

https://github.com/elixir-lang/registry/blob/master/bench/shared.exs

プロセスを起動して、登録して。それを10000回登録する間の時間を計測しているみたいですね。
各ベンチマークの最後で登録した名前をチェックして、その欠損がないことを確認して終わり、と。

register/3 周りは以下

https://github.com/elixir-lang/registry/blob/master/lib/registry.ex#L535

ここら辺を見て回ると、 :ets テーブルを複数に分割(sharding)しているぽい。
同じようなことをしているものがあるのかなと調べてみると、以下のライブラリがすでに。

https://github.com/cabol/shards
https://github.com/cabol/exshards

プロセスを気軽に使えるように便利機能を拡充していく、という感じですかね。


おまけ

テストコード、繰り返しには以下のように fordescribetest を囲むことができるのですね。こう言う書き方もあるのねーという学びでした。

https://github.com/elixir-lang/registry/blob/master/test/registry_test.exs

[Elixir]diff of struct against elixir 1.2.6 and 1.3.1

pattern match with struct

  • Structでもpattern matchingすることができる
    • [Kernel] Allow variable struct names when matching, for example, %module{key: “value”} = struct

__struct__

__struct__ が補完候補に出てこない。けれど、使うことは可能。

  • Elixir 1.2.6
iex(1)> Version.
InvalidRequirementError    InvalidVersionError
Parser                     Requirement
__struct__/0               compare/2
match?/2                   parse/1
  • Elixir 1.3.1
iex(1)> Version.
InvalidRequirementError    InvalidVersionError
Parser                     Requirement
compare/2                  compile_requirement/1
match?/2                   match?/3
parse!/1                   parse/1
parse_requirement/1

ただし、Elixir1.3.1でも、

iex(1)> Version.__struct__
%Inspect.Error{message: "got Protocol.UndefinedError with message \"protocol Enumerable not implemented for nil\" while inspecting %{__struct__: Version, build: nil, major: nil, minor: nil, patch: nil, pre: nil}"}
iex(1)> %Version{}
%Inspect.Error{message: "got Protocol.UndefinedError with message \"protocol Enumerable not implemented for nil\" while inspecting %{__struct__: Version, build: nil, major: nil, minor: nil, patch: nil, pre: nil}"}

と使うことは可能。

[iOS]EarlGreyを使ってシナリオを記述する

過去、 EarlGreyが出たての頃に試してみた のですが、最近またプライベートで使ってみたので自身のために残しておきます。

幾つかサンプルではなくて自分で使ってみて、Appiumとの使い分けやテストレベルの対応などもある程度私の中で腑に落ちた感じがしました。

EarlGreyについて

EarlGreyは、XCUITestみたいに描画要素に対して何らかの操作を行うライブラリです。面白いのは、 UIView をハックしてなにか操作を模倣するのではなく、 UIAccessibility Protocolを操作する。

リポジトリはこちら。

https://github.com/google/EarlGrey

EarlGrey自体の説明はあるのでここでは書きません。

何か困った時

使えるAPIや、使い方がわからないとか、そういう時はテストコード読んだりAPIドキュメント見るとある程度対応できます。

  • APIドキュメント
  • Matcherの実装
    – どのように動作しているか、といった説明も書かれているので、ざっと一読することをお勧めします
    https://github.com/google/EarlGrey/blob/master/EarlGrey/Matcher/GREYMatchers.h
    – AccessibilytLabelやidentifierの他にも、Valueなど多くの要素が使えるのよいですね
    – ただ、 We strongly recommend using an accessibility identifier as it uniquely identifies an element. と書かれているように、やぱり accessibilityIdentifier を使うことが良いことには変わりなさそう。ここは激しく同意。

Other Tips

  • 要素を見つけたい時
    • シミュレータだと、AccessibilityのAccessibility Inspectorを有効にしてそれを使うと良いです
    • Appiumだとinspectorを使ったりPonyDebugger使ってたのですが、このAccessibility Inspectorが実は一番楽なのかも?
  • Search Fieldなどで”Search”をしたい(テキスト入力後の決定)
    • \ngrey_typeText で入力しましょう。そこを契機にkeyboardの”return”や”search”になる箇所の操作と同じ動作をします

シナリオの記述例

以下、Searchフィールドをたっぷ、”KazuCocoa”と入力して決定、検索するというシナリオです。

  • selectElementWithMatcher で要素を見つけ、 performAction で何か操作をし、 assertWithMatcher で要素をチェックする。
  • EspressoのViewMatcher、Perform、Assertの形と同じですね。Googleではこういう形での記述に統一しているような雰囲気を得ます。

具体的には以下。

Appiumとの使い分け

ざっくりと書くと、ツールの使い分けは以下な感じ。Quickなどはありますが、やはりSwiftでシナリオベースのテストコードを書くのは面倒です。なので、本当にその視点から記述したシナリオベースのテストを残しておきたいなら、私はAppium + Rubyをベースにしたものをつかたいと思います。

  • Appiumを使うとき
    • シナリオを記述したテストコードの実行
    • ネットワークキャプチャなどのアプリ全体を操作したい時
  • EarlGreyを使いたい
    • CIに組み込む
    • 限定的な操作を安定して早く実施したい
      • イメージとしては、単一の機能であったり、境界値によってViewが変化するような隅っこのチェック
    • Layoutをチェックしたい(image diffではない)

image diffなんかは単なるassertionの手段なので、必要に応じて使いましょう。

こういうのを、社内で置いているテストレベルと照らし合わせながら導入できると雑多にはならなさそうですね。

XCTest -> EarlGrey -> Appium

という感じで、ロジックのチェックからGUIのチェック、アプリ全体の計測まで進んでいくと順当そう。
ちょうど、テストサイズをベースにするとS/M付近がXCTest、M/L付近がEarlGrey、L/EがAppiumという感じの関係性でしょうか。

締め

あまり情報がないですが、やはり短時間で成果を出すにはこの手のテストコードも素早く安定させた形にすることが必要です。その上で、この手ではできないことを人が実施する。

そのためにはこういうツールやテストの構築方法含め、フルで知見を導入していきたいですね。

Reading “Raft” – consensus algorithm

Raftという、合意アルゴリズムが存在する。これは、多数決を元にした多数派の意見を決定するためのアルゴリズムで、分散環境下における合意形成でも使える。最近、分散系の幾つかのWebサイトを眺めていると見つけた。

私は、こういう系統の技術分野は大学院の頃にByzantine General Problemを扱ってから比較的興味を持っている。

実際のツールだと、CoreOSのetcdやhashicopeのconsulなんかで使われているみたい。

Raft自体に関係するところは以下。

幾つかの言語で実装されているみたい。etcdではgolangぽい。

幾つかRaftの論文のreferencesを見てみましたが、Byzantine faultなんかはやぱり参考にされていました。2014年が論文としては初出?

LESLIE LAMPORT氏によるByzantine General Problemの問題は、懐かしさがある(大学院の頃によく読んでいた)。最近はご無沙汰だけれど、技術だけの話でいうとこれ系が関わる仕事はしてみたいな。

参考

[Elixir][Erlang]difference of binary

double quote and single quote have different meanings between Elixir and Erlang. In addition, “$” and “?” also have.

They make me confuse a bit … 😦

[Elixir]愚直にズンドコキヨシ

こちらの「ズンドコキヨシ」を簡単に実装してみた。Streamとか、そういうのは使ってない。実際に処理するメソッド数は3つ。 Enum.take/2 のようなものは使っていない。

実行

iex> c "zndc.exs"
iex> Znd.kiyoshi
"ズンズンズンズンドコキ・ヨ・シ"

Listの追加方法を先頭から追加する形に少し変更してみた。ついでにdropしてた所を出力してみた。ただ、少しに煩雑になったかな…

[Erlang]Dive into Designing for Scalability with Erlang/OTP

Designing for Scalability with Erlang/OTPを読みました。Erlang/OTPを軸とした、スケーラブルなシステムを構築するための設計に必要な知見がたまってそうだったのと、半額程度で購入できたのでありがたく読みました。

内容として、半分はErlang/OTPのエコシステム周り、設計思想とかの話でした。ただ、残す半分はErlangに限ったことではない、広く使えそうな基礎がまとまっていました。個人的には、Elixir in Actionと合わせて読むとこの系統の書籍は十分そうな感覚です。

ちなみに、所どころ使われている例題や、それを個人的にElixirに書き直したものを以下に置いています。(所どころ壊れているものもありますが。)
https://github.com/KazuCocoa/erlang-scalable-design

前半部分

Erlang/OTPの全体的な話が書かれています。背景とか。message passingの概要とか。諸々。Erlangの文法も学びながら、gen_serverだったり、gen_fsmだったりといくつかのOTPの話に発展する感じでErlangを学ぶことができます。

debugのための、sysやdbgモジュールも記載されていました。以前読んだQiitaのReconTrace で Erlang VM のトレース機能に親しむでかかれていたrecon_traceなんかのことも言及されています。

proc_libという特別なプロセスの話も。この特別なプロセスは、

  • システムメッセージや、イベント、シャットダウンとが可能
  • 動的モジュールのリストを得ることができる
  • debug flagを使ってトレースメッセージを利用することができる

といった特徴があります。

後半部分(Chapter13以降くらい)

Chapter 13のDistributed Architectureは、SOAやP2Pといった大局な設計やinterfaceから、その配布方法などの話まで色々ありました。これはErlangに特出したツールの話以外は、普通にErlang以外でも役立ちそうな情報だと思います。

リリース関係の話の中で、riakというdecentralized datastoreなツールの話もあって、面白かったです。Gossip protocolを使ってClusteringしているとか、そういう話も載っていたので。HashiCorpのSurfなんかでも結構知られていますね。Gossip protocol。

Scalableなシステムを組むためのtipsとして、以下の項目がまとめられていました。

  • 分割する
  • Distributed architectural pattern(cluster, SOAなど )
  • Network protocol
  • node間のinterfaceや状態も持ちようやデータモデル
  • node間のretry strategy
  • node間のsharing data strategyとか

Chapter14は可用性(availability)をより高めるための話。例えばuptime99.999%の物とか。Fault toleranceの話もここで本腰になってきます。このScalabilityのために、availability、reliability、consistencyのトレードオフの話があります。これらには、例えばlatencyの話とかも含まれます。

  • failからの回復に関して
    • Availability
      • exactly once < at least once > at most once
    • Consistency
      • exactly once > at least once > at most once
  • データの共有
    • Availability
      • share everything < Share something > Share nothing
    • Reliability
      • share everything > Share something > Share nothing

テストに関しても言及されていました。Capability Testingとして、これはmustなやつですね。

  • Soak Testing
    • 長時間稼働させておく
  • Spike testing
    • 高負荷の時に正しく復帰できるか、耐えることができるか
  • Stress testing
    • 負荷を上昇させてボトルネックかシステムの上限に達するかどうか
  • Load testing
    • 上限に近い負荷をかけ続けてどうか

ツール群

とか、3rd party SaaSとか。

あとはモニタリングの話とか。

締め

分散システムに対する話として、Erlang/OTPの話はとてもまとまっていますね。Elixirに踏み込むとやはりここは大事な所だし、純粋にシステムの理解としても大事な所。

また、early releaseが終わった段階でChapter13以降は読み直そう。

[Elixir][Erlang]RecordとElixirのStructの違い

最近、Erlangのある書籍を読み始めました。そこでは始めの方にErlangの基本的な事柄が書かれていたので、そこを軽く追いながらErlangを軽く学んでいます。(と言っても、Elixirやってきたので文法以上は特に目新しいものはないのですが)

そこで、ElixirのStructとElixir/ErlangのRecordの違いが気になったので、まとめておきます。

結局は、RecordとMapの違いになってきて、Erlangコミュニティで話されるその違いと同じような感じになっていました。(すごいE本のP. 567とか。やっぱりこの本、すごい。)ただ、ElixirのStruct自体はElixir独自のものなので、ちゃんと残しておきます。

Erlang x Record

Erlangでは、Recordはtupleの糖衣構文。例えば、以下の通り

-module (record).
-compile (export_all).

-record(robot, {name,
                type=industrial,
                hobbies,
                details=[]}).

first_robot() -&gt;
  #robot{name=&quot;Machatron&quot;,
         type=handmade,
         details=[&quot;Moved by a small man insides&quot;]}.

を実行すると以下の結果になります。

1&gt; c(record).
{ok,record}
2&gt; record:first_robot().
{robot,&quot;Machatron&quot;,handmade,undefined,
       [&quot;Moved by a small man insides&quot;]}
3&gt; rr(record).
[robot]
4&gt; record:first_robot().
#robot{name = &quot;Machatron&quot;,type = handmade,
       hobbies = undefined,
       details = [&quot;Moved by a small man insides&quot;]}

なるほど。

Elixir x Record

iex(4)&gt; defmodule MR do
...(4)&gt; require Record
...(4)&gt; Record.defrecord :user, name: &quot;Machatron&quot;, age: 29
...(4)&gt; end
{:module, MR,
 &lt;&lt;70, 79, 82, 49, 0, 0, 6, 184, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 240, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...&gt;&gt;,
 {:user, 2}}
iex(5)&gt; MR.user
user/0    user/1    user/2
iex&gt;(5) MR.user
{:user, &quot;kazu&quot;, 29}

なるほど。でも、こう見るとこれはstructに似ている。と思いますよね。普通にElixirのget startを学んだだけだとRecordがでてこないので、考える順としてはこんな感じだと思われます。

iex(19)&gt; defmodule MS do
...(19)&gt; defstruct [name: &quot;kazu&quot;, age: 29]
...(19)&gt; end
{:module, MS,
 &lt;&lt;70, 79, 82, 49, 0, 0, 5, 16, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 133, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...&gt;&gt;,
 %MS{age: 29, name: &quot;kazu&quot;}}
iex(20)&gt; MS.__struct__
%MS{age: 29, name: &quot;kazu&quot;}

ElixirのRecord

ElixirのRecordのドキュメントを見ると

  1. to work with short, internal data
  2. to interface with Erlang records

と、Recordの使うポイントが書かれています。ふと、ここでよく見るとstructとの使いわけが気になります。

まぁ、そう思うよね、と思ったらGoogle Groupsにやっぱり。

結論だけここに残しておくと、たいていの場合はStructを使って、限られたときだけRecordを使いましょう、というもの。StructはMapで __struct__ 定義されます。

To clarify: when we said that Records in Elixir were deprecated, it was Elixir implementation of records which is long gone by now.

Recordはcompile time、MapはRuntimeなので、errorを出すタイミングが異なる、など理由をいくつか挙げてたりします。Recordを使う時は、loop内であったりエラーを気にしなくて良い時とか、そういう時に高速に使いたい場合、といった限られていると記載しています。

ちなみに、

Structs offer a mixture between records and maps. Records are compile-time based, maps are runtime based. Structs aim to add record-like compile time checks on top of maps. This is actually faster and conceptually simpler than trying to add runtime features to Records.

と書いているように、ElixirのStructはコンパイルタイムのチェックもされます。実際に使ってみると、keyに対して代入される初期値はcompile-timeの物です。

Recordが使われているところ

Recordが実際に使われているライブラリあるのかな、と思ってPlugを参考にしてみました。すると、Recordは1か所だけで使われていた。それはErlangのrecordから値を引っ張ってくるところ。

https://github.com/elixir-lang/plug/blob/1ae124a4f841da5a655f01695e5104286d66c17f/lib/plug/static.ex#L94

ここを実行してみると、確かにerlangの物を持ってきています。

 iex&gt; Record.extract(:file_info, from_lib: &quot;kernel/include/file.hrl&quot;)
[size: :undefined, type: :undefined, access: :undefined, atime: :undefined,
 mtime: :undefined, ctime: :undefined, mode: :undefined, links: :undefined,
 major_device: :undefined, minor_device: :undefined, inode: :undefined,
 uid: :undefined, gid: :undefined]

これで、↑の値が Plug.Static.file_info で取得できるわけですね。

なるほどー。

締め

Erlang書いていると、文法の並び以外は思いの外Elixirだった。(まぁ、ElixirがErlang母体なのでそうなのですが)

以前いただいたメンションであった以下の正しさがわかってしまった。

実際、Erlangの “;” や “.” 、大文字開始の変数とかの使い方付近に不慣れなところが多いのですが、それを除くとElixir書いている時と同じ脳みその使い方している感じです。

ただ、個人的にはpipelineで処理をつなげるような記述の方が考えやすかったので、Elixirの方が文法は好みな感じですね。

あの本はちゃんと読んでいこう。

TensorFlowに関するメモ

タイトルの通り。