Skip to content

addIoTDatabaseIndex races the IoT Agent and kills the services script - #18

Open
kzangeli wants to merge 1 commit into
FIWARE:NGSI-LDfrom
kzangeli:fix/iot-db-index-race
Open

kzangeli wants to merge 1 commit into
FIWARE:NGSI-LDfrom
kzangeli:fix/iot-db-index-race

Conversation

@kzangeli

Copy link
Copy Markdown

addIoTDatabaseIndex drops every collection in iotagentjson and then re-creates devices and groups:

db.getCollectionNames().forEach(c=>db[c].drop());
db.createCollection("devices");
...

By the time it runs, the IoT Agent container is already up and connected to the same database — it is started by the same docker compose up. If the agent creates devices in the window between the drop loop and the createCollection call, the call fails:

MongoServerError: Collection iotagentjson.devices already exists.

On mongo 6.0, which is what MONGO_DB_VERSION pins, db.createCollection on an existing collection throws NamespaceExists; mongosh then exits 1; and services runs under set -e, so the whole invocation dies — after the stack is up, before the tutorial has run a single request.

Because it depends on who wins the race, it shows up as an intermittent mystery red rather than as a bug. It was caught in tutorials.Big-Data-Flink's own CI, where the identical commit then passed on re-run.

(Worth knowing for later: mongo 8 made createCollection return {ok:1} in this case, so raising MONGO_DB_VERSION would hide this rather than fix it.)

The fix

The two createCollection calls are redundant — createIndex creates the collection implicitly when it is missing. Dropping them closes the window with no other change.

Verified on mongo 6.0:

current amended
clean database exit 0 exit 0
run twice in a row exit 1 exit 0
collection created concurrently mid-script exit 1 exit 0

and the resulting indexes are identical either way:

devices: {_id}, {_id.service,_id.id,_id.type}, {_id.type}, {_id.id}
groups:  {_id}, {_id.resource,_id.apikey,_id.service}, {_id.type}

Scope

Nine tutorials carry this function verbatim. This is one of them; the same one-hunk change is going to each, with FIWARE/tutorials.Big-Data-Flink#17 as the original.

🤖 Generated with Claude Code

`addIoTDatabaseIndex` drops every collection in `iotagentjson` and then
re-creates `devices` and `groups`. The IoT Agent container is already up and
connected by then - it is started by the same `docker compose up` - so it can
create `devices` itself in the window between the drop loop and the
`createCollection` call.

On mongo 6.0, which is what `MONGO_DB_VERSION` pins, `db.createCollection` on
an existing collection throws `NamespaceExists` and `mongosh` exits 1. The
script runs under `set -e`, so the whole `services` invocation dies - after
the stack is up, before the tutorial has done anything:

    MongoServerError: Collection iotagentjson.devices already exists.

The two `createCollection` calls are redundant: `createIndex` creates the
collection implicitly if it is missing. Removing them makes the block
idempotent and closes the window, with no other change - verified on mongo 6.0
that the resulting index sets are identical:

    devices: {_id}, {_id.service,_id.id,_id.type}, {_id.type}, {_id.id}
    groups:  {_id}, {_id.resource,_id.apikey,_id.service}, {_id.type}

and that the amended block exits 0 when run twice in a row and when the
collection has been created concurrently in between - the two cases that make
the current version exit 1.

Caught in tutorials.Big-Data-Flink's own CI; the same function is carried
verbatim by nine tutorials, this one among them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant