Slide 1

Slide 1 text

Multiple Databasesを用いて2つのRails プロジェクトを統合する pixiv Inc. imadoki 2023.10.28

Slide 2

Slide 2 text

2 自己紹介 ● ピクシブ株式会社でエンジニアをしています ● お仕事ではRuby/Railsを書いています ● Ruby歴は7年ほど ● 今欲しいキーボードは kinesis advantage 360 ● Github: @imadoki imadoki

Slide 3

Slide 3 text

今日話すこと ● 2つのRailsプロジェクトの統合についての経緯と課題 ● 複数DB機能を用いたRailsプロジェクトの統合で実際に行ったこと ● その他統合の上で工夫した点 3

Slide 4

Slide 4 text

pixivコミック ● 2012年開始のマンガサービス ● https://comic.pixiv.net ● 現在はアプリ版(Android/iOS)、 ブラウザ版の3プラットフォーム ● 商業作品の連載 / 電子書籍ストア / pixivの投稿作品閲覧 ● バックエンド・管理画面はRailsで実装 ○ リリース時はRails3.2 ○ 現在はRails6.1 4

Slide 5

Slide 5 text

pixivノベル ● 2015年開始の小説サービス ● https://novel.pixiv.net ● ブラウザ版オンリー ● 商業の小説・ライトノベルの連載 ● すべてRailsで実装 ● 元々はpixivコミックをクローンして実装 された 5

Slide 6

Slide 6 text

課題感 ● pixivコミック・pixivノベルはそれぞれ別のサービスとして稼働してきた ● 一方で掲載されているマンガ作品は小説・ライトノベルを原作とするものも多い 6

Slide 7

Slide 7 text

pixivコミックとpixivノベルを より連携させたい 7

Slide 8

Slide 8 text

Railsの複数DB機能を用いて連携する 8

Slide 9

Slide 9 text

なぜ複数DB機能を使う? 選択肢としては… ● APIベースで連携する ● 複数DB機能を用いて1つのRailsプロジェクトに統合する 9

Slide 10

Slide 10 text

なぜ複数DB機能を使う? ● pixivノベルは元々pixivコミックをクローンして出来たものであり、 似たような機能が多い ● pixivノベルは専門のチームがおらず、pixivコミックチームが見ているが どうしてもメンテナンスやリファクタリングが行き届いていない部分がある ● 2つのRailsプロジェクトとして保守していくのではなく、 1つのRailsプロジェクトに統合していったほうがメンテナンスし易いと判断 10

Slide 11

Slide 11 text

進め方 全体の流れとして 1. 一般ユーザー向けの機能をpixivコミックへ統合 2. 社内向け・社外向けの管理画面を統合 ビックバンリリースにならないように段階を経て統合作業を進める 11

Slide 12

Slide 12 text

進め方 ● pixivノベルのDBスキーマをpixivコミックへ移す ● app/models/novel/* にpixivノベル用のActiveRecordのモデル定義を移植 ● pixivノベルの機能に対して優先度をつけてAPIごとに機能をpixivコミック側に 再実装 12

Slide 13

Slide 13 text

pixivノベルのDBスキーマをコミックへ ● pixivノベルを稼働したまま機能を移していくため、pixivノベルのDBスキーマは pixivノベルのものを正として管理することに ● pixivノベルのスキーマデータをコピー ○ pixivコミックのconfig/database.ymlにpixivノベルのDBに接続設定を追加 ○ pixivノベルのdb/schema.rbをdb/novel_schema.rbにコピー ○ pixivノベルのマイグレーションファイルを1つにまとめ db/novel_migrate/*に配置 13

Slide 14

Slide 14 text

pixivノベルのDBスキーマをコミックへ ● 本番環境などでマイグレーションを実行する際に db:migrate ではなく、 db:migrate:primary を使う ● pixivコミックではcapistranoを使ってマイグレーションを実行しているため、 migration_commandにdb:migrate:primaryを設定してあげれば良い 14 # config/deploy.rb set :migration_command, 'db:migrate:primary'

Slide 15

Slide 15 text

pixivノベルのモデルを移植 app/models/novel/* にpixivノベル用の ARモデル定義を移植 15

Slide 16

Slide 16 text

pixivノベルのモデルを移植 pixivノベル用のモデルはNovelモジュール以下にまとめる形にする ● 同じ名前のモデルがpixivコミック上に存在するため見分けるため ● 今後を想定してtable_name_prefixを指定できるようにしておく 16 module Novel def self.table_name_prefix '' end end

Slide 17

Slide 17 text

pixivノベルのモデルを移植 ● Novel::ApplicationRecordを作成 ● connects_toを使用してpixivノベル用のDBへ接続設定を追加 17 class Novel::ApplicationRecord < ActiveRecord::Base self.abstract_class = true connects_to database: {writing: :novel, reading: :novel_replica} # … end

Slide 18

Slide 18 text

18 class Novel::ApplicationRecord < ActiveRecord::Base # … module ClassMethods def with_writable(&block) ActiveRecord::Base.connected_to(role: :writing, &block) end # novelのプライマリDBに接続しトランザクションを開始する def transaction_with(&block) ActiveRecord::Base.connected_to(role: :writing) do ActiveRecord::Base.transaction(&block) end end end extend ClassMethods end

Slide 19

Slide 19 text

pixivノベルのモデルを移植 19 # 書き込み用のDBに接続する場合 Novel::ApplicationRecord.with_writable do # このブロック内では書き込み用のDBに接続される end # トランザクションを貼る場合 Novel::ApplicationRecord.transaction_with do # … end

Slide 20

Slide 20 text

pixivコミックに実装を移植 ● 基本的には愚直に実装を移していくしかない ○ 可能な限り円滑に実装をすすめるため、設計上の方針だけ設定 20

Slide 21

Slide 21 text

pixivコミックに実装を移植 同じ機能はできるだけpixivコミックのAPIレスポンスに形式を合わせる 21 ● pixivコミックとpixivノベルで同じような機能を扱っている部分が多い ● pixivコミックではUIコンポーネントとAPIレスポンスの型が対応していて、 レスポンスの型が合っていればクライアント側の改修が容易になる

Slide 22

Slide 22 text

pixivコミックに実装を移植 pixivコミックでもpixivノベルでもバナー機能に差はないので同じレスポンスの型 ● トップバナーはpixivコミックでもpixivノベルでも画像+リンクで表現できる 22 { "image_url": "https://www.example.com/banner.png", "width": 600, "height": 300, "in_app": true, "url": "https://comic.pixiv.net/link_url" }

Slide 23

Slide 23 text

pixivコミックに実装を移植 合わない場合は仕方がないので専用のレスポンス型を作る ● pixivコミックでは一覧したいときは表紙のみを表示していた ● pixivノベルは表紙に加えてあらすじを表示したい 23

Slide 24

Slide 24 text

まとめ ● 複数DB機能を用いて、2つのRailsプロジェクトの統合を進めている ● DBのマイグレーションを管理する方法を決めておく必要がある ● モジュールによってネームスペースを切ってモデルを管理するとわかりやすい ● 機能の移植自体は愚直にやることになるが今回はAPIの設計を工夫した 24

Slide 25

Slide 25 text

ご清聴ありがとうございました 25