エラー:範囲外の整数

post_actions の場合はこれで解決しました。提案ありがとうございます!

現在、主に 2 つの障害が引き続き発生しています。

  1. GET https://devforum.roblox.com/notifications は、bigInt ID を持つ通知があるユーザーに対して 404 エラーを返します。

  2. Jobs::GrantAnniversaryBadges スケジュール済みジョブが失敗します。

通知のモデル/コントローラー/サービスが、notifications.id フィールドを整数としてハードコーディングしている可能性はありますか?

可能性は非常に低い… 404 は正しくないように聞こえますが、/logs に問題に関する記述はありますか?

残念ながら、/logs 自体には特に有用なものは見つかりませんが、ローカルで再現すると、リクエストが来てから 404 になることがわかります。ただし、これは最新の通知の ID を bigint に設定した場合にのみ発生します (int32 の範囲内であれば問題なく動作します)。

調べてみると、http://localhost/notifications.json?limit=30 を呼び出すと有効な応答が得られることに気づきました。

{
  "notifications": [
    {
      "id": 2148935910,
      "user_id": 2,
      "notification_type": 5,
      "read": true,
      "high_priority": false,
      "created_at": "2023-02-16T00:50:53.135Z",
      "post_number": 2,
      "topic_id": 8,
      "fancy_title": "Welcome to the Lounge",
      "slug": "welcome-to-the-lounge",
      "data": {
        "topic_title": "Welcome to the Lounge",
        "original_post_id": 13,
        "original_post_type": 1,
        "original_username": "blarouche",
        "revision_number": null,
        "display_username": "blarouche"
      }
    }
  ],
  "total_rows_notifications": 1,
  "seen_notification_id": 1001,
  "load_more_notifications": "/notifications?offset=60&username=bjlarouche"
}

しかし、recent クエリパラメータを渡すと、つまり http://localhost/notifications.json?recent=true&limit=30 とすると、これは通知メニューから呼び出されるものですが、どうなるでしょうか?

{
  "errors": [
    "The requested URL or resource could not be found."
  ],
  "error_type": "not_found"
}

編集: これは、current_user.seen_notification_id がまだ整数であるためではないかと考えています :thinking:

これで大丈夫だと思います!

notifications.id だけでなく、notification_id を参照する他のテーブルの列も移行する必要があることに気づきました。そうでなければ、services/notifications.rb または services/badge_granter.rb でエラーが発生していました。


将来、同様の問題に直面する他の大規模なフォーラム設定のために、以下に実施したことを示します…

合計で、4つのテーブルの4つの列を移行する必要がありました。

  1. notifications.id
  2. user.seen_notification_id
  3. user_badges.notification_id
  4. shelved_notifications.notification_id

当初は上記で提案された ALTER コマンドで #1 を行いましたが、その後、言及したように ActiveRecord のマイグレーションを使用することにしました。これにより、マイグレーションファイルがスキーマに追加されます。

20230215070319_change_notifications_id_to_bigint.rb
# frozen_string_literal: true

class ChangeNotificationsIdToBigint < ActiveRecord::Migration[6.1]
    def change
        change_column :notifications, :id, :bigint
    end
end
20230215070320_change_user_seen_notification_id_to_bigint.rb
# frozen_string_literal: true

class ChangeUserSeenNotificationIdToBigint < ActiveRecord::Migration[6.1]
    def change
        change_column :users, :seen_notification_id, :bigint
    end
end
20230215070321_change_user_badges_notification_id_to_bigint.rb
# frozen_string_literal: true

class ChangeUserBadgesNotificationIdToBigint < ActiveRecord::Migration[6.1]
    def change
        change_column :user_badges, :notification_id, :bigint
    end
end
20230215070322_change_shelved_notifications_notification_id_to_bigint.rb
# frozen_string_literal: true

class ChangeShelvedNotificationsNotificationIdToBigint < ActiveRecord::Migration[6.1]
    def change
        change_column :shelved_notifications, :notification_id, :bigint
    end
end

カスタム Dockerfile を使用しているため(Kubernetes 上で discourse と sidekiq を別々のリソースで実行できるようにイメージをビルドしています)、これらのファイルを /db/migrate にコピーするのは Dockerfile で簡単に行えました。

その後は rake db:migrate にすべてを任せました。すべての discourse および sidekiq ポッドでローリング再起動を行ったところ、すべてが期待どおりに動作しました :crossed_fingers:

「いいね!」 3

素晴らしいデータです。コアのDiscourseでこれをbigintに移行することにしましょう。コストはかかりますが、大きなフォーラムでは必ずまた問題になるでしょうから、今のうちに修正しておくのが良いでしょう。

注意…OPはpost_idについてです…それをオーバーフローさせるのは、notificationsよりもはるかに困難になります。21億件の投稿は確かに起こるでしょうが、post_idをbigintにするコストはnotification idよりもはるかに高価です。この時限爆弾については、もう少し待つことができます。

「いいね!」 4

ブランドン、

以下を採用する可能性があります。

ここでバランスを取る必要があるのは、25億件の通知という驚異的な偉業を達成した1つか2つの外れ値フォーラムのために、40,000のDiscourseインスタンスを「罰したくない」ということです。

どう思いますか?

(注:これには、あなたが逃したものが少なくとも1つ含まれます。チャットテーブルもあります)

「いいね!」 3

これは素晴らしいですし、賢い解決策のように見えます :slight_smile:

これでループバックします。マージされました。 :partying_face:

「いいね!」 5

このトピックは4日後に自動的に閉じられました。新しい返信は許可されていません。