Skip to content

Commit e254d00

Browse files
Sagar-TalikotiSagar-Talikoti
authored andcommitted
fix for idempotent call
1 parent 1ca654c commit e254d00

3 files changed

Lines changed: 64 additions & 3 deletions

File tree

‎bin/mas-devops-feature-status-update.md‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ Verifies MongoDB connectivity and confirms that the required indexes exist on th
148148

149149
Pass `--create-indexes` to create missing indexes automatically instead of exiting with an error.
150150

151+
**Idempotency:** Safe to run repeatedly. The connectivity check is read-only. When `--create-indexes` is passed, `create_index` is a no-op for any index that already exists — it will never drop or recreate an existing index.
152+
151153
**Options**
152154

153155
| Flag | Required | Description |
@@ -181,9 +183,11 @@ After a successful `prep` run the command prints the `export` statements needed
181183

182184
### `status-update`
183185

184-
Upserts a feature status document.
186+
Upserts a feature status document.
185187
Upsert key: `(region, instance_id, account, cluster, type)` — an existing document is updated in-place; a new document is inserted if no match is found.
186188

189+
**Idempotency:** Safe to call multiple times with the same arguments. The underlying `find_one_and_update` with `upsert=True` guarantees that re-running with the same identity key produces the same final document state. `created_at` is set only on the first insert (`$setOnInsert`); subsequent calls update `updated_at` and all mutable fields without creating duplicate documents.
190+
187191
**Identity options** *(all required)*
188192

189193
| Flag | Description |
@@ -341,6 +345,8 @@ mas-devops-feature-status-update status-update \
341345

342346
Fetches a single feature status document by its ObjectId and prints it as formatted JSON.
343347

348+
**Idempotency:** Read-only. Safe to call any number of times with no side effects.
349+
344350
**Arguments**
345351

346352
| Argument | Required | Description |

‎mongodb_schemas/README.md‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,44 @@ db.instance_level_config.aggregate([
489489
mongosh "mongodb://<host>:27017/feature_dashboard" mongodb_schemas/init_db.js
490490
```
491491

492+
> **Idempotency:** `db.createCollection()` raises a `MongoServerError: Collection already exists` error if the collection is already present. The initialization scripts are **not safe to re-run** against an existing database. Use the safe re-initialization pattern below if you need to ensure indexes are up to date without dropping data.
493+
494+
### Safe re-initialization (collections already exist)
495+
496+
If the collections already exist and you only need to ensure indexes are up to date, run `createIndex` calls directly — they are no-ops when the index name and definition already match:
497+
498+
```js
499+
use feature_dashboard
500+
501+
// cluster_level_config indexes
502+
db.cluster_level_config.createIndex(
503+
{ tenant_id: 1, account: 1, region: 1, cluster: 1 },
504+
{ unique: true, name: "ux_cluster_level_config_tenant_account_region_cluster" }
505+
);
506+
db.cluster_level_config.createIndex(
507+
{ tenant_id: 1, account: 1 },
508+
{ name: "ix_cluster_level_config_tenant_account" }
509+
);
510+
511+
// instance_level_config indexes
512+
db.instance_level_config.createIndex(
513+
{ tenant_id: 1, subscription_id: 1, account: 1, region: 1, cluster: 1, instance: 1 },
514+
{ unique: true, name: "ux_instance_level_config_tenant_sub_account_region_cluster_instance" }
515+
);
516+
db.instance_level_config.createIndex(
517+
{ tenant_id: 1, subscription_id: 1, account: 1, region: 1, cluster: 1 },
518+
{ name: "ix_instance_level_config_tenant_sub_account_region_cluster" }
519+
);
520+
db.instance_level_config.createIndex(
521+
{ "instance_level_features.status": 1 },
522+
{ name: "ix_instance_level_config_feature_status" }
523+
);
524+
db.instance_level_config.createIndex(
525+
{ "instance_level_features.status_details.error_code": 1 },
526+
{ sparse: true, name: "ix_instance_level_config_error_code" }
527+
);
528+
```
529+
492530
### Clear the collections
493531

494532
```js
@@ -497,6 +535,8 @@ db.cluster_level_config.deleteMany({})
497535
db.instance_level_config.deleteMany({})
498536
```
499537

538+
> **Idempotency:** Safe to run repeatedly — `deleteMany({})` is a no-op when the collection is already empty.
539+
500540
### Drop the collections
501541

502542
```js
@@ -506,6 +546,7 @@ db.instance_level_config.drop()
506546
```
507547

508548
> **Note:** `drop()` removes the collection, all its documents, and its indexes. Re-run `init_db.js` to recreate them.
549+
> **Idempotency:** Not idempotent — `drop()` raises an error if the collection does not exist. Re-running `init_db.js` after a drop is safe because the collections no longer exist at that point.
509550
510551
### Run a schema file directly
511552

@@ -514,6 +555,22 @@ mongosh "mongodb://<host>:27017/feature_dashboard" mongodb_schemas/cluster_level
514555
mongosh "mongodb://<host>:27017/feature_dashboard" mongodb_schemas/instance_level_config.js
515556
```
516557

558+
> **Idempotency:** Same caveat as `init_db.js` — each file calls `db.createCollection()`, which fails if the collection already exists. Only run against a fresh or dropped database.
559+
560+
---
561+
562+
## Idempotency reference
563+
564+
| Operation | Idempotent | Notes |
565+
|---|---|---|
566+
| `init_db.js` (full init) | ❌ | `db.createCollection()` fails if the collection already exists. Only run against a fresh or dropped database. |
567+
| `cluster_level_config.js` | ❌ | Same — calls `db.createCollection()`. |
568+
| `instance_level_config.js` | ❌ | Same — calls `db.createCollection()`. |
569+
| `createIndex` (standalone) | ✅ | No-op when an index with the same name and definition already exists. Safe to run on a live collection. |
570+
| `deleteMany({})` (clear) | ✅ | No-op on an already-empty collection. |
571+
| `drop()` | ❌ | Errors if the collection does not exist. |
572+
| Document upserts via `mas-devops-feature-status-update status-update` | ✅ | Uses `find_one_and_update` with `upsert=True`. Repeated calls on the same identity key update in-place; `created_at` is protected by `$setOnInsert`. |
573+
517574
---
518575

519576
## Validation behaviour

‎src/mas/devops/feature_status.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,12 @@ def create_indexes(mongo_url: str, credentials: Optional[dict] = None) -> None:
179179
collection.create_index(
180180
[("region", ASCENDING), ("instance_id", ASCENDING), ("account", ASCENDING)],
181181
name="instance_config_level",
182-
background=True,
183182
)
184183
logger.info("Index 'instance_config_level' ensured on %s.%s", DATABASE, COLLECTION)
185184

186185
collection.create_index(
187186
[("region", ASCENDING), ("cluster", ASCENDING), ("account", ASCENDING)],
188187
name="cluster_config_level",
189-
background=True,
190188
)
191189
logger.info("Index 'cluster_config_level' ensured on %s.%s", DATABASE, COLLECTION)
192190
finally:

0 commit comments

Comments
 (0)