summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@oath.com>2018-07-09 09:14:48 +0200
committerHarald Musum <musum@oath.com>2018-07-09 09:14:48 +0200
commitad555e737c4a98b5d1cf0c60de999b96b7599c5b (patch)
tree9a31838b93239c3a955687bae0967134d424482a /configserver
parent871411290d22988e9d0b6e3aeebd5b90e636ca14 (diff)
Move deletion of inactive sessions to a maintainer
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java10
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/FileDistributionMaintainer.java8
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/Maintainer.java5
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/SessionsMaintainer.java26
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainer.java6
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ZooKeeperDataMaintainer.java4
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java10
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java47
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/RedeployTest.java46
10 files changed, 106 insertions, 59 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index e8cfcf75de3..8d20d610c47 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -553,6 +553,9 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return session.getSessionId();
}
+ public void deleteOldSessions() {
+ listApplications().forEach(app -> tenantRepository.getTenant(app.tenant()).getLocalSessionRepo().purgeOldSessions());
+ }
// ---------------- Tenant operations ----------------------------------------------------------------
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java
index 1f8e8ff6fe8..c1fc484e23c 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ConfigServerMaintenance.java
@@ -10,11 +10,19 @@ import com.yahoo.vespa.curator.Curator;
import java.time.Duration;
+/**
+ * Maintenance jobs of the config server.
+ * Each maintenance job is a singleton instance of its implementing class, created and owned by this,
+ * and running its own dedicated thread.
+ *
+ * @author hmusum
+ */
public class ConfigServerMaintenance extends AbstractComponent {
private final TenantsMaintainer tenantsMaintainer;
private final ZooKeeperDataMaintainer zooKeeperDataMaintainer;
private final FileDistributionMaintainer fileDistributionMaintainer;
+ private final SessionsMaintainer sessionsMaintainer;
@SuppressWarnings("unused") // instantiated by Dependency Injection
public ConfigServerMaintenance(ConfigserverConfig configserverConfig,
@@ -25,6 +33,7 @@ public class ConfigServerMaintenance extends AbstractComponent {
tenantsMaintainer = new TenantsMaintainer(applicationRepository, curator, defaults.tenantsMaintainerInterval);
zooKeeperDataMaintainer = new ZooKeeperDataMaintainer(applicationRepository, curator, defaults.defaultInterval);
fileDistributionMaintainer = new FileDistributionMaintainer(applicationRepository, curator, defaults.defaultInterval, configserverConfig);
+ sessionsMaintainer = new SessionsMaintainer(applicationRepository, curator, defaults.defaultInterval);
}
@Override
@@ -32,6 +41,7 @@ public class ConfigServerMaintenance extends AbstractComponent {
tenantsMaintainer.deconstruct();
zooKeeperDataMaintainer.deconstruct();
fileDistributionMaintainer.deconstruct();
+ sessionsMaintainer.deconstruct();
}
/*
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/FileDistributionMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/FileDistributionMaintainer.java
index 4f45b200111..a5d4aa226a6 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/FileDistributionMaintainer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/FileDistributionMaintainer.java
@@ -9,7 +9,13 @@ import com.yahoo.vespa.defaults.Defaults;
import java.io.File;
import java.time.Duration;
-// Note: Unit test is in ApplicationRepositoryTest
+/**
+ * Removes unused file references from disk
+ * <p>
+ * Note: Unit test is in ApplicationRepositoryTest
+ *
+ * @author hmusum
+ */
public class FileDistributionMaintainer extends Maintainer {
private final ApplicationRepository applicationRepository;
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/Maintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/Maintainer.java
index ae000385dfd..513f70e4187 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/Maintainer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/Maintainer.java
@@ -16,6 +16,11 @@ import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
+/**
+ * A maintainer is some job which runs at a fixed interval to perform some maintenance task in the config server.
+ *
+ * @author hmusum
+ */
public abstract class Maintainer extends AbstractComponent implements Runnable {
protected static final Logger log = Logger.getLogger(Maintainer.class.getName());
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/SessionsMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/SessionsMaintainer.java
new file mode 100644
index 00000000000..53f2553161f
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/SessionsMaintainer.java
@@ -0,0 +1,26 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.maintenance;
+
+import com.yahoo.vespa.config.server.ApplicationRepository;
+import com.yahoo.vespa.curator.Curator;
+
+import java.time.Duration;
+
+/**
+ * Removes inactive sessions
+ * <p>
+ * Note: Unit test is in ApplicationRepositoryTest
+ *
+ * @author hmusum
+ */
+public class SessionsMaintainer extends Maintainer {
+
+ SessionsMaintainer(ApplicationRepository applicationRepository, Curator curator, Duration interval) {
+ super(applicationRepository, curator, interval);
+ }
+
+ @Override
+ protected void maintain() {
+ applicationRepository.deleteOldSessions();
+ }
+}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainer.java
index ad3b1f9b1ea..86bd4e8db8e 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/TenantsMaintainer.java
@@ -7,6 +7,11 @@ import com.yahoo.vespa.curator.Curator;
import java.time.Duration;
import java.time.Instant;
+/**
+ * Removes unused tenants (has no applications and was created more than 7 days ago)
+ *
+ * @author hmusum
+ */
public class TenantsMaintainer extends Maintainer {
private final Duration ttlForUnusedTenant;
@@ -21,7 +26,6 @@ public class TenantsMaintainer extends Maintainer {
}
@Override
- // Delete unused tenants that were created more than ttlForUnusedTenant ago
protected void maintain() {
applicationRepository.deleteUnusedTenants(ttlForUnusedTenant, Instant.now());
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ZooKeeperDataMaintainer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ZooKeeperDataMaintainer.java
index c906423d991..625665312fd 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ZooKeeperDataMaintainer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/maintenance/ZooKeeperDataMaintainer.java
@@ -1,5 +1,5 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
- package com.yahoo.vespa.config.server.maintenance;
+package com.yahoo.vespa.config.server.maintenance;
import com.yahoo.path.Path;
import com.yahoo.vespa.config.server.ApplicationRepository;
@@ -9,6 +9,8 @@ import java.time.Duration;
/**
* Removes unused zookeeper data (for now only data used by old file distribution code is removed)
+ *
+ * @author hmusum
*/
public class ZooKeeperDataMaintainer extends Maintainer {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java
index dbb581eb16d..acfd81b33bf 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/LocalSessionRepo.java
@@ -1,7 +1,6 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.session;
-import com.yahoo.concurrent.ThreadFactoryFactory;
import com.yahoo.log.LogLevel;
import com.yahoo.path.Path;
import com.yahoo.transaction.NestedTransaction;
@@ -13,13 +12,10 @@ import com.yahoo.vespa.curator.Curator;
import java.io.File;
import java.io.FilenameFilter;
import java.time.Clock;
-import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
@@ -32,11 +28,7 @@ public class LocalSessionRepo extends SessionRepo<LocalSession> {
private static final Logger log = Logger.getLogger(LocalSessionRepo.class.getName());
private static final FilenameFilter sessionApplicationsFilter = (dir, name) -> name.matches("\\d+");
- private static final Duration delay = Duration.ofMinutes(5);
- // One executor for all instances of this class
- private static final ScheduledExecutorService purgeOldSessionsExecutor =
- new ScheduledThreadPoolExecutor(1, ThreadFactoryFactory.getDaemonThreadFactory("purge-old-sessions"));
private final Map<Long, LocalSessionStateWatcher> sessionStateWatchers = new HashMap<>();
private final long sessionLifetime; // in seconds
private final Clock clock;
@@ -46,7 +38,6 @@ public class LocalSessionRepo extends SessionRepo<LocalSession> {
Clock clock, long sessionLifeTime, Curator curator) {
this(clock, curator, sessionLifeTime);
loadSessions(tenantFileSystemDirs.sessionsPath(), loader);
- purgeOldSessionsExecutor.scheduleWithFixedDelay(this::purgeOldSessions, delay.getSeconds(), delay.getSeconds(), TimeUnit.SECONDS);
}
// Constructor public only for testing
@@ -85,7 +76,6 @@ public class LocalSessionRepo extends SessionRepo<LocalSession> {
}
}
- // public for testing
public void purgeOldSessions() {
log.log(LogLevel.DEBUG, "Purging old sessions");
try {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
index 18e2525f61a..b0320dad88b 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java
@@ -1,11 +1,14 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server;
+import com.google.common.io.Files;
+import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.component.Version;
import com.yahoo.component.Vtag;
import com.yahoo.config.model.application.provider.FilesApplicationPackage;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
+import com.yahoo.config.provision.Deployment;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.Provisioner;
@@ -13,6 +16,7 @@ import com.yahoo.config.provision.TenantName;
import com.yahoo.io.IOUtils;
import com.yahoo.test.ManualClock;
import com.yahoo.text.Utf8;
+import com.yahoo.vespa.config.server.deploy.DeployTester;
import com.yahoo.vespa.config.server.http.SessionHandlerTest;
import com.yahoo.vespa.config.server.http.v2.PrepareResult;
import com.yahoo.vespa.config.server.session.LocalSession;
@@ -31,12 +35,16 @@ import java.io.IOException;
import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Optional;
import java.util.Set;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
@@ -234,6 +242,45 @@ public class ApplicationRepositoryTest {
assertFalse(applicationRepository.deleteApplicationLegacy(applicationId()));
}
+ @Test
+ public void testDeletingInactiveSessions() {
+ ManualClock clock = new ManualClock(Instant.now());
+ ConfigserverConfig configserverConfig = new ConfigserverConfig(new ConfigserverConfig.Builder()
+ .configServerDBDir(Files.createTempDir()
+ .getAbsolutePath())
+ .configDefinitionsDir(Files.createTempDir()
+ .getAbsolutePath())
+ .sessionLifetime(60));
+ DeployTester tester = new DeployTester(configserverConfig, clock);
+ tester.deployApp("src/test/apps/app", "myapp", Instant.now()); // session 2 (numbering starts at 2)
+
+ clock.advance(Duration.ofSeconds(10));
+ Optional<Deployment> deployment2 = tester.redeployFromLocalActive();
+
+ assertTrue(deployment2.isPresent());
+ deployment2.get().activate(); // session 3
+ long activeSessionId = tester.tenant().getApplicationRepo().getSessionIdForApplication(tester.applicationId());
+
+ clock.advance(Duration.ofSeconds(10));
+ Optional<com.yahoo.config.provision.Deployment> deployment3 = tester.redeployFromLocalActive();
+ assertTrue(deployment3.isPresent());
+ deployment3.get().prepare(); // session 4 (not activated)
+
+ LocalSession deployment3session = ((com.yahoo.vespa.config.server.deploy.Deployment) deployment3.get()).session();
+ assertNotEquals(activeSessionId, deployment3session);
+ // No change to active session id
+ assertEquals(activeSessionId, tester.tenant().getApplicationRepo().getSessionIdForApplication(tester.applicationId()));
+ assertEquals(3, tester.tenant().getLocalSessionRepo().listSessions().size());
+
+ clock.advance(Duration.ofHours(1)); // longer than session lifetime
+
+ // All sessions except 3 should be removed after the call to deleteOldSessions
+ tester.applicationRepository().deleteOldSessions();
+ final Collection<LocalSession> sessions = tester.tenant().getLocalSessionRepo().listSessions();
+ assertEquals(1, sessions.size());
+ assertEquals(3, new ArrayList<>(sessions).get(0).getSessionId());
+ }
+
private PrepareResult prepareAndActivateApp(File application) throws IOException {
FilesApplicationPackage appDir = FilesApplicationPackage.fromFile(application);
ApplicationId applicationId = applicationId();
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/RedeployTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/RedeployTest.java
index 9bc9a93e9fa..c6f4df74049 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/RedeployTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/RedeployTest.java
@@ -1,28 +1,21 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.deploy;
-import com.google.common.io.Files;
-import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.config.model.api.ModelFactory;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.Version;
-import com.yahoo.test.ManualClock;
-import com.yahoo.vespa.config.server.session.LocalSession;
import org.junit.Test;
import java.time.Clock;
-import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
/**
@@ -61,43 +54,4 @@ public class RedeployTest {
assertFalse(tester.redeployFromLocalActive(id).isPresent());
}
- @Test
- public void testPurgingOfOldNonActiveDeployments() {
- ManualClock clock = new ManualClock(Instant.now());
- ConfigserverConfig configserverConfig = new ConfigserverConfig(new ConfigserverConfig.Builder()
- .configServerDBDir(Files.createTempDir()
- .getAbsolutePath())
- .configDefinitionsDir(Files.createTempDir()
- .getAbsolutePath())
- .sessionLifetime(60));
- DeployTester tester = new DeployTester(configserverConfig, clock);
- tester.deployApp("src/test/apps/app", "myapp", Instant.now()); // session 2 (numbering starts at 2)
-
- clock.advance(Duration.ofSeconds(10));
- Optional<com.yahoo.config.provision.Deployment> deployment2 = tester.redeployFromLocalActive();
-
- assertTrue(deployment2.isPresent());
- deployment2.get().activate(); // session 3
- long activeSessionId = tester.tenant().getApplicationRepo().getSessionIdForApplication(tester.applicationId());
-
- clock.advance(Duration.ofSeconds(10));
- Optional<com.yahoo.config.provision.Deployment> deployment3 = tester.redeployFromLocalActive();
- assertTrue(deployment3.isPresent());
- deployment3.get().prepare(); // session 4 (not activated)
-
- LocalSession deployment3session = ((Deployment) deployment3.get()).session();
- assertNotEquals(activeSessionId, deployment3session);
- // No change to active session id
- assertEquals(activeSessionId, tester.tenant().getApplicationRepo().getSessionIdForApplication(tester.applicationId()));
- assertEquals(3, tester.tenant().getLocalSessionRepo().listSessions().size());
-
- clock.advance(Duration.ofHours(1)); // longer than session lifetime
-
- // All sessions except 3 should be removed after the call to purgeOldSessions
- tester.tenant().getLocalSessionRepo().purgeOldSessions();
- final Collection<LocalSession> sessions = tester.tenant().getLocalSessionRepo().listSessions();
- assertEquals(1, sessions.size());
- assertEquals(3, new ArrayList<>(sessions).get(0).getSessionId());
- }
-
}