Skip to content

Commit 385806a

Browse files
authored
Merge pull request #36196 from vespa-engine/hmusum/stop-using-delete-tenant-feature-flags
Stop using feature flags related to deleting tenants
2 parents b35b449 + f040d0b commit 385806a

2 files changed

Lines changed: 12 additions & 45 deletions

File tree

configserver/src/main/java/com/yahoo/vespa/config/server/tenant/TenantRepository.java

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@
3737
import com.yahoo.vespa.curator.Curator;
3838
import com.yahoo.vespa.curator.transaction.CuratorOperations;
3939
import com.yahoo.vespa.curator.transaction.CuratorTransaction;
40-
import com.yahoo.vespa.flags.BooleanFlag;
4140
import com.yahoo.vespa.flags.FlagSource;
42-
import com.yahoo.vespa.flags.Flags;
43-
import com.yahoo.vespa.flags.LongFlag;
4441
import org.apache.curator.framework.CuratorFramework;
4542
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
4643
import org.apache.curator.framework.state.ConnectionState;
@@ -112,7 +109,6 @@ public class TenantRepository {
112109
private final FileDistributionFactory fileDistributionFactory;
113110
private final ExecutorService deployHelperExecutor;
114111
private final FlagSource flagSource;
115-
private final BooleanFlag softDeleteTenantFlag;
116112
private final HostProvisionerProvider hostProvisionerProvider;
117113
private final ConfigserverConfig configserverConfig;
118114
private final ConfigServerDB configServerDB;
@@ -128,7 +124,6 @@ public class TenantRepository {
128124
private final List<EndpointCertificateSecretStore> endpointCertificateSecretStores;
129125
private final OnnxModelCost onnxModelCost;
130126
private final InheritableApplications inheritableApplications;
131-
private final LongFlag deleteIdleTenantSecondsFlag;
132127

133128
/**
134129
* Creates a new tenant repository
@@ -204,7 +199,6 @@ public TenantRepository(HostRegistry hostRegistry,
204199
this.zkSessionWatcherExecutor = zkSessionWatcherExecutor;
205200
this.fileDistributionFactory = fileDistributionFactory;
206201
this.flagSource = flagSource;
207-
this.softDeleteTenantFlag = Flags.SOFT_DELETE_TENANT.bindTo(flagSource);
208202
this.hostProvisionerProvider = hostProvisionerProvider;
209203
this.configServerDB = configServerDB;
210204
this.zone = zone;
@@ -215,7 +209,6 @@ public TenantRepository(HostRegistry hostRegistry,
215209
this.tenantListener = tenantListener;
216210
this.zookeeperServerConfig = zookeeperServerConfig;
217211
this.endpointCertificateSecretStores = endpointCertificateSecretStores;
218-
this.deleteIdleTenantSecondsFlag = Flags.DELETE_IDLE_TENANT_SECONDS.bindTo(flagSource);
219212
// This we should control with a feature flag.
220213
this.deployHelperExecutor = createModelBuilderExecutor();
221214
this.onnxModelCost = onnxModelCost;
@@ -270,7 +263,7 @@ private TenantMetaData createMetaData(Tenant tenant) {
270263
Instant now = tenant.getSessionRepository().clock().instant();
271264
TenantMetaData metadata = getTenantMetaData(tenant);
272265
Instant deployTime = metadata.lastDeployTimestamp();
273-
if (deployTime.equals(Instant.EPOCH) || deleteIdleTenantSecondsFlag.with(tenant.getName()).value() < 0)
266+
if (deployTime.equals(Instant.EPOCH))
274267
deployTime = now;
275268
Instant createdTime = metadata.createdTimestamp();
276269
if (createdTime.equals(Instant.EPOCH))
@@ -489,22 +482,17 @@ public void deleteTenant(TenantName name) {
489482

490483
notifyRemovedTenant(name);
491484
tenant.close();
492-
if (softDeleteTenantFlag.with(name).value()) {
493-
// Because each config server has a PathDirectoryCache on the `sessions` and `applications` children:
494-
// 1. Once the first config server (say cfg1) reaches this point, the caches on cfg2-3 will recreate
495-
// `sessions` and `applications` immediately after they are deleted by this tryDelete(), likely
496-
// failing this deletion.
497-
// 2. Once the next config server (say cfg2) also reaches this point, the caches on cfg3 will recreate
498-
// `sessions` and `applications`, possibly failing this deletion.
499-
// 3. Once the last config server (cfg3) reaches this point, the delete should succeed.
500-
if (curator.tryDelete(tenant.getPath())) {
501-
log.log(Level.INFO, "Deleted tenant " + name);
502-
} else {
503-
log.log(Level.INFO, "Deleted tenant " + name + " (" + tenant.getPath() + " to be removed by other cfgs)");
504-
}
485+
// Because each config server has a PathDirectoryCache on the `sessions` and `applications` children:
486+
// 1. Once the first config server (say cfg1) reaches this point, the caches on cfg2-3 will recreate
487+
// `sessions` and `applications` immediately after they are deleted by this tryDelete(), likely
488+
// failing this deletion.
489+
// 2. Once the next config server (say cfg2) also reaches this point, the caches on cfg3 will recreate
490+
// `sessions` and `applications`, possibly failing this deletion.
491+
// 3. Once the last config server (cfg3) reaches this point, the delete should succeed.
492+
if (curator.tryDelete(tenant.getPath())) {
493+
log.log(Level.INFO, "Deleted tenant " + name);
505494
} else {
506-
curator.delete(tenant.getPath());
507-
log.log(Level.INFO, "Deleted tenant '" + name + "'");
495+
log.log(Level.INFO, "Deleted tenant " + name + " (" + tenant.getPath() + " to be removed by other cfgs)");
508496
}
509497
}
510498
}
@@ -661,11 +649,7 @@ public Set<TenantName> deleteUnusedTenants(Duration ttlForUnusedTenant, Instant
661649
.filter(tenantName -> activeApplications(tenantName).isEmpty())
662650
.filter(tenantName -> !tenantName.equals(TenantName.defaultName())) // Not allowed to remove 'default' tenant
663651
.filter(tenantName -> !tenantName.equals(HOSTED_VESPA_TENANT)) // Not allowed to remove 'hosted-vespa' tenant
664-
.filter(tenantName -> {
665-
long ttlSeconds = deleteIdleTenantSecondsFlag.with(tenantName).value();
666-
Duration ttl = ttlSeconds < 0 ? ttlForUnusedTenant : Duration.ofSeconds(ttlSeconds);
667-
return getTenantMetaData(getTenant(tenantName)).lastDeployTimestamp().isBefore(now.minus(ttl));
668-
})
652+
.filter(tenantName -> getTenantMetaData(getTenant(tenantName)).lastDeployTimestamp().isBefore(now.minus(ttlForUnusedTenant)))
669653
.peek(this::deleteTenant)
670654
.collect(Collectors.toSet());
671655
}

flags/src/main/java/com/yahoo/vespa/flags/Flags.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,6 @@ public class Flags {
6666
"Takes effect on next deployment of the application",
6767
INSTANCE_ID, VESPA_VERSION);
6868

69-
// TODO(2026-02-20): Remove once this has rolled out, and the overrides have been removed.
70-
public static final UnboundLongFlag DELETE_IDLE_TENANT_SECONDS = defineLongFlag(
71-
"delete-idle-tenant-seconds", 604800,
72-
List.of("hakonhall"), "2026-02-03", "2026-04-03",
73-
"If >=0, then (A) the last deploy time is not updated on config server bootstrap, " +
74-
"and (B) an idle tenant will be deleted after this many seconds (default 604800 = 1 week).",
75-
"(A) takes effect on cfg bootstrap, (B) on next tick of TenantsMaintainer",
76-
TENANT_ID);
77-
78-
// TODO(2026-02-20): Remove once this has rolled out, and the overrides have been removed.
79-
public static final UnboundBooleanFlag SOFT_DELETE_TENANT = defineFeatureFlag(
80-
"soft-delete-tenant", true,
81-
List.of("hakonhall"), "2026-01-20", "2026-04-20",
82-
"When deleting /config/v2/tenants/TENANT recursively - whether to give up (true) or retry (false) on NotEmptyException",
83-
"Takes effect immediately",
84-
TENANT_ID);
85-
8669
public static final UnboundBooleanFlag LOCKED_GCP_PROVISION = defineFeatureFlag(
8770
"locked-gcp-provision", true,
8871
List.of("hakonhall"), "2025-08-05", "2026-04-15",

0 commit comments

Comments
 (0)