bug(nodes): duplicate ObservedNode rows from a non-atomic get-then-create

オープン
#480 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
30/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
python
領域
backend, databases

調査の方向性

Start by reading packets/services/base.py and packets/receivers.py, where the issue identifies the non-atomic get-then-create. Then inspect the models and migrations to map the Meshtastic node number, unique constraint, and foreign keys that the dedupe must preserve; review the 2.2.0 migration for its fail-closed and dry-run approach. Done means preventing concurrent duplicates, safely merging existing rows before adding the partial unique index, and naming the node in the remaining error response.

索引モデルが issue の本文から書いたものです。

説明

bug tech-debt

Problem

Some Meshtastic node numbers have two or more ObservedNode rows. In pre-prod there are 38 duplicate pairs, and the prod identity backfill on 2026-11-04 reported 8 duplicate rows.

Cause (confirmed by a verifier): the node is created with a non-atomic get-then-create in packets/services/base.py and packets/receivers.py. Two packets from a new node, ingested within milliseconds of each other (0–8 ms apart in the pre-prod pairs), both miss the get and both create a row.

Effects:

  • Packet uploads that then look the node up hit MultipleObjectsReturned and return 500. The pre-prod bot log had 6 of these on 2026-11-04, and the 400 they produce doesn't name the node.
  • Ghost rows keep a synthesised Unknown Node !xxxxxxxx name while the real row has the node's name, so search and the UI can show two nodes.
  • NodeDB upserts touch .first(), so it's unpredictable which row they update.

Expected

  1. Prevent it: make the create atomic, with get_or_create backed by a unique constraint and a retry on IntegrityError.
  2. Constraint: add a unique (partial) index on the Meshtastic node number, for example meshtastic_node_id where the protocol is Meshtastic.
  3. Clean up existing rows: a data migration or management command that merges each duplicate set into one row: the one with the most history, or the oldest. It re-points every FK (packets, observations, positions, telemetry, claims, watches, and so on), keeps the best name, and deletes the extras. It needs a --dry-run, and should run before the unique index is added.
  4. Error message: the remaining 500/400 should name the node.

Notes

  • This predates the Meshtastic 2.8 work. The rows date from before 2026-11.
  • The dedupe has to run in prod, so it needs the same care as the 2.2.0 migration: fail closed, dry-run first.
  • Related: #436 (ingest correctness review), #437 (2.8: identity linking will need one row per node number).
主要言語
Python
スター
1
フォーク
0
平均マージ
23時間 9分
マージ済み PR(30日)
15

環境構築

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

pskillen/meshflow-api のほかの issue

pskillen/meshflow-api の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。