Subscribed unsubscribe Subscribe Subscribe

Islands in the byte stream

Technical notes by a software engineer

Ormaに関する雑談&質問用にgitterのchat roomをつくりました

en: https://gitter.im/Android-Orma/Lobby ja: https://gitter.im/Android-Orma/Ja

背景

GitLab、Slackライクなサービス「Gitter」を買収。有償プラン廃止で何人でも無料で利用可能に。オープンソース化も約束 - Publickey でひさびさにgitterを知って、悪くないんじゃないかと思って設置してみました。

OSSコミュニティの母体としてSlackをつかうことが増えてるようですが、gitterだとpublic channelであれば招待されなくても入れるし、コミュニティとしてはそのほうがいいですよね。

正直チャットサービスとしてのクオリティはSlackのほうが高いです。gitterはリアクションとかできないし、モバイルアプリもGitHubのパスワードをアプリ内ブラウザで入力しないといけないので使えないし。しかしライブラリやフレームワークごとにslackチャンネルに入るのも大変面倒なので、それよりはgitterのほうがよさそうだなと思っています。

カンファレンススタッフ用アプリがあるとよさそう

DroidKaigi 2017お疲れさまでした。スタッフとしては3回目、スピーカーとしては初めての参加でした。

スタッフとしては、受付の誘導、司会、副司会、会場の片付けなどをしました。特に司会はわりと臨機応変に行動しなければならず、部屋ごとにけっこうバラバラだったのではないかなあと思います。

カンファレンスが始まってからも次々と様々な仕様変更がきて、「意識を高くもって気をつける」だけだとカバーしきれないところがあります。そういう点をカバーできるようにカンファレンススタッフ用アプリがあるといいなーと思って記憶が鮮明なうちにメモしておきます。もちろん関係者でのKTPは別途しますが、それは公開されないと思うので。

実際に起きたこと

  • スタッフのシフト表の変更
    • 頻繁におきてた印象、というのもいくつか不整合がみつかるので
    • シフト表にいれるスタッフは40人くらいいるので、不整合なく保つのは至難の業
  • セッションのTimetableの変更
    • やむを得ない事情によりキャンセルになった枠に当日の判断でFireside Chatをいれることになった
    • 決定があった時点でアナウンスしたけど館内放送があるわけではないので全員に周知できたかどうかは不明
  • 司会用チートシートがどんどん増える問題
    • 部屋 x 時間帯(ランチ前・一日目終了後・二日目終了後)などで微妙に言うことが違うのもなかなか大変
  • 適切な人に適切なタイミングで情報をpush通知する必要性
    • インカム(トランシーバ)を多用していたけど、インカムから情報を聞き取るのはかなり集中しないといけない
    • インカム議事録係がいたけど大変そうだった
  • 司会から発表者への残り時間の通知を適切にするためのツールが乏しく意識だけでやってる、ゆえにときどきミスる

こういうアプリがほしい

  • 1秒で起動して「いま自分が何をすべきか」を知りたい(チートシート)
  • チートシートに差分があればわかりやすく表示してほしい
  • 司会の場合、発表開始5分前、開始時、発表終了10分前、5分前、終了時に通知がほしい
  • スタッフ(あるいはスタッフグループごと)へ情報をpushできるようにする
    • 重要な知らせは強いpush通知(5分くらいバイブレーションが続くとか)があってもいいかもしれない

DroidKaigi 2017で「ORMの選び方」という発表をしました

Ormaの開発の際に他のORMはどういう設計思想なのかを調べたときの知見をもとに、DroidKaigi 2017用に仕上げた発表です。

これ契機にORMについて一家言ある人が増えるといいなと思いながら発表しました。

SQLiteDatabase (SQLiteOpenHelper) を直接つかうかどうかでいうと圧倒的にORMをつかったほうが早く品質のよいアプリを開発できると思っていて、それはやはりORMのマッピング、クエリビルダ、アソシエーション、pub-sub、マイグレーションといった機能が便利だからなんですよね。ただ便利といういだけのみならず、型安全だったり自動化してくれたりと信頼性を高める工夫を書くORMがしているわけで、それを使わないのはもったいないです。

その上で、まあ私としてはOrmaが私の感じる問題を解決してくれる唯一のORMなのでOrmaを使いますが、機能や将来性などを考えるとフルコミッターを大勢抱えるRealmはよさそうだなとは思います。Ormaはすばらしいライブラリですが、開発者がSPOFという点は否めませんからね。ただなぜ私がRealmを好かないのか、Realmがある世界に敢えてもうさらにORMを追加したのかというのも資料で触れてます。

