エアコミケ開催に伴ってTwitterからフォロー中のサークルの新刊等委託情報を検索/抽出してリスト化するやつ(https://itaota.paltee.net )をリリースしました。
久々に開発をやったのでメモがてらやったことを書きたいと思います。
エアコミケ向けに頒布物の委託情報をまとめるやつ(仮)を公開しました。認証して更新は走るんですが結構長くなる見込みなのである程度時間を空けてから見たほうが確実です。急ごしらえだったので足りてない点もありますが温かい目で見てもらえればと。。。 https://t.co/RExLXWSu8O pic.twitter.com/PTiraXYibT
— ログ取り職人 (@paralleltree) April 29, 2020
発想から設計
4月も3週目の土曜日、陽も落ちてから突如アイデアが出てきました。
なぜ週末折り返しになってやりたいこと出てくるかな
— ログ取り職人 (@paralleltree) April 18, 2020
ビッグサイトでのコミックマーケット開催が中止になってから数週間経ってから考え付いたあたり、逆に何で思いつかなかったんだろうという感じですね。
このときはユーザのツイートから検索することしか考えていなかったのですが、軽く調べると、Web用の埋め込みツイートが動的に生成できることが分かったのでこれを使って作るしかないになりました。
この日はとりあえずリポジトリを作成して続く日にメインのデータ取得処理をどう組み上げるか思案して終了。
データの取得はフォロー中のユーザからツイートを取得してURLを引っかけるだけのシンプルなものですが、レートリミットが厳しめ(900reqs/15min)なので取得履歴が古い順にAPIを叩くように設計することにしました。1度取得したデータは保持しておけばこちらの話になるので、ある種複数ユーザで取得したデータのシェアリングエコノミーな感じになります。
新たなデータの反映には時間がかかりますが、取得後はすぐにレスポンスに載せられるようになりました。
実装
サーバサイド開発
以前にイベントの参加者を抽出するやつ(https://circlesearch.paltee.net )を制作しましたが、かれこれ4年近く前にできたもので当時のRailsバージョンは5.0でした。あれから時代は進み、rails newでできるのは6.0。いろいろと変化があった中で新鮮な気持ちで開発を進めていました。
モデルのクラスを作りながらTwitterでOAuth認証する部分を実装し、更新ジョブを書いたくらい(ここが大変だった)でバックエンドはだいたい完了し、フェッチ用のエンドポイントとフロント開発に移ることにしました。ここまでだいたい3,4日くらい。
実際に動かしてわかったんですが、更新ジョブのスループットがすこぶる悪いです(それはそう)。
もっと高速化できるといいんですが、リソース的にも原理的にも難しそうでした。
どうにかしたいですね~~~。
フロントエンド開発
Rails 5.1でフロント開発がwebpack標準になっていたこともあり、さすがにモダンな開発できないとなあという感じでしたが、いろいろ調べて検討した結果webpackerは引っぺがすことにしました。確かにwebpackの設定書くために新たにDSL覚える必要ある?と言われるとうーんという感じで、つぶしを効かせたかったところも。
そんなわけで今回はwebpack&simpackerの構成で作ってみました。ちゃんとモダンなフロント開発したことがなく、時間的にも若干の危機感を感じていましたが、わからないなりに調べながら実装しました。なんだかんだ3日くらいで見るに堪えうるところまで進めたので良かったです。
フレームワークはVue.jsを使い、Sassを書いてスタイルを当てつつ階層ごとにコンポーネント化して記述しました。CirclesearchでもVueを使っていましたが、当時は全てをべた書きにするというまあひどいものだったので少なからず進歩したと思います。
バンドルされたスクリプトはapplicationのviewで読み、body
に#app
だけ載せて各viewでコンポーネントに相当するタグを含めるようにしてサーバサイドでレンダリングが行われます。
スクリプト内で#app
要素にマウントするようにしたので、フロントの実装自体はRailsと分離して書ける形になりました。
後述のcapistranoによるデプロイでも、Rails側のasset compileの代わりにrakeを介してyarnを叩けば同様にコンパイルが走ったのであまり詰まらずに済みました。
Sidekiq 6
今のsidekiqはproduction環境で動かすならsystemdで管理してねというスタンスなので、デプロイ時にユーザ権限で動かすための設定をしました。
普段sshでログインしてsuしてるのでXDG_RUNTIME_DIR
を設定してsystemdを叩かないとそもそも動かせなかったり、エラーの確認方法を調べるのにちょっと時間がかかったりと危なっかしかったですね。
Capistrano
デプロイ時に割と困ったのがここ。
sidekiqをsystemdでコントロールする設定をしましたが、capistranoで対応できるのが3.9.0以降。
その一方で、ローカルでビルドしたファイルをrsyncで配布する系プラグインが軒並みcapistrano本体に追従してなくて泣きました。
今からsidekiqのバージョンを下げることは困難なので、結局rsyncを諦めて一切合切本番環境でビルドすることにしました。まあお前がcontributorになるんだよ!!!って言われたらそれまでですが。
結局サーバとしては1台に詰め込んで動いているので妥協したところですね。これでマルチなインスタンスにデプロイするのは避けたいなあという気持ちになりました。
所感
モダンなフロント開発したことがなかったのでこれ開催期間に間に合わなかったらいやだなーというところもありましたが、結果的にリリースまで漕ぎつけたので良かったです。
見よう見まねで頑張ってwebpack導入してみましたが、Vueの単一ファイルコンポーネントを書きつつjs/cssで分けて1つのファイルにバンドルしてくれるの良いですね。
委託情報をまとめる点で今回に限らず使えるかな~と思うのでしばらく運用していく所存。
あとは時間を見つけてCI回したり(しました)Circlesearchのフロント回りをモダン化したいですね……。