-
肥大化するusersテーブルを飼いならす方法
クライアントのアプリはどうやってこの状態に陥ったのか?詳細に入る前に、アプリがどのようにこの状態に至るのかを理解してみましょう。まずはシンプルなusersテーブルから始めます。数週間後、「最終ログイン時刻」を判定できるようにする必要が生じ、users.last_sign_in_atを追加します。次にユーザーの氏名が必要になり、first_nameとlast_nameを追加します。Twitterハンドル?もう1カラム追加。GitHubプロフィール?電話番号?こうして数ヶ月もすると、テーブルは想像を絶する姿になります。何が問題なのか?これほど巨大なテーブルには、いくつかの問題が潜んでいます。Use
-
Rubyの例外処理(rescue)入門:正しい例外ハンドリングの書き方
AppSignalではRubyアプリケーション向けのエラートラッキングサービスを提供しています。そのために、アプリケーションが発生させるすべての例外をキャッチし、発生したタイミングで開発者へ通知する仕組みを持っています。例外処理を正しく実装するのは意外と難しいものです。この記事では、Rubyにおける例外処理の仕組み、不適切なハンドリングが引き起こす問題、そして例外を適切にrescueする方法について詳しく解説します。rescueによる例外の捕捉Rubyで例外をrescueすると、何か問題が起きた瞬間にアプリケーションがクラッシュするのを防げます。begin .. rescueブロックを使えば、
-
Rubyでわずか30行のコードでHTTPサーバーを構築する方法
WebサーバーやHTTPという仕組みは、一見すると難解に感じられるかもしれません。ブラウザはどのようにリクエストを組み立て、レスポンスはどうやってユーザーの手元に届くのでしょうか?この記事では、わずか30行のコードでRubyによるHTTPサーバーを構築する方法を解説します。完成したサーバーはHTTP GETリクエストを処理できるようになり、最終的にはRackアプリケーションを配信できるところまで進めます。HTTPとTCPが連携する仕組みTCPは、サーバーとクライアントがデータをやり取りする方法を定めたトランスポートプロトコルです。一方、HTTPはWebサーバーとHTTPクライアント(Webブラ
-
Rubyの文字エスケープ完全ガイド:クォート・正規表現・改行の基本を解説
この記事では、Rubyにおける文字のエスケープについて詳しく解説します。文字をエスケープする方法、その仕組み、そして一部のユースケースではエスケープ自体を回避する方法まで学べます。「\ のことは全部知っている」と思っている方も、最後まで読めば意外な発見があるかもしれません。それでは、文字列内の文字エスケープから始めましょう。クォートのエスケープRubyで文字列を扱うとき、文字列の定義に使った引用符と同じ記号を、文字列の中身として含めたいことがあります。その場合は、バックスラッシュ \ を使ってクォート文字をエスケープします。# ダブルクォート文字列内でクォートをエスケープ Hello \wor
-
Rackを動かす:自作Ruby HTTPサーバーでRailsアプリを実行する方法
Ruby Magicシリーズでは、ソフトウェアを分解して内部の仕組みを学ぶのが大好きです。大切なのはプロセスそのものであり、最終的な成果物は本番環境で使うものではありません。目的は、Ruby言語や人気ライブラリの内部的な動作への理解を深めることにあります。新しい記事は月に1回ほど公開しているので、この手の話題がお好きな方はぜひニュースレターをご購読ください。以前のRuby Magicでは、わずか30行のコードでRuby製のHTTPサーバーを実装しました。大量のコードを書くことなく、HTTP GETリクエストを処理し、シンプルなRackアプリケーションを配信することができました。今回は、この自作
-
Rubyの並行性を深掘り:マルチプロセスによるチャットサーバーの実装
以前の「Ruby Magic」の並行性入門記事では、Ruby開発者が利用できる3つの並行性実現手法について紹介しました。本記事は、それぞれの手法を詳しく掘り下げていく3部作シリーズの第1弾です。 まず取り上げるのはマルチプロセスです。この手法では、マスタープロセスが自身を複数のワーカープロセスにフォークします。実際の処理はワーカープロセスが担当し、マスタープロセスはそれらのワーカーを管理します。 本記事の例で使用しているソースコード一式はGitHubで公開されているので、ぜひ自分でも試してみてください。 チャットシステムを作ってみよう! 並行性を学ぶには、チャットシステムの構築がうってつけです
-
並行性の詳細解説:マルチスレッドで実現するRubyチャットサーバー
前回のRuby Magicでは、複数のプロセスを使ってチャットシステムを実装する方法をご紹介しました。今回は、同じことをマルチスレッドで実現する方法を解説します。おさらい基本的なセットアップの詳細については、前回の記事をご覧ください。ここで簡単におさらいしておきましょう。今回作成するチャットシステムは次のような構成になっています。クライアント側のコードは前回と同じものを使用します。# client.rb # $ ruby client.rb require socket client = TCPSocket.open(ARGV[0], 2000) Thread.new do while
-
並行処理の仕組みを徹底解説:Rubyで学ぶイベントループ
はじめに 本記事は「Ruby Magic」による並行処理(コンカレンシー)シリーズの最終回です。これまでの記事では、複数プロセスと複数スレッドを使ってチャットサーバーを実装してきました。今回は同じものをイベントループを使って実装します。 おさらい 前回までの記事と同じクライアントとサーバーの構成を使用します。目標は、複数のユーザーがリアルタイムにメッセージをやり取りできるチャットシステムを構築することです。 基本的なセットアップの詳細については、以前の記事をご覧ください。本記事のサンプルで使用している完全なソースコードはGitHubで公開されているので、実際に手元で動かしながら試すこともでき
-
RubyVM::InstructionSequenceで覗く!Rubyがコードを解釈する仕組み
Ruby Magicの新しい記事へようこそ!今回は、Rubyが私たちのコードをどのように解釈しているのか、そしてその知識をどう活かせるかに迫ります。この記事を通じて、コードが解釈される仕組みを理解し、より高速なコードを書くためのヒントを得られるでしょう。記号の微妙な違い以前のRuby Magic記事「Rubyでのエスケープ文字」では、改行のエスケープに関する例を紹介しました。以下の例では、複数行にわたって2つの文字列を1つのStringに結合する方法として、プラス記号+を使う場合とバックスラッシュ\を使う場合を示しています。foo + bar => foobar # versus
-
カスタムメトリックでキャッシュヒットを追跡し、DBクエリ急増の原因を特定する
AppSignalを利用するアプリケーションが動作しているすべてのサーバーは、30秒ごとにサンプルとメトリクスのコレクションをPush APIへ送信しています。各リクエストにはキーが付与されており、このキーをもとに、そのデータがどのアプリケーションから送られてきたものかを判別します。そのためには、受信したリクエストごとにデータベースへ問い合わせて該当するアプリを検索する必要があります。月間300億件という膨大なリクエストを処理する私たちは、AppSignalをより高速に動作させるため、クエリ数をいかに減らすかを常に模索しています。キャッシュ導入後に逆にクエリが増加した問題そこで私たちは、データ
-
Rubyのスタックトレースを読み解く:例外の発生箇所を特定する方法
アプリケーションでエラーが発生すると、Rubyは例外を発生させ(raise)、ログにスタックトレースを出力します。この記事では、スタックトレースの基本的な読み方と、それを活用してアプリケーション内の例外の発生源を特定する方法を解説します。 コールスタックとは メソッドを呼び出すたびに、Rubyはコールスタック(「ランタイムスタック」とも呼ばれ、単に「スタック」と略されることが多いです)にスタックフレームを積み上げます。スタックフレームとはメモリ上の領域のことで、メソッドの引数、内部変数用のスペース、そして呼び出し元へのリターンアドレスなどを保持しています。 # divide.rb def di
-
Railsアプリの例外をスタックトレースで追跡してバグを特定する方法
Railsアプリケーションでエラーが発生したとき、例外メッセージとスタックトレースは「どこで」問題が起きたのかを教えてくれる重要な手がかりです。しかし、発生場所がわかった後には、その「なぜ」を突き止める必要があります。この記事では、実際の例外を例に、スタックトレースを使ってRailsアプリケーションのバグを特定する手順を解説します。例外メッセージを読み解くまず、次のような例外が発生したケースを見てみましょう。NoMethodError (undefined method `request_uri for #<URI::Generic >): app/models/product.
-
Rubyのシンタックスシュガー徹底解説:name=や[]メソッドの仕組みと自作テクニック
Ruby Magicシリーズへようこそ!今回のテーマはシンタックスシュガーです。Rubyがどのように構文を読みやすく、表現力豊かにしているのかを掘り下げていきます。この記事を読み終える頃には、Rubyのいくつかのトリックが内部でどう動いているのか、そして自分でも「糖衣構文」を活かしたメソッドを書く方法がわかるはずです。Rubyアプリケーションを書いていると、クラスの属性や配列・ハッシュを、他の言語では標準的とは言えない方法で操作することがよくあります。属性を代入するメソッドや、配列・ハッシュから値を取り出すメソッドは、一体どうやって定義すればよいのでしょうか?person1 = Person.
-
Rubyでのデータ検査入門:puts・inspect・pメソッドの使い方
例外の多くは、本来なら問題なく動作するメソッドに予期しないデータが渡されることで発生します。そのため、エラーの原因を突き止めるには、アプリケーション内で対象のデータがどのように流れているかを追跡するのが有効です。この記事では、RubyおよびRailsアプリケーションにおけるデータの検査(インスペクション)方法を紹介します。 puts、#inspect、p Rubyのputsメソッドは、コンソールにメッセージを出力するために使われます。 unknown = This is a string puts unknown 上記のスクリプトを実行すると、変数の中身が出力され、値を確認できます。 $ ru
-
Rubyコードのベンチマーク:パフォーマンス測定と実装比較の基本
Rubyには標準ライブラリとしてベンチマークツールが付属しており、コードのパフォーマンスを手軽に測定できます。特に、2つの実装を比較してどちらが速いかを調べたい場合に威力を発揮します。この記事では、文字列をキーとするハッシュ( bar} のようなもの)を、シンボルをキーとするハッシュ( bar} のようなもの)に変換するタスクを例に取り上げます。例を通して、英字アルファベットの各文字をキーと値のペアにしたハッシュを使用します。ハッシュを手入力せずに素早く生成するために、文字の範囲をテスト用ハッシュに変換します。後で使えるよう、input 変数に格納しておきましょう。z}テスト用の input
-
Rubyの例外処理入門:raiseとrescueの基本をマスターしよう
例外(Exception)とは、アプリケーションで発生した例外的な状況に関する情報を保持する特殊なデータ構造です。プログラムが特定の状況への対処方法を判断できず、実行を継続できないときに送られるシグナルが例外です。Rubyでは、このようなシグナルを送ることを「例外を発生させる(raise)」と呼びます。 raise これは例外です puts このメッセージは表示されません。 例外の動作を最も手軽に確認する方法は、自分で例外を発生させてみることです。raiseメソッドにメッセージを渡して呼び出すと、Rubyはそのテキストを説明文として持つRuntimeErrorを生成します。同時に、コード内
-
Railsのフラグメントキャッシングでビュー描画を高速化する方法
Railsアプリケーションがリクエストを受け取ると、通常はコントローラーがモデルに対象データの取得を依頼します。モデルはデータベースからデータを取り出してコントローラーへ返し、最後にコントローラーがそのデータを人間が読みやすい形式で表現するビューをレンダリングします。しかし場合によっては、ビューのレンダリングが大きなボトルネックになることがあります。特に、ストアで販売中の商品一覧のように大量のデータを表示するケースでは顕著です。こうした場面では、ビューの一部をキャッシュすることでレスポンスを高速化できます。データの更新頻度が低いほど、その効果は大きくなります。👋 この記事が役に立った方は、R
-
ロードアベレージの基本:システム負荷の仕組みと適切な値の判断方法
top、uptime、w などのコマンドや AppSignal のホストメトリクスには、「ロードアベレージ(負荷平均)」という指標が表示されます。この指標を見ることで、複数の時間枠にわたって平均化されたシステムの負荷状況を把握できます。$ uptime 10:14:14 up 60 days, 17:42, 1 user, load average: 0.44, 0.28, 0.25 ロードアベレージは、上記の uptime の出力例のように、通常 3 つの数値として表示されます。末尾の 3 つの数字は、それぞれ直近 1 分間の平均(0.44)、直近 5 分間の平均(0.28)、直近 15
-
Railsのロシア人形キャッシング(Russian Doll Caching)徹底解説:ネストされたフラグメントキャッシュでビューを高速化
Railsの組み込みフラグメントキャッシュをさらに一歩進めてパフォーマンスを最大化したいなら、「ロシア人形キャッシング(Russian Doll Caching)」という手法が強力な武器になります。本記事では、この手法の仕組みと実装方法を詳しく解説します。 フラグメントキャッシュとは Railsに標準搭載されているフラグメントキャッシュでは、レンダリング済みビューの一部が「ビューフラグメント」として保存され、再度リクエストされた際に再利用されます。これらのキャッシュ済みフラグメントは「stale(陳腐化)」状態になるまで使い回されます。staleとは、フラグメント作成後に表示対象のデータが
-
Rubyで例外をrescue(捕捉)する方法を徹底解説
アプリケーション内で発生した例外は、そのまま放置するとコールスタックの最上部まで伝播し、アプリケーション全体をクラッシュさせてしまいます。これを防ぐために、Rubyではrescueキーワードを使って例外を捕捉(キャッチ)します。さらに、Rubyで例外を捕捉する際には、どの例外クラスを対象とするかを具体的に指定することも可能です。begin raise この例外は捕捉されます! rescue StandardError => e puts Rescued: #{e.inspect} end補足:raiseを呼び出す際に例外クラスを指定しなかった場合、RubyはデフォルトでRunti