というのはすべて差し置いて、ORMの開発はめちゃくちゃ楽しかったのでよかったらあなただけのオリジナルORMを作ってみてください。

Bit Journeyに転職してKibelaをリリースしました

半年くらいまえにBit Journeyに転職してKibelaを作ってました。AndroidエンジニアからRails + Reactエンジニアへの転向ということになります。

Kibelaはこちら。ようやく本日リリースできました。といっても開発面でいうとこれからが正念場ではあります。

Kibela - 個人の発信を組織の力にする情報共有ツール

“個人の発信を組織の力にする情報共有ツール” と銘打っているとおり、これは 個人が組織内で自由に情報を発信すると組織が活性化する という仮説に基づいて設計されている、会社などの組織向けのサービスです。もちろんそれだけでなく、仕様書の整理につかったり議事録をとりあえず突っ込んでおくみたいなのもありです。

さてKibelaでできることはBlogとWikiを書くことです。これはつまり 個人が発信する情報 とそれ以外を分けるということです。このあたりの思想やベストプラクティスは追々公式ブログで語っていきたいです。

今回の転職は、このKibelaというサービス自体に興味があったというのが主な理由でした。Kibelaはクックパッドの社内向け内製ツールGroupadにヒントを得て設計されています。実際のところ、 個人が組織内で自由に情報を発信すると組織が活性化する という仮説は、私やBit Journey創業メンバーがいたクックパッド社での経験がもとになっています。Groupadが見せてくれた組織における情報共有のありかたには在職中ずっと興味をもっていて、クックパッド社の活力の源のひとつだと考えていたのです。そういう思いがあったので、Bit Journey代表の井原からの「一緒にKibelaを作らないか」という誘いに乗ることにしたのでした。

Kibelaは技術的にみると普通のRailsアプリケーションといえますたサービスの性質上そこまでスケーラビリティやパフォーマンスへのプレッシャーはありません。しかし半年経験してみると、技術的に深掘りできるポイントもたくさんあり、いまのところ楽しんで開発してます。

というわけで、Kibelaをどうぞよろしく!

Herokuのreview appsでRailsのLetter Opener WebをつかうHack

github.com

これのREADMEにもありますが、Letter Opener (-Webも含む)をHerokuで使うにはちょっと注意が必要です。つまり、

  • Letter Openerはデータを #{Rails.root}/tmp/letter_opener に保存する
  • Herokuはdyno (node) 間でデータのやりとりは出来ない設計
  • ActionMailerの deliver_later! はActiveJobで実行するので、web dynoではなくworker dyno のファイルシステムにLetter Openerのデータを保存する

という状況なので、 #deliver_now! で送信したものはLetter Openerで見えますが、 #deliver_later! で送信したものは見えない、ということになります。

じゃあHeroku review appのときだけ #deliver_later!#deliver_now! に置き換えればいいんですねということでApplicationMailerにこんな感じのhackを入れました。

ActionMailerの内部実装に強く依存しているのでRailsのアップデートなどで動かなくなる可能性はありますが、 Rails 4.2.x, 5.1.x あたりはこれで大丈夫そうです。

# rubocop:disable Style/MethodMissing

class ApplicationMailer < ActionMailer::Base
  # Heroku web apps do not access worker's filesystem
  # https://github.com/fgrehm/letter_opener_web#usage-on-heroku

  # override
  def self.method_missing(method_name, *args)
    if action_methods.include?(method_name.to_s)
      MyMessageDelivery.new(self, method_name, *args)
    else
      super
    end
  end

  class MyMessageDelivery < ActionMailer::MessageDelivery
    # override
    def deliver_later!
      if Rails.env.heroku_review_app?
        deliver_now!
      else
        super
      end
    end

    # override
    def deliver_later
      if Rails.env.heroku_review_app?
        deliver_now
      else
        super
      end
    end
  end
end

Orma v4.2.0 の Relation#upsert() の設計

https://github.com/gfx/Android-Orma

Orma v4.2.0 で Relation#upsert() を実装しました。これは、モデルのインスタンスを渡すとその状態に応じて INSERT または UPDATE を実行するというメソッドです。

モデル同士の関連もよしなにしてくれるので、とりあえず #upsert() で突っ込むといい感じに保存されるという便利メソッドです。

ただひとつ注意点があって、primary key の自動採番モード(デフォルトの挙動)のときに #upsert() 後にそのモデルを参照する場合は、#upsert() の戻り値を使わなければいけません。というのも、Ormaは どんなモデルでもimmutableであるという仮定 を置いており、自動採番したprimary keyをモデルのフィールドに代入したりはしないからです。

