2018年後半に学びたいこと
2018年も半分以上過ぎてしまったが、今年の残り期間で勉強したいことをメモっておくメモです。
Docker
業務ではほとんど使ってないので個人的に勉強しておきたい。
空き時間でchefとvagrantで構築しているローカル開発環境をDocker化する。
とりあえず今はオライリーのDocker本読んでる。
Kubernates
全然わからんけどとりあえず本読んでおく。
AWS, GCP
こちらも業務で使う機会がほとんどないので個人的に勉強しておかないとやばい。
lambda、dynamoあたりを使ってサーバーレス + SPAなWebアプリを作ってみる。
Go
CLIツールを作るのに使ったことがある程度なのでWebアプリのバックエンドをGoで作ってみる。
あとはgoroutine使ったなにか。
Vue
Reactしかまともに触ったことないのでちょっとやっておきたい。
NuxtがNextより良く出来てそうでSSRなPWAとか簡単に作れそう。
ブロックチェーン
dAppsをちょっと齧った程度だけど面白そう。
でもどっから勉強していいのかがわからない。Etheriumの論文とか読んだらいいのかな。
英語
これは今年のはじめからずっとリスニングやってるので引き続き。
まとめ
基本的に業務でやってないけどやっとかないと将来的に転職先なくなりそうみたいな技術はMustでやっておきたい。 あとは関数型言語とかWebAssemblyとかやってみたいことは他にも山ほどあるけど全部は無理なので出来そうなところからコツコツやっていきます。
最近やってる英語勉強法
リーディングは基本的に技術系のドキュメントが全部英語で読まざるを得ないので普段から結構英文を読む機会が多く特別勉強はしてなくて、単語はDUO3.0を買ったけどあんまりやってない。
英語のカンファレンス動画とかeSportsの実況とか英語を聞き取れるだけで楽しめるコンテンツが増えるのでとにかくリスニング出来るようになりたい。
リスニング
教材は無料のPodcast。 英語のPodcastは世の中に無限にあり、リスニング力がそこそこあるならその中から自分が興味のあるものを聞いているだけで勝手に伸びていきそうだが、 いかんせんまだリスニング力が低いためTranscriptが用意されているPodcastを利用している。
Spotlight English
以前使っていたサイト。
速度が結構遅いので初心者向け。
エピソードの内容は多岐にわたっていて、自分はテクノロジー系の中から興味のあるエピソードを選んで聞いていた。
更新頻度が高い。
Better at English
最近一番聞いているのがこれ。
会話スピードはかなり速いので、前述のSpotlight Englishである程度慣れてから聞き始めたほうが良い。
会話内容は「専門家への "如何にモチベーションを保つか" についてのインタビュー」や「クリエイティブな人々の習慣についての書籍 "Daily Rituals" について」など英語学習をする上でも役立つものでなかなか面白い。
1エピソード10分くらいなので繰り返し聞くのにも丁度良い。
Transcript には会話中に使われた単語について英語の説明がついており、単語を日本語としてではなく英語として覚えることが出来て便利。
バイリンガルニュース
有名なので知っている人も多いと思う。
バイリンガルな二人が一方は英語、一方は日本語という「バイリンガル会話形式」のPodcast。
最新のニュースから二人がピックアップしたテーマについて議論しているのだが、二人のアンテナが非常に高く普段全然キャッチアップできていないようなニュースを知ることができるのでそういう意味でも勉強になる。
ただ1エピソード1時間超えで繰り返し聞くのには向いていない。
自分はリスニング力がどれくらい向上したか確かめるためにたまに聞く、みたいな使い方をしている。
Transcriptは有料。
シャドーイングについて
自宅から最寄り駅まで15分~20分くらい毎日歩いているのでその間ずっとPodcastを聞きながらブツブツ言っている。
また、通勤電車内でTranscriptを読みながら非常に小さい声でブツブツ言っている。電車内ではみんなイヤホンつけているので意外と変な顔をされたりはしない。
おすすめ。
どうやって習慣化するか
英語学習で最も大事なのは続けることだと思う。
続けるためにやっているのが勉強したら記録を付けるということ。人間不思議なもので記録を付けるだけで何故かモチベーションが上がる。
記録を付けるのには Studyplus というスマホアプリを使っている。
これが非常に良くできている。
教材を自分で登録して教材別に記録することが出来て、記録した時間・量を勝手にグラフにしてくれるのであとで眺めるだけで楽しい。
毎週1週間の目標を立てるように促されるのだけど、いつも2時間くらいの短時間で設定して成功体験を積んでいる。
このアプリはSNS要素があるのだが、ターゲットが受験勉強中の中高生なのでいきなり中高生から友達申請が来て変な気持ちになるのがちょっと問題。
その他
Youtubeでテックカンファレンスの英語動画を英語字幕で見るとか。 これも結構良いけどやはり1動画が長いので繰り返しできないのが勉強向けではなさそう。
CQRS + ESについてのまとめ
CQRS+ESというアーキテクチャがどういったものか気になったので調べたことをまとめてみた。
CQRSとは
コマンドクエリ責務分離(Command Query Responsibility Segregation)の略で、 データの読み込み(クエリ)と書き込み(コマンド)の責務を分離するアーキテクチャのこと。
コマンドモデル
- ユーザーインターフェースなどのクライアントから実行される振る舞いを持つ
- データの書き込みに責務を持つ
- 操作の成否以外の情報を呼び出し側に返さない
クエリモデル
- 非正規化したデータモデル
- データの表示のみに責務を持つ
- データモデルがSQLだった場合はクライアントの表示内容毎にテーブルを用意する
- 操作は冪等であることが保証される
クエリモデルの更新
コマンドモデルの実行時の最後にはイベントが発行される。
特別なサブスクライバが全てのイベントを受信していて、受け取ったイベントに沿ってクエリモデルを更新し、変更を反映する。
更新を同期的にするか非同期処理にするかはシステムの負荷がどれくらいかかるかによって選択されるべきである。
同期的な場合は一貫性が保たれるが、システム負荷は高くなる。
非同期処理の場合は負荷は抑えられるが、表示されるまでに時間がかかってしまう。
イベントソーシング(ES)とは
状態(State)を永続化するのではなく、Eventを永続化(ソーシング)すること。
ソフトウェアに何が起きたのか(Event)を記録しておくことで現在の状態を割り出す。
ステートソーシング
ステートソーシングとは通常のCRUDなアプリケーションでやっているようなもので、
最新の状態だけを永続化すること。
何故、どういう意図を持って状態が変更されたのかというような、状態が変更された経緯が見落とされる という問題がある。
イベントソーシングなら
- ソフトウェアの履歴が完全に保存される
- ある時点での状態を再現できる
状態遷移は,私たちの問題空間における重要部分であり,私たちのドメインでモデル化されるべきものです。
イベントソーシングの問題点
- 特定の名前のユーザをすべて検出するというようなクエリが,SQLデータベースで常にテーブルのフルスキャンを行わなければならないような非常に厄介なものになる可能性がある点
- 書き込みと読み込みを分離して、クエリを最適化することが可能な CQRS の出番
イベントソーシングで解決できる問題
- 商品の更新履歴
イベントを記録しておくことで在庫数を算出する
- 商品が在庫数10で出品された ⇢ 在庫10
- 商品が1個購入された ⇢ 在庫9
- 商品が1個購入された ⇢ 在庫8
- 出品者が商品の個数を10に変更した ⇢ 在庫10
例えば4のイベントを取り消したければ3のイベントまで再生することで状態を再現出来る。
イベントストア
イベントを永続化する為のデータストア。
CQRS考案者による実装
ActiveRecord ベースの実装
https://github.com/arkency/rails_event_store
CQRSとESの組み合わせ
クエリモデルとコマンドモデルをそれぞれ永続化すると、コマンド発行後にクエリモデルが同期されていることを担保することが難しい。
そこでイベントソーシングを組み合わせることで、コマンドモデルでイベントの永続化を行い、永続化されたイベントによって用途に合わせ何度でもいくらでも最適化されたクエリモデルを作ることが可能になる。
参考文献
http://postd.cc/using-cqrs-with-event-sourcing/
https://www.slideshare.net/shuheifujita90/ss-14294169
https://www.infoq.com/jp/news/2014/10/greg-young-event-sourcing
http://d.hatena.ne.jp/digitalsoul/20100712/1278886009
実践ドメイン駆動設計
ElectronでSubsonicクライアント作った話
以前このブログでも書いたSubsonicという音楽ストリーミングサーバー用のクライアントソフト Sonictron を作った。 オリジナルのWeb版が音量調整とかいまいちやりづらくデスクトップアプリ欲しいとなったので、せっかくだからElectronで作ってみようと思い立った。
アプリの特徴
Web版とそれほど違いはないが、
- グローバルショートカットで再生/停止、音量調整操作
- web版では何故か無かった1曲リピート機能
Web版での最大の不満点だった音量調整部分が改善できたのでだいぶ満足してる。
SubsonicはかなりAPIが充実して色々出来そうなのでまだまだ機能の追加は出来そう。
今後はクロスフェード再生やNotificationなどを入れていく予定。
ソースコード&成果物
GitHub - hiyamamo/sonictron: subsonic client with electron
releaseページに各プラットフォーム毎のzipが置いてあるので、Subsonic自体使っている人があまりいなさそうだけど、もしよければ使ってみてください。
ちなみにSubsonicにはDemoサーバーが用意されており、サーバーを立ててない人でも使ってみることが出来る。SonictronではDemoサーバーに接続する設定も用意してあるので是非。
技術的選択
transpilerはbabelでタスクランナーはgulp。この辺りはかなり情報多くて助かった。 gulpfileはこちらの記事を参考にさせてもらいました。 基本はES2015の構文で書いてbabelでコンパイルした。
ViewはReact。
見た目的に3つのPane+Headerのプレイヤー部分とわけていたのでそれぞれRoot Componentでstate管理して、子Componentにprops流すという設計。stateはほぼStoreから受け取っているのでReact側でstateはほとんど変更しなかった。
Fluxフレームワークは最初はfacebook/flux使っていたが色々と複雑になるにつれてカオスになってきたので、azu/material-fluxを採用した。 正直どれが良いかよくわかんなかったので、参考にしたアプリで採用されていたものをそのまま採用した。
context, action, storeそれぞれでクラスを継承して使う形でシンプルでわかりやすかった。fluxのcontextをviewにpropsとして渡すのがめんどくさかったので<Provider>
というComponentを作り、Reactのcontextからstoreやactionのインスタンスを取得出来るようにした。
最近のデファクトはReduxになりつつあるようなので次はこっちも使ってみたい。
CSSフレームワークとしてphotonkitを採用した。photonkitはMacアプリ風の見た目に簡単に出来るもので、React用としてreact-photonkitといモジュールがあったのでそれを使った。
多少バグがあったのでreact-photonkitのほうにプルリク送ったが、開発止まってるみたいで未だマージされず。
フレームワークだけだと色々厳しいので自分でもかなりCSS書いたが案の定カオスになってしまったのでうまく設計出来るようになりたい。
大枠としては以上で、後は曲の再生にWeb Audio API使ってて、設定の保存とかはlocalStorageをつかってる。
Electronの話
ElectronはMain ProcessとRenderer Processで分かれており、プロセス間通信の手段としてIPCモジュールが用意されている。
今回音源の再生にWeb Audio APIを使っているので、再生状況等の状態は全部Rendererプロセス側で管理して、状態が変更される度にIPCでMainプロセスにメッセージを送って、Mainプロセス側で更に受け取った状態を管理するという形になっていて、結構厳しかった。
今回のアプリは大した規模ではなかったのでなんとかなったが規模が大きくなった場合すぐ破綻しそうなので、何かしら状態を共有出来るようないい感じの設計が必要だと感じた。
あとテストあんまり書いてないのでちゃんと書いていきたい。
さいごに
作ってるうちにElectronやReactについての知見が色々溜まった気がしたが、今となっては大部分を忘れたので思い出したらまた書く。(知見だと思ったらすぐ書くことが大事という学びがあった)
とりあえず最低限の機能が出来たので公開したが今後もどんどん機能追加等していきたい。
IssueやPull Requestお待ちしております。
Subsonicとかいうメディアストリーミングサーバー構築できてどこからでも音楽聞けちゃうやつ
久しぶりに自宅のサーバーいじりました。
音楽聞く環境としては自宅、職場、移動中などそれぞれ使うデバイスが違ってそれぞれにデータ入れなきゃいけなくてめんどう…。
出来ればデータは同じマシン上で管理したいってことで以前からやろうと思っていたストリーミングサーバーを構築してみました。
Subsonic
何年も前からあるみたいですが最新版は今年の3月に出したりしていい感じです。
導入
CentOS 6
- JAVA
sudo yum install java-1.7.0-openjdk
- ダウンロード
wget http://sourceforge.net/projects/subsonic/files/subsonic/5.2.1/subsonic-5.2.1.rpm
- インストール
sudo rpm -ivh subsonic-5.2.1.rpm
- ライブラリ
sudo yum install lame flac faad2 vorbis-tools ffmpeg
するだけで起動まで勝手にやってくれます。
日本語の曲名とかだと文字化けするっぽいので
/etc/sysconfig/subsonic
にexport LANG="ja_JP.UTF-8"
と追記- あとデフォだとrootユーザーで起動してるようなので
SUBSONIC_USER=yourusername
に変更 - 再起動
sudo service subsonic restart
デフォルトポートは4040です。接続してログインするとブラウザ上で色々設定出来ます。日本語もサポートしてます。
ちょっとだけ躓いた
最初は↑と同じ最新版の5.2.1を入れてみたんだけど音楽フォルダをスキャンしても全く表示されませんでした。
とりあえず4.9を入れてみたら直りました。若干UIが違うくらいで特に問題なさそう。
古いVersionはこちら↓
Subsonic - Browse /subsonic at SourceForge.net
こんな感じです
どこからでもブラウザで自宅サーバー上の音楽聞けるので最高でした。スマホアプリも色々あるっぽい。
注) 30日間の試用期間すぎるとアプリから聞いたり出来なくなったり色々制限はあるようです。多分ブラウザからは大丈夫。
Premiumは$1/monthとのことです。
参考
さくらのVPSとSubsonicでiTunesをゴミ箱にダンクシュートした - 甘味志向@はてな
Subsonicでストリーミングメディアサーバーを構築。どこでも自分の音楽にアクセス:Garbage In Garbage Out
IT系勉強会を検索出来るAndroidアプリを作りました
エンジニアの皆さん、勉強会には行ってますか?
勉強会の情報を一括で検索出来るサービスは色々あると思いますが、Androidから手軽に探せるのがあるといいなぁ、と思いつくりました。
やってることはConnpassとかのイベントサイトのAPIを利用してアプリで表示してるだけのシンプルな作りですが、いざ完成させるとなると結構大変でした。 アプリ作りはある程度形にするまでは出来てもちゃんと完成させるのはほんとに大変ですね…。
ホントはDoorKeeperの情報も入れたかったんですけどAPIの仕様的に難しかったので今回は見送り。
とりあえずの機能としては
カレンダーから日付を選択して一覧表示
キーワードでAND、OR検索
となります。
対応サイトは現在Connpass,Zusaar,ATNDです。 アプリから手軽に複数サイト検索できるのでまあまあ便利だと思いますのでぜひ使ってみて下さい。
フィードバックお待ちしております。
Bundleに独自クラスを保存したい
fragmentを使って画面遷移する時にデータを渡したい場合なんかによく使うBundleですが、データを格納しておく独自クラスをそのまま入れたい時があります。
そういう時は通常のクラスでしたらParcelableを実装すれば bundle.putParcelable(key, val);
でそのまま格納できます。
Parcelableの実装方法はこちらが非常に参考になります。
Y.A.M の 雑記帳: Android Parcelable を使ってクラスのメンバを一時保存
問題はParcelableを実装したいクラスが抽象クラスだった場合です。Parcelable実装にはParcelable.Createorというスタティックフィールドが必要になりますが、そのフィールドを初期化する際にParcelに保存したデータを復元するためのコンストラクタを呼びます。しかしながら抽象クラスだと当然コンストラクタを呼ぶことができません。以下一部コード例
// Content.java(ContentはParcelableをimplementsしたabstractクラス) public static final Creator<Content> CREATOR = new Creator<Content>(){ @Override public Content createFromParcel(Parcel parcel) { return new Content(parcel); // ここでエラーになります } @Override public Content[] newArray(int i) { return new Content[0]; } }; private Content(Parcel in) {} // 実際はこのコンストラクタ内でParcelからデータを読み出します
前置きが長くなりましたがではどうすればよいかというと、独自クラスにSerializableを実装するだけです。
Serializableはメソッドなどをオーバーライドする必要はなくimplementsするだけで大丈夫ですが、クラスの構造がSerialize出来るようになっていないといけません。
Serializableについてはこちらが参考になりますので読んでみてください。
Android SDKの,ParcelableとSerializableの違いを比較 - Intentで独自オブジェクトを運搬する際,役立つのはどちら? - 主に言語とシステム開発に関して
難解なSerializableという仕様について俺が知っていること、というか俺の理解 - 都元ダイスケ IT-PRESS
Serializableなクラスとして実装しておけばbundle.putSerializable(key, val);
の形でBundleに格納できます。