Skip to content

Commit

Permalink
Merge pull request #21 from cloudflare/kenton/experimental
Browse files Browse the repository at this point in the history
Add --experimental CLI flag, require it to enable experimental features.
  • Loading branch information
kentonv committed Sep 25, 2022
2 parents 1d2d962 + 6dd6738 commit 324be7b
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/workerd/io/compatibility-date-test.c++
Expand Up @@ -156,7 +156,17 @@ 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);

// 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",
Expand Down
10 changes: 9 additions & 1 deletion src/workerd/io/compatibility-date.c++
Expand Up @@ -112,7 +112,8 @@ void compileCompatibilityFlags(kj::StringPtr compatDate, capnp::List<capnp::Text
auto parsedCompatDate = CompatDate::parse(compatDate, errorReporter);

switch (dateValidation) {
case CompatibilityDateValidation::CODE_VERISON:
case CompatibilityDateValidation::CODE_VERSION_EXPERIMENTAL:
case CompatibilityDateValidation::CODE_VERSION:
if (KJ_ASSERT_NONNULL(CompatDate::parse(SUPPORTED_COMPATIBILITY_DATE)) < parsedCompatDate) {
errorReporter.addError(kj::str(
"This Worker requires compatibility date \"", parsedCompatDate, "\", but the newest "
Expand Down Expand Up @@ -195,6 +196,13 @@ void compileCompatibilityFlags(kj::StringPtr compatDate, capnp::List<capnp::Text
// it redundant, because at a future date it won't be redundant, and someone could want to
// set the flag early to make sure they don't forget later.
}
if (dateValidation == CompatibilityDateValidation::CODE_VERSION &&
enableByFlag && !enableByDate && enableDate == nullptr) {
errorReporter.addError(kj::str(
"The compatibility flag ", enableFlagName, " 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."));
}

dynamicOutput.set(field, enableByFlag || (enableByDate && !disableByFlag));
}
Expand Down
8 changes: 6 additions & 2 deletions src/workerd/io/compatibility-date.h
Expand Up @@ -10,17 +10,21 @@
namespace workerd {

enum class CompatibilityDateValidation {
CODE_VERISON,
CODE_VERSION,
// Allow dates up through the date specified by `supportedCompatibilityDate` in
// `compatiility-date.capnp`.

CODE_VERSION_EXPERIMENTAL,
// Like CODE_VERSION but permit the use of experimental flags, which is any flag that does not
// yet have a default-on date set.

CURRENT_DATE_FOR_CLOUDFLARE,
// Allow dates up to through the current date.
//
// This should ONLY be used by Cloudflare. If Cloudflare fails to deploy a compatibility flag
// before its default-on date passes, then the flag's default-on date needs to be pushed back.
//
// TODO(someday): We may want to consider eliminating this and using CODE_VERISON even for
// TODO(someday): We may want to consider eliminating this and using CODE_VERSION even for
// Cloudflare. Once people are testing their code using the open source runtime in wrangler,
// they will be forced to set a date no later than `supportedCompatibilityDate` anyway. If
// we make sure Cloudflare is updated before the runtime used locally by Wrangler is updated,
Expand Down
1 change: 1 addition & 0 deletions src/workerd/server/server-test.c++
Expand Up @@ -1290,6 +1290,7 @@ KJ_TEST("Server: Ephemeral Objects") {
]
))"_kj);

test.server.allowExperimental();
test.start();
auto conn = test.connect("test-addr");
conn.httpGet200("/",
Expand Down
17 changes: 15 additions & 2 deletions src/workerd/server/server.c++
Expand Up @@ -1243,7 +1243,9 @@ kj::Own<Server::Service> Server::makeWorker(kj::StringPtr name, config::Worker::
if (conf.hasCompatibilityDate()) {
compileCompatibilityFlags(conf.getCompatibilityDate(), conf.getCompatibilityFlags(),
featureFlags, errorReporter,
CompatibilityDateValidation::CODE_VERISON);
experimental
? CompatibilityDateValidation::CODE_VERSION_EXPERIMENTAL
: CompatibilityDateValidation::CODE_VERSION);
} else {
errorReporter.addError(kj::str("Worker must specify compatibiltyDate."));
}
Expand Down Expand Up @@ -1885,6 +1887,12 @@ kj::Promise<void> 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;
}
Expand All @@ -1908,8 +1916,13 @@ kj::Promise<void> 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&&...) {
Expand Down
6 changes: 6 additions & 0 deletions src/workerd/server/server.h
Expand Up @@ -34,6 +34,10 @@ class Server: private kj::TaskSet::ErrorHandler {
kj::EntropySource& entropySource, kj::Function<void(kj::String)> 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<kj::ConnectionReceiver> port) {
socketOverrides.upsert(kj::mv(name), kj::mv(port));
}
Expand All @@ -57,6 +61,8 @@ class Server: private kj::TaskSet::ErrorHandler {
kj::EntropySource& entropySource;
kj::Function<void(kj::String)> reportConfigError;

bool experimental = false;

kj::HashMap<kj::String, kj::OneOf<kj::String, kj::Own<kj::ConnectionReceiver>>> socketOverrides;
kj::HashMap<kj::String, kj::String> directoryOverrides;
kj::HashMap<kj::String, kj::String> externalOverrides;
Expand Down
3 changes: 3 additions & 0 deletions src/workerd/server/workerd.c++
Expand Up @@ -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();
}
Expand Down

0 comments on commit 324be7b

Please sign in to comment.