つまり、次のようなモデルクラスがあったときに:

@Table
public class Todo {

    @PrimaryKey
    public long id;

    @Column(indexed = true)
    public String title;

#upsert() により次のような状態になります。

Todo todo = new Todo();
todo.title = "foo";

Todo newTodo = todoRelation.upsert(todo);

assert todo.id == 0; // todo.idは変化なし

assert newTodo.id > 0; // newTodoのほうは割り当てられたidを持っている

newTodo.title = "bar";

todoRelation.upsert(newTodo); // 変化する要素がないので戻り値は不要

associationについても同様です。

少し煩雑ですが、実は Inserter#execute() も渡されたモデルを変更しないという意味では同じで、モデルをimmutableと見なす設計です。

というわけで、ちょっとクセはありますが便利だと思いますので使ってみてください。

新技術を学ぶ技術と三つの壁とDroidKaigi 2017

こないだの@onkさんのスライドがとても良かったんですよ。

短時間といいつつ守破離の「離」までいくのに3年かかるといってて、高速道路なんてものはないんだなということがわかりますね。

とはいえ自分自身に照らし合わせてみてもそのとおりだなと思いました。ぼくもAndroidで対外的にアウトプットできるようになるまで3年くらいかかってますし。まあ、ぼくは新技術を学ぶのはわりと苦手なほうではあるんですが。

で、スライドにはないけど新しい技術を学ぶ際には大きな壁がいくつかあるなとあると思ってます。それを 意識して 乗り越えるための指標としてもこのスライドはよさそうだなと。

ついでなのでちょっと ぼくの感じる 三大壁をまとめてみました。まあ、壁を壁と感じない人もいると思いますけどね!

Lv.1 着手の壁

症状:

  • 何の役に立つのかわからないので興味がわかない
    • たとえば同僚から「最近◯◯勉強してみてる」といわれてフ~ンと受け流している状態
  • 知らない概念・用語が多くて難しく着手できない

解決方法:

  • 詳しい人の話を聞く
  • 入門系記事をいくつか読んでとにかく用語や概念を頭になじませる

ぼくの例:

  • Androidの例だとSQLite, ContenProvider, RxJava, Fragmentあたりはこの壁を強く感じて着手するまでが大変だった
  • Elasticsearchは新概念が多くて最初は非常につらい

Lv.2 知った気になる壁

症状:

  • 関連情報を一通り読んでなんとなく知った気になり、何も作ってない状態で満足してしまう状態
  • 実際にはこのレベルのスキルはほとんど使い物にならないし、このレベルの技術を調子にのって批評してると的外れなことも多い(自戒をこめて)

解決方法:

  • 何か作る
  • OSSのコードを読んでコミットする(not just “fix a typo")

ぼくの例:

  • Androidだとマテリアルデザインの実装の詳細とかアニメーションまわりはこの壁を超えてない感覚がある
  • ほかは、たとえばちょっと学んだだけのプログラミング言語: C#, Go, Rust, Swift(3)あたりは明らかにこの壁を超えてない

Lv.3 雰囲気でやっているの壁

症状:

  • ある程度使えるようになって仕事でも使えているけど詳細は理解していない状態
  • 自分が書いたコードを説明できない
    • 理解せずにコードを書いている “オマジナイ” が多いときはこの壁の手前にいるということ

解決方法:

  • 疑問に思ったことやなんとなく理解しているだけのことをそのままにせず調べる
  • あとはひたすら読み書きして功夫(クンフー)を積むしかなさそう

ぼくの例:

  • AndroidだとRxJavaは「使えるようになった気がする」からの何かにハマって「全然理解してなかった…」というパターンが頻発するのでまだこの壁を超えられていないのかも
  • React, Elasticsearchなども一通り使えるようになったものの、まだ雰囲気でやっている感じ

この三つの壁を乗り越えると、やっと「使いこなしている」という感覚になります。

で、DroidKaigi 2017ですが、@onkさんのスライドにもあるとおり、コミュニティ主導のカンファレンスで知り合いを作るのは効率よく学ぶ環境作りためのいい機会です。

それと同時に、新しい技術に触れて第一の壁を突破する勢いを得たり、第二・第三の壁を突破してる人の話を聞いたり質問したりして自分のショートカットに役立てたりと、いろいろといい刺激を得られるのではないかと思います。2017年2月2日現在、まだチケットは70席ほど余っているので、刺激を得るために参加してみるのもいいんじゃないでしょうか。

なおぼくは二日目の朝10:40からAndroidのORMまわりの話をします!ぜひ聞きに来てください。