From 0744470313a348074d58d26e707f08bf11d4018f Mon Sep 17 00:00:00 2001 From: Kenton Varda Date: Sun, 25 Sep 2022 15:45:37 -0500 Subject: [PATCH 1/2] Fix typo: CODE_VERISON -> CODE_VERSION --- src/workerd/io/compatibility-date-test.c++ | 2 +- src/workerd/io/compatibility-date.c++ | 2 +- src/workerd/io/compatibility-date.h | 4 ++-- src/workerd/server/server.c++ | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/workerd/io/compatibility-date-test.c++ b/src/workerd/io/compatibility-date-test.c++ index 24f4d7b5200..82f0b8d0740 100644 --- a/src/workerd/io/compatibility-date-test.c++ +++ b/src/workerd/io/compatibility-date-test.c++ @@ -156,7 +156,7 @@ KJ_TEST("compatibility flag parsing") { expectCompileCompatibilityFlags("2252-04-01", {}, "()", {kj::str("This Worker requires compatibility date \"2252-04-01\", but the newest date " "supported by this server binary is \"", SUPPORTED_COMPATIBILITY_DATE, "\".")}, - CompatibilityDateValidation::CODE_VERISON); + CompatibilityDateValidation::CODE_VERSION); // Multiple errors. expectCompileCompatibilityFlags("abcd", diff --git a/src/workerd/io/compatibility-date.c++ b/src/workerd/io/compatibility-date.c++ index 567ebce4eaf..51f44f27658 100644 --- a/src/workerd/io/compatibility-date.c++ +++ b/src/workerd/io/compatibility-date.c++ @@ -112,7 +112,7 @@ void compileCompatibilityFlags(kj::StringPtr compatDate, capnp::List Server::makeWorker(kj::StringPtr name, config::Worker:: if (conf.hasCompatibilityDate()) { compileCompatibilityFlags(conf.getCompatibilityDate(), conf.getCompatibilityFlags(), featureFlags, errorReporter, - CompatibilityDateValidation::CODE_VERISON); + CompatibilityDateValidation::CODE_VERSION); } else { errorReporter.addError(kj::str("Worker must specify compatibiltyDate.")); } From 6dd673836c2af1308b26afccd1837090020191c0 Mon Sep 17 00:00:00 2001 From: Kenton Varda Date: Sun, 25 Sep 2022 15:57:12 -0500 Subject: [PATCH 2/2] Add --experimental CLI flag, require it to enable experimental features. Specifically, the following features are considered experimental: - Ephemeral objects (fka "colo-local actors"). - Any compatibility flag that doesn't have a default-on date assigned. We could consider creating a separate `$experimental` or `$stable` annotation instead of using presence/absence of a date, but I wanted to be cautious for now. (Incidentally, though, it looks like we should go ahead and assign dates to most of the flags that don't have them?) I decided to use a CLI flag rather than a config flag in order to add resistance against using this in production, but we can consider finer-grained control if it proves warranted. --- src/workerd/io/compatibility-date-test.c++ | 10 ++++++++++ src/workerd/io/compatibility-date.c++ | 8 ++++++++ src/workerd/io/compatibility-date.h | 4 ++++ src/workerd/server/server-test.c++ | 1 + src/workerd/server/server.c++ | 17 +++++++++++++++-- src/workerd/server/server.h | 6 ++++++ src/workerd/server/workerd.c++ | 3 +++ 7 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/workerd/io/compatibility-date-test.c++ b/src/workerd/io/compatibility-date-test.c++ index 82f0b8d0740..9a599ae4c64 100644 --- a/src/workerd/io/compatibility-date-test.c++ +++ b/src/workerd/io/compatibility-date-test.c++ @@ -158,6 +158,16 @@ KJ_TEST("compatibility flag parsing") { "supported by this server binary is \"", SUPPORTED_COMPATIBILITY_DATE, "\".")}, CompatibilityDateValidation::CODE_VERSION); + // Test experimental requirement using the durable_object_alarms flag since we know this flag + // is obsolete and will never have a date set. + expectCompileCompatibilityFlags("2020-01-01", {"durable_object_alarms"_kj}, "(obsolete14 = true)", + {"The compatibility flag durable_object_alarms is experimental and may break or be removed " + "in a future version of workerd. To use this flag, you must pass --experimental on the " + "command line."_kj}, + CompatibilityDateValidation::CODE_VERSION); + expectCompileCompatibilityFlags("2020-01-01", {"durable_object_alarms"_kj}, "(obsolete14 = true)", + {}, CompatibilityDateValidation::CODE_VERSION_EXPERIMENTAL); + // Multiple errors. expectCompileCompatibilityFlags("abcd", {"formdata_parser_supports_files"_kj, "fetch_refuses_unknown_protocols"_kj, diff --git a/src/workerd/io/compatibility-date.c++ b/src/workerd/io/compatibility-date.c++ index 51f44f27658..58e6c61cf96 100644 --- a/src/workerd/io/compatibility-date.c++ +++ b/src/workerd/io/compatibility-date.c++ @@ -112,6 +112,7 @@ void compileCompatibilityFlags(kj::StringPtr compatDate, capnp::List Server::makeWorker(kj::StringPtr name, config::Worker:: if (conf.hasCompatibilityDate()) { compileCompatibilityFlags(conf.getCompatibilityDate(), conf.getCompatibilityFlags(), featureFlags, errorReporter, - CompatibilityDateValidation::CODE_VERSION); + experimental + ? CompatibilityDateValidation::CODE_VERSION_EXPERIMENTAL + : CompatibilityDateValidation::CODE_VERSION); } else { errorReporter.addError(kj::str("Worker must specify compatibiltyDate.")); } @@ -1885,6 +1887,12 @@ kj::Promise Server::run(jsg::V8System& v8System, config::Config::Reader co Durable { kj::str(ns.getUniqueKey()) }); continue; case config::Worker::DurableObjectNamespace::EPHEMERAL_LOCAL: + if (!experimental) { + reportConfigError(kj::str( + "Ephemeral objects (Durable Object namespaces with type 'ehpmeralLocal') are an " + "experimental feature which may change or go away in the future. You must run " + "workerd with `--experimental` to use this feature.")); + } serviceActorConfigs.insert(kj::str(ns.getClassName()), Ephemeral {}); continue; } @@ -1908,8 +1916,13 @@ kj::Promise Server::run(jsg::V8System& v8System, config::Config::Reader co reportConfigError(kj::str( "Encountered unknown durableObjectStorage type in service \"", name, "\". Was the config compiled with a newer version of the schema?")); + validDurableObjectStorage: - ; + if (workerConf.hasDurableObjectUniqueKeyModifier()) { + // This should be implemented along with parameterized workers. It's not relevant + // otherwise, but let's make sure no one sets it accidentally. + KJ_UNIMPLEMENTED("durableObjectUniqueKeyModifier is not implemented yet"); + } } actorConfigs.upsert(kj::str(name), kj::mv(serviceActorConfigs), [&](auto&&...) { diff --git a/src/workerd/server/server.h b/src/workerd/server/server.h index a387843f921..0c9fb6fb647 100644 --- a/src/workerd/server/server.h +++ b/src/workerd/server/server.h @@ -34,6 +34,10 @@ class Server: private kj::TaskSet::ErrorHandler { kj::EntropySource& entropySource, kj::Function reportConfigError); ~Server() noexcept(false); + void allowExperimental() { experimental = true; } + // Permit experimental features to be used. These features may break backwards compatibility + // in the future. + void overrideSocket(kj::String name, kj::Own port) { socketOverrides.upsert(kj::mv(name), kj::mv(port)); } @@ -57,6 +61,8 @@ class Server: private kj::TaskSet::ErrorHandler { kj::EntropySource& entropySource; kj::Function reportConfigError; + bool experimental = false; + kj::HashMap>> socketOverrides; kj::HashMap directoryOverrides; kj::HashMap externalOverrides; diff --git a/src/workerd/server/workerd.c++ b/src/workerd/server/workerd.c++ index 05f301afec7..b4be7622c74 100644 --- a/src/workerd/server/workerd.c++ +++ b/src/workerd/server/workerd.c++ @@ -575,6 +575,9 @@ public: .addOption({'w', "watch"}, CLI_METHOD(watch), "Watch configuration files (and server binary) and reload if they change. " "Useful for development, but not recommended in production.") + .addOption({"experimental"}, [this]() { server.allowExperimental(); return true; }, + "Permit the use of experimental features which may break backwards " + "compatibility in a future release.") .callAfterParsing(CLI_METHOD(serve)) .build(); }