Skip to content

Commit 3c2b96a

Browse files
authored
Enable use of shortids by default (#24142)
This PR enables use of short ids by default. Along with having a kill-switch configuration available to turn the feature off if needed). The PR also fixes the corresponding test. The was implemented with `assetInvert` to negatively test for special characters and short ids when the bug was not fixed. Note: This PR is a follow up from a sequence of fixes that have went in before, to ensure cross client and cross layer compat. Short summary - short ids previously generated characters that changed their form when any code used `encodeURIComponent()`. That has been fixed by - 1 updating the shortids generator code to only use encode safe characters + removal of `encodeURIComponent` where it was being used. #21680 #24097 #24032 Fixes [AB#8568](https://dev.azure.com/fluidframework/235294da-091d-4c29-84fc-cdfc3d90890b/_workitems/edit/8568)
1 parent 02ecf8d commit 3c2b96a

File tree

4 files changed

+20
-41
lines changed

4 files changed

+20
-41
lines changed

packages/runtime/container-runtime/src/channelCollection.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -621,11 +621,11 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
621621
*/
622622
protected createDataStoreId(): string {
623623
/**
624-
* There is currently a bug where certain data store ids such as "[" are getting converted to ASCII characters
625-
* in the snapshot.
626-
* So, return short ids only if explicitly enabled via feature flags. Else, return uuid();
624+
* Return uuid if short-ids are explicitly disabled via feature flags.
627625
*/
628-
if (this.mc.config.getBoolean("Fluid.Runtime.IsShortIdEnabled") === true) {
626+
if (this.mc.config.getBoolean("Fluid.Runtime.DisableShortIds") === true) {
627+
return uuid();
628+
} else {
629629
// We use three non-overlapping namespaces:
630630
// - detached state: even numbers
631631
// - attached state: odd numbers
@@ -641,7 +641,6 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
641641
}
642642
return id;
643643
}
644-
return uuid();
645644
}
646645

647646
public createDetachedDataStore(

packages/runtime/datastore/src/dataStoreRuntime.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -459,11 +459,11 @@ export class FluidDataStoreRuntime
459459
this.validateChannelId(id);
460460
} else {
461461
/**
462-
* There is currently a bug where certain data store ids such as "[" are getting converted to ASCII characters
463-
* in the snapshot.
464-
* So, return short ids only if explicitly enabled via feature flags. Else, return uuid();
462+
* Return uuid if short-ids are explicitly disabled via feature flags.
465463
*/
466-
if (this.mc.config.getBoolean("Fluid.Runtime.IsShortIdEnabled") === true) {
464+
if (this.mc.config.getBoolean("Fluid.Runtime.DisableShortIds") === true) {
465+
id = uuid();
466+
} else {
467467
// We use three non-overlapping namespaces:
468468
// - detached state: even numbers
469469
// - attached state: odd numbers
@@ -480,8 +480,6 @@ export class FluidDataStoreRuntime
480480
this.dataStoreContext.containerRuntime.generateDocumentUniqueId?.() ?? uuid();
481481
id = typeof res === "number" ? encodeCompactIdToString(2 * res + 1, "_") : res;
482482
}
483-
} else {
484-
id = uuid();
485483
}
486484
assert(!id.includes("/"), 0x8fc /* slash */);
487485
}

packages/test/test-end-to-end-tests/src/test/idCompressor.spec.ts

+12-28
Original file line numberDiff line numberDiff line change
@@ -945,25 +945,13 @@ describeCompat("IdCompressor Summaries", "NoCompat", (getTestObjectProvider, com
945945
);
946946
});
947947

948-
/**
949-
* Function that asserts that the value is not as expected. e have a bug in one of our customer's app where a short
950-
* data store ID created is `[` but in a downloaded snapshot, it is converted to its ASCII equivalent `%5B` in
951-
* certain conditions. So, when an op comes for this data store with id `[`, containers loaded with this snapshot
952-
* cannot find the data store.
953-
*
954-
* While we figure out the fix, we are disabling the ability to create short IDs and this assert validates it.
955-
*/
956-
function assertInvert(value: boolean, message: string) {
957-
assert(!value, message);
958-
}
959-
960948
async function TestCompactIds(enableRuntimeIdCompressor: IdCompressorMode) {
961949
const container = await createContainer({
962950
runtimeOptions: { enableRuntimeIdCompressor },
963951
});
964952
const defaultDataStore = (await container.getEntryPoint()) as ITestDataObject;
965953
// This data store was created in detached container, so it has to be short!
966-
assertInvert(
954+
assert(
967955
defaultDataStore._runtime.id.length <= 2,
968956
"short data store ID created in detached container",
969957
);
@@ -1002,14 +990,14 @@ describeCompat("IdCompressor Summaries", "NoCompat", (getTestObjectProvider, com
1002990
// Check directly that ID compressor is issuing short IDs!
1003991
// If it does not, the rest of the tests would fail - this helps isolate where the bug is.
1004992
const idTest = defaultDataStore._context.containerRuntime.generateDocumentUniqueId();
1005-
assertInvert(typeof idTest === "number" && idTest >= 0, "short IDs should be issued");
993+
assert(typeof idTest === "number" && idTest >= 0, "short IDs should be issued");
1006994

1007995
// create another datastore
1008996
const ds2 = await defaultDataStore._context.containerRuntime.createDataStore(pkg);
1009997
const entryPoint2 = (await ds2.entryPoint.get()) as ITestDataObject;
1010998

1011999
// This data store was created in attached container, and should have used ID compressor to assign ID!
1012-
assertInvert(
1000+
assert(
10131001
entryPoint2._runtime.id.length <= 2,
10141002
"short data store ID created in attached container",
10151003
);
@@ -1028,7 +1016,7 @@ describeCompat("IdCompressor Summaries", "NoCompat", (getTestObjectProvider, com
10281016
undefined,
10291017
SharedDirectory.getFactory().type,
10301018
);
1031-
assertInvert(channel.id.length <= 2, "DDS ID created in detached data store");
1019+
assert(channel.id.length <= 2, "DDS ID created in detached data store");
10321020

10331021
// attached data store.
10341022
await ds2.trySetAlias("foo");
@@ -1043,7 +1031,7 @@ describeCompat("IdCompressor Summaries", "NoCompat", (getTestObjectProvider, com
10431031
undefined,
10441032
SharedDirectory.getFactory().type,
10451033
);
1046-
assertInvert(channel2.id.length <= 2, "DDS ID created in attached data store");
1034+
assert(channel2.id.length <= 2, "DDS ID created in attached data store");
10471035
}
10481036

10491037
it("Container uses short DataStore & DDS IDs in delayed mode", async () => {
@@ -1062,19 +1050,17 @@ describeCompat("IdCompressor Summaries", "NoCompat", (getTestObjectProvider, com
10621050
};
10631051
const container = await loader.createDetachedContainer(defaultCodeDetails);
10641052
const defaultDataStore = (await container.getEntryPoint()) as ITestFluidObject;
1065-
assertInvert(
1053+
assert(
10661054
defaultDataStore.context.id.length <= 2,
1067-
"Default data store's ID should be short",
1055+
"Default data store's ID should be short.",
10681056
);
10691057
const dataStore1 =
10701058
await defaultDataStore.context.containerRuntime.createDataStore(TestDataObjectType);
10711059
const ds1 = (await dataStore1.entryPoint.get()) as ITestFluidObject;
1072-
assertInvert(
1060+
assert(
10731061
ds1.context.id.length <= 2,
10741062
"Data store's ID in detached container should not be short",
10751063
);
1076-
const dds1 = SharedDirectory.create(ds1.runtime);
1077-
assertInvert(dds1.id.length <= 2, "DDS's ID in detached container should not be short");
10781064

10791065
await container.attach(provider.driver.createCreateNewRequest());
10801066

@@ -1085,15 +1071,14 @@ describeCompat("IdCompressor Summaries", "NoCompat", (getTestObjectProvider, com
10851071
ds2.context.id.length > 8,
10861072
"Data store's ID in attached container should not be short",
10871073
);
1088-
const dds2 = SharedDirectory.create(ds2.runtime);
1089-
assert(dds2.id.length > 8, "DDS's ID in attached container should not be short");
10901074
});
10911075
});
10921076

10931077
/**
1094-
* These tests repro a bug where ODSP driver does not correctly decode encoded snapshot tree paths.
1095-
* Data store / DDS created with special characters are encoded during summary upload but during
1096-
* download, they are not correctly decoded in certain scenarios.
1078+
* These tests try to reproduce a bug where ODSP driver did not correctly decode encoded snapshot tree paths.
1079+
* Data store / DDS created with special characters were encoded during summary upload but during
1080+
* download, they were not correctly decoded in certain scenarios.
1081+
* The bug has been resolved, but these tests are kept to ensure that the bug does not regress.
10971082
*/
10981083
describeCompat(
10991084
"Short IDs in detached container",
@@ -1119,7 +1104,6 @@ describeCompat(
11191104
if (provider.driver.type !== "odsp") {
11201105
this.skip();
11211106
}
1122-
configProvider.set("Fluid.Runtime.IsShortIdEnabled", true);
11231107
});
11241108

11251109
/**

packages/test/test-end-to-end-tests/src/test/summarization/summaryHandles.spec.ts

-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,6 @@ describeCompat.skip(
6262
});
6363

6464
it("A data store id with special character `[` works properly with summary handles", async () => {
65-
// Enable short ids for this test to create a data store with special character.
66-
configProvider.set("Fluid.Runtime.IsShortIdEnabled", true);
6765
// Enable single-commit summaries so that when the test runs with old odsp driver, it doesn't fail with summary nacks.
6866
configProvider.set("Fluid.Container.summarizeProtocolTree2", true);
6967
const container = await provider.createDetachedContainer(runtimeFactory, {

0 commit comments

Comments
 (0)