Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make locks dynamic based on TTL of lock table #587

Merged
merged 14 commits into from
Oct 20, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.metadata.Node;
import com.ericsson.bss.cassandra.ecchronos.application.config.Config;
import com.ericsson.bss.cassandra.ecchronos.application.config.lockfactory.CasLockFactoryConfig;
import com.ericsson.bss.cassandra.ecchronos.connection.JmxConnectionProvider;
import com.ericsson.bss.cassandra.ecchronos.connection.NativeConnectionProvider;
import com.ericsson.bss.cassandra.ecchronos.connection.StatementDecorator;
Expand Down Expand Up @@ -75,11 +76,17 @@ public ECChronosInternals(final Config configuration,
.withJmxProxyFactory(myJmxProxyFactory)
.build();

CasLockFactoryConfig casLockFactoryConfig = configuration.getLockFactory()
.getCasLockFactoryConfig();

myLockFactory = CASLockFactory.builder()
.withNativeConnectionProvider(nativeConnectionProvider)
.withHostStates(myHostStatesImpl)
.withStatementDecorator(statementDecorator)
.withKeyspaceName(configuration.getLockFactory().getCasLockFactoryConfig().getKeyspaceName())
.withKeyspaceName(casLockFactoryConfig.getKeyspaceName())
.withLockTimeInSeconds(casLockFactoryConfig.getLockTimeInSeconds())
.withLockUpdateTimeInSeconds(casLockFactoryConfig.getLockUpdateTimeInSeconds())
.withCacheExpiryInSeconds(casLockFactoryConfig.getFailureCacheExpiryTimeInSeconds())
.build();

Node node = nativeConnectionProvider.getLocalNode();
Expand Down Expand Up @@ -221,9 +228,9 @@ public void remainingRepairTime(final TableReference tableReference, final long

@Override
public void repairSession(final TableReference tableReference,
final long timeTaken,
final TimeUnit timeUnit,
final boolean successful)
final long timeTaken,
final TimeUnit timeUnit,
final boolean successful)
{
if (LOG.isTraceEnabled())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,54 @@

public class CasLockFactoryConfig
{
private String myKeyspaceName = "ecchronos";
private static final long DEFAULT_LOCK_TIME_IN_SECONDS = 600L;
private static final long DEFAULT_LOCK_UPDATE_TIME_IN_SECONDS = 60L;
private static final long DEFAULT_EXPIRY_TIME_IN_SECONDS = 30L;
private static final String DEFAULT_KEYSPACE_NAME = "ecchronos";
private String myKeyspaceName = DEFAULT_KEYSPACE_NAME;
private long myLockTimeInSeconds = DEFAULT_LOCK_TIME_IN_SECONDS;
private long myLockUpdateTimeInSeconds = DEFAULT_LOCK_UPDATE_TIME_IN_SECONDS;
private long myExpiryTimeInSeconds = DEFAULT_EXPIRY_TIME_IN_SECONDS;

public final long getLockTimeInSeconds()
{
return myLockTimeInSeconds;
}

@JsonProperty ("lock_time_in_seconds")
public final void setLockTimeInSeconds(final long lockTimeInSeconds)
{
myLockTimeInSeconds = lockTimeInSeconds;
}

public final long getLockUpdateTimeInSeconds()
{
return myLockUpdateTimeInSeconds;
}

@JsonProperty ("lock_update_time_in_seconds")
public final void setLockUpdateTimeInSeconds(final long lockUpdateTimeInSeconds)
{
myLockUpdateTimeInSeconds = lockUpdateTimeInSeconds;
}

public final long getFailureCacheExpiryTimeInSeconds()
{
return myExpiryTimeInSeconds;
}

@JsonProperty ("cache_expiry_time_in_seconds")
public final void setFailureCacheExpiryTimeInSeconds(final long expiryTimeInSeconds)
{
myExpiryTimeInSeconds = expiryTimeInSeconds;
}

@JsonProperty("keyspace")
public final String getKeyspaceName()
{
return myKeyspaceName;
}

@JsonProperty("keyspace")
@JsonProperty ("keyspace")
masokol marked this conversation as resolved.
Show resolved Hide resolved
public final void setKeyspaceName(final String keyspaceName)
{
myKeyspaceName = keyspaceName;
Expand Down
17 changes: 17 additions & 0 deletions application/src/main/resources/ecc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,23 @@ lock_factory:
## The keyspace used for the CAS lock factory tables.
##
keyspace: ecchronos
##
## The duration for which the lock is held, in seconds
## and directly tied with the TTL(time to live)
## of 'ecchronos.lock' table.
##
lock_time_in_seconds: 600
SajidRiaz138 marked this conversation as resolved.
Show resolved Hide resolved
##
## The interval at which the lock is updated, in seconds
##
lock_update_time_in_seconds: 60
##
## The number of seconds until the lock failure cache expires.
## If an attempt to secure a lock is unsuccessful,
## all subsequent attempts will be failed until
## the cache expiration time is reached.
SajidRiaz138 marked this conversation as resolved.
Show resolved Hide resolved
##
cache_expiry_time_in_seconds: 30

run_policy:
time_based:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2023 Telefonaktiebolaget LM Ericsson
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ericsson.bss.cassandra.ecchronos.application.config;

import com.ericsson.bss.cassandra.ecchronos.application.config.lockfactory.CasLockFactoryConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

import static org.assertj.core.api.Assertions.assertThat;

public class TestCasLockFactoryConfig
{
@Test
public void testCasLockFactoryConfigWithProvidedValue() throws IOException
{
CasLockFactoryConfig casLockFactoryConfig = getCasLockFactoryConfig("all_set.yml");
assertThat(casLockFactoryConfig.getKeyspaceName()).isEqualTo("ecc");
assertThat(casLockFactoryConfig.getLockTimeInSeconds()).isEqualTo(800L);
assertThat(casLockFactoryConfig.getLockUpdateTimeInSeconds()).isEqualTo(80L);
assertThat(casLockFactoryConfig.getFailureCacheExpiryTimeInSeconds()).isEqualTo(100L);
}

@Test
public void testCasLockFactoryConfigDefaultValue() throws IOException
{
CasLockFactoryConfig casLockFactoryConfig = getCasLockFactoryConfig("nothing_set.yml");
assertThat(casLockFactoryConfig.getKeyspaceName()).isEqualTo("ecchronos");
assertThat(casLockFactoryConfig.getLockTimeInSeconds()).isEqualTo(600L);
assertThat(casLockFactoryConfig.getLockUpdateTimeInSeconds()).isEqualTo(60L);
assertThat(casLockFactoryConfig.getFailureCacheExpiryTimeInSeconds()).isEqualTo(30L);

}

private CasLockFactoryConfig getCasLockFactoryConfig(final String fileName) throws IOException
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
File file = new File(classLoader.getResource(fileName).getFile());
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
Config config = mapper.readValue(file, Config.class);
return config.getLockFactory().getCasLockFactoryConfig();
}
}
4 changes: 4 additions & 0 deletions application/src/test/resources/all_set.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ statistics:
lock_factory:
cas:
keyspace: ecc
lock_time_in_seconds: 800
lock_update_time_in_seconds: 80
cache_expiry_time_in_seconds: 100


run_policy:
time_based:
Expand Down
SajidRiaz138 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
public class CASLockFactoryService implements LockFactory
{
private static final String DEFAULT_KEYSPACE_NAME = "ecchronos";
SajidRiaz138 marked this conversation as resolved.
Show resolved Hide resolved
private static final long DEFAULT_LOCK_TIME_IN_SECONDS = 600L;
private static final long DEFAULT_UPDATE_TIME_IN_SECONDS = 60L;

@Reference(service = NativeConnectionProvider.class,
cardinality = ReferenceCardinality.MANDATORY,
Expand All @@ -64,6 +66,8 @@ public final synchronized void activate(final Configuration configuration)
.withHostStates(myHostStates)
.withStatementDecorator(myStatementDecorator)
.withKeyspaceName(configuration.keyspaceName())
.withLockTimeInSeconds(configuration.lockTimeInSeconds())
.withLockUpdateTimeInSeconds(configuration.lockUpdateTimeInSeconds())
.build();
}

Expand Down Expand Up @@ -101,5 +105,13 @@ public final boolean sufficientNodesForLocking(final String dataCenter, final St
@AttributeDefinition(name = "The lock factory keyspace to use",
description = "The name of the keyspace containing the lock factory tables")
String keyspaceName() default DEFAULT_KEYSPACE_NAME;
@AttributeDefinition(name = "Lock Time",
description = "The duration for which the lock is held, in seconds")
long lockTimeInSeconds() default DEFAULT_LOCK_TIME_IN_SECONDS;

@AttributeDefinition(name = "Lock Update Time",
description = "The interval at which the lock is updated, in seconds")
long lockUpdateTimeInSeconds() default DEFAULT_UPDATE_TIME_IN_SECONDS;

}
}
Loading