From 3db4437a354fcfeacd5ad532bd0a3d064c03cdfa Mon Sep 17 00:00:00 2001 From: Sep Taheri Date: Tue, 4 Mar 2025 15:00:40 +0000 Subject: [PATCH 1/4] Fix cache key --- CHANGELOG.md | 15 ++++++++++++++- gradle.properties | 2 +- .../transferwise/tasks/helpers/sql/CacheKey.java | 6 +++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 929214bb..4fbc9153 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.50.2 - 2025/03/04 + +- Update CacheKey to support weights up to 32. + +## 1.50.1 - 2025/02/25 + +- Remove TagSet for the cancellation flow specifically for bucket metrics as it is not used. + ## 1.50.0 - 2025/02/12 ### Changed -- Added support to cancel tasks in waiting state. +- Added support to cancel tasks in waiting state, by introducing a new Enum for TaskStatus. + +If you have an Enum for TaskStatus in DB, you will need to add a new value 'CANCELLED' to it. +```sql +ALTER TYPE status ADD VALUE 'CANCELLED'; +``` ## 1.49.0 - 2025/01/08 diff --git a/gradle.properties b/gradle.properties index b47c664c..ff73234b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ -version=1.50.1 +version=1.50.2 org.gradle.internal.http.socketTimeout=120000 diff --git a/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java b/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java index 62723c55..34416696 100644 --- a/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java +++ b/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java @@ -4,12 +4,12 @@ import lombok.EqualsAndHashCode; /** - * A cache key, each weight is expected to be less than 8 (3 bits). + * A cache key, each weight is expected to be less than 32 (5 bits). */ @EqualsAndHashCode public final class CacheKey { - private static final int LEFT_SHIFT = 3; + private static final int LEFT_SHIFT = 5; private static final int MAX_WEIGHT_EXCLUSIVE = 1 << LEFT_SHIFT; private final String name; @@ -27,4 +27,4 @@ public CacheKey(String name, int weight1, int weight2) { int weights = (1 << LEFT_SHIFT) + weight1; this.weightsSum = (weights << LEFT_SHIFT) + weight2; } -} +} \ No newline at end of file From 106cda737f65abf52aa7aeb4795152f4221976e9 Mon Sep 17 00:00:00 2001 From: Sep Taheri Date: Tue, 4 Mar 2025 16:19:42 +0000 Subject: [PATCH 2/4] add tests --- CHANGELOG.md | 2 +- .../tasks/test/dao/JdbcTestTaskDao.java | 8 ++--- .../transferwise/tasks/dao/JdbcTaskDao.java | 12 +++---- .../{CacheKey.java => WeightedCacheKey.java} | 6 ++-- .../helpers/sql/WeightedCacheKeyTest.java | 36 +++++++++++++++++++ .../management/dao/JdbcManagementTaskDao.java | 6 ++-- 6 files changed, 53 insertions(+), 17 deletions(-) rename tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/{CacheKey.java => WeightedCacheKey.java} (82%) create mode 100644 tw-tasks-core/src/test/java/com/transferwise/tasks/helpers/sql/WeightedCacheKeyTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fbc9153..0a5e2e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 1.50.2 - 2025/03/04 -- Update CacheKey to support weights up to 32. +- Update CacheKey to support weights up to 32 (5 bits) from previously 8 (3 bits). ## 1.50.1 - 2025/02/25 diff --git a/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java b/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java index cfdc93bb..b2054a46 100644 --- a/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java +++ b/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java @@ -11,7 +11,7 @@ import com.transferwise.tasks.domain.TaskContext; import com.transferwise.tasks.domain.TaskStatus; import com.transferwise.tasks.helpers.sql.ArgumentPreparedStatementSetter; -import com.transferwise.tasks.helpers.sql.CacheKey; +import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.helpers.sql.SqlHelper; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -76,7 +76,7 @@ private static class Queries { private final JdbcTemplate jdbcTemplate; private final Queries queries; private final ITaskSqlMapper sqlMapper; - private final ConcurrentHashMap sqlCache; + private final ConcurrentHashMap sqlCache; private final ITaskDaoDataSerializer taskDataSerializer; private final JsonConverter jsonConverter = new DefaultJsonConverter(new ObjectMapper()); @@ -102,7 +102,7 @@ public void deleteTasks(String type, String subType, TaskStatus... statuses) { } String query = sqlCache.computeIfAbsent( - new CacheKey( + new WeightedCacheKey( Queries.GET_ID_AND_VERSION_BY_TYPE_AND_SUBTYPE_AND_STATUS, subType == null ? 0 : 1, ArrayUtils.getLength(statuses) @@ -181,7 +181,7 @@ public List findTasksByTypeSubTypeAndStatus(String type, String subType, T } String sql = sqlCache.computeIfAbsent( - new CacheKey( + new WeightedCacheKey( Queries.GET_TASKS_BY_TYPE_AND_STATUS_AND_SUB_TYPE, subType == null ? 0 : 1, ArrayUtils.getLength(statuses) diff --git a/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java b/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java index 3b074e78..58d06edb 100644 --- a/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java +++ b/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java @@ -18,7 +18,7 @@ import com.transferwise.tasks.domain.TaskVersionId; import com.transferwise.tasks.helpers.ICoreMetricsTemplate; import com.transferwise.tasks.helpers.sql.ArgumentPreparedStatementSetter; -import com.transferwise.tasks.helpers.sql.CacheKey; +import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.helpers.sql.SqlHelper; import com.transferwise.tasks.utils.TimeUtils; import java.nio.charset.StandardCharsets; @@ -80,7 +80,7 @@ public abstract class JdbcTaskDao implements ITaskDao, InitializingBean { @Autowired protected ObjectMapper objectMapper; - private final ConcurrentHashMap sqlCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap sqlCache = new ConcurrentHashMap<>(); private final JdbcTemplate jdbcTemplate; private final ITaskSqlMapper sqlMapper; @@ -531,7 +531,7 @@ public DeleteFinishedOldTasksResult deleteOldTasks(TaskStatus taskStatus, Durati final int currentProcessedIdsCount = processedIdsCount; if (tasksProperties.isParanoidTasksCleaning()) { - var tasksDeleteLockSql = sqlCache.computeIfAbsent(new CacheKey(LOCK_TASKS_FOR_DELETE_SQL, b), + var tasksDeleteLockSql = sqlCache.computeIfAbsent(new WeightedCacheKey(LOCK_TASKS_FOR_DELETE_SQL, b), k -> SqlHelper.expandParametersList(lockTasksForDeleteBatchesSql, bucketSize) ); @@ -562,7 +562,7 @@ public DeleteFinishedOldTasksResult deleteOldTasks(TaskStatus taskStatus, Durati } String tasksDeleteSql = sqlCache.computeIfAbsent( - new CacheKey(DELETE_TASKS_BY_ID_BATCHES, b), + new WeightedCacheKey(DELETE_TASKS_BY_ID_BATCHES, b), k -> SqlHelper.expandParametersList(deleteTasksByIdBatchesSql, bucketSize) ); @@ -580,7 +580,7 @@ public DeleteFinishedOldTasksResult deleteOldTasks(TaskStatus taskStatus, Durati }); var uniqueTaskKeysDeleteSql = sqlCache.computeIfAbsent( - new CacheKey(DELETE_UNIQUE_TASK_KEYS_BY_ID_BATCHES, b), + new WeightedCacheKey(DELETE_UNIQUE_TASK_KEYS_BY_ID_BATCHES, b), k -> SqlHelper.expandParametersList(deleteUniqueTaskKeysByIdBatchesSql, bucketSize) ); @@ -598,7 +598,7 @@ public DeleteFinishedOldTasksResult deleteOldTasks(TaskStatus taskStatus, Durati }); var taskDatasDeleteSql = sqlCache.computeIfAbsent( - new CacheKey(DELETE_TASK_DATAS_BY_ID_BATCHES, b), + new WeightedCacheKey(DELETE_TASK_DATAS_BY_ID_BATCHES, b), k -> SqlHelper.expandParametersList(deleteTaskDatasByIdBatchesSql, bucketSize) ); diff --git a/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java b/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/WeightedCacheKey.java similarity index 82% rename from tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java rename to tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/WeightedCacheKey.java index 34416696..6a8aa102 100644 --- a/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/CacheKey.java +++ b/tw-tasks-core/src/main/java/com/transferwise/tasks/helpers/sql/WeightedCacheKey.java @@ -7,7 +7,7 @@ * A cache key, each weight is expected to be less than 32 (5 bits). */ @EqualsAndHashCode -public final class CacheKey { +public final class WeightedCacheKey { private static final int LEFT_SHIFT = 5; private static final int MAX_WEIGHT_EXCLUSIVE = 1 << LEFT_SHIFT; @@ -15,13 +15,13 @@ public final class CacheKey { private final String name; private final int weightsSum; - public CacheKey(String name, int weight1) { + public WeightedCacheKey(String name, int weight1) { Preconditions.checkArgument(weight1 < MAX_WEIGHT_EXCLUSIVE); this.name = name; this.weightsSum = (1 << LEFT_SHIFT) + weight1; } - public CacheKey(String name, int weight1, int weight2) { + public WeightedCacheKey(String name, int weight1, int weight2) { Preconditions.checkArgument(weight1 < MAX_WEIGHT_EXCLUSIVE && weight2 < MAX_WEIGHT_EXCLUSIVE); this.name = name; int weights = (1 << LEFT_SHIFT) + weight1; diff --git a/tw-tasks-core/src/test/java/com/transferwise/tasks/helpers/sql/WeightedCacheKeyTest.java b/tw-tasks-core/src/test/java/com/transferwise/tasks/helpers/sql/WeightedCacheKeyTest.java new file mode 100644 index 00000000..f1cb3f01 --- /dev/null +++ b/tw-tasks-core/src/test/java/com/transferwise/tasks/helpers/sql/WeightedCacheKeyTest.java @@ -0,0 +1,36 @@ +package com.transferwise.tasks.helpers.sql; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class WeightedCacheKeyTest { + + @Test + void testSingleWeightConstructorWithInvalidWeight() { + assertThrows(IllegalArgumentException.class, () -> new WeightedCacheKey("testKey", 32)); + } + + @Test + void testDoubleWeightConstructorWithInvalidWeight() { + assertThrows(IllegalArgumentException.class, () -> new WeightedCacheKey("testKey", 10, 32)); + } + + @Test + void testEqualsAndHashCode() { + WeightedCacheKey cacheKey1 = new WeightedCacheKey("testKey", 10); + WeightedCacheKey cacheKey2 = new WeightedCacheKey("testKey", 10); + assertEquals(cacheKey1, cacheKey2); + assertEquals(cacheKey1.hashCode(), cacheKey2.hashCode()); + + WeightedCacheKey cacheKey3 = new WeightedCacheKey("testKey", 8); + assertNotEquals(cacheKey1, cacheKey3); + assertNotEquals(cacheKey1.hashCode(), cacheKey3.hashCode()); + + WeightedCacheKey cacheKey4 = new WeightedCacheKey("no", 10); + assertNotEquals(cacheKey1, cacheKey4); + assertNotEquals(cacheKey1.hashCode(), cacheKey4.hashCode()); + } +} \ No newline at end of file diff --git a/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java b/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java index 6ffe2ab0..14ceda00 100644 --- a/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java +++ b/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java @@ -13,7 +13,7 @@ import com.transferwise.tasks.domain.FullTaskRecord; import com.transferwise.tasks.domain.TaskStatus; import com.transferwise.tasks.helpers.sql.ArgumentPreparedStatementSetter; -import com.transferwise.tasks.helpers.sql.CacheKey; +import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.helpers.sql.SqlHelper; import com.transferwise.tasks.management.dao.JdbcManagementTaskDao.Queries.QueryBuilder; import com.transferwise.tasks.management.dao.JdbcManagementTaskDao.Queries.QueryBuilder.Op; @@ -146,7 +146,7 @@ enum Op { private final JdbcTemplate jdbcTemplate; private final Queries queries; private final ITaskSqlMapper sqlMapper; - private final ConcurrentHashMap queriesCache; + private final ConcurrentHashMap queriesCache; private final ITaskDaoDataSerializer taskDataSerializer; public JdbcManagementTaskDao(DataSource dataSource, ITwTaskTables tables, ITaskSqlMapper sqlMapper, ITaskDaoDataSerializer taskDataSerializer) { @@ -278,7 +278,7 @@ public List getTasks(List taskIds) { int questionsCount = questionBuckets[bucketId]; String sql = queriesCache.computeIfAbsent( - new CacheKey(Queries.GET_TASKS, bucketId), + new WeightedCacheKey(Queries.GET_TASKS, bucketId), k -> SqlHelper.expandParametersList(queries.getTasks, questionsCount) ); From b3f28fd72aeaf6a084c2547e203d77946b22894e Mon Sep 17 00:00:00 2001 From: Sep Taheri Date: Tue, 4 Mar 2025 16:33:33 +0000 Subject: [PATCH 3/4] CheckStyle --- .../src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java b/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java index 58d06edb..79265641 100644 --- a/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java +++ b/tw-tasks-core/src/main/java/com/transferwise/tasks/dao/JdbcTaskDao.java @@ -18,8 +18,8 @@ import com.transferwise.tasks.domain.TaskVersionId; import com.transferwise.tasks.helpers.ICoreMetricsTemplate; import com.transferwise.tasks.helpers.sql.ArgumentPreparedStatementSetter; -import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.helpers.sql.SqlHelper; +import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.utils.TimeUtils; import java.nio.charset.StandardCharsets; import java.sql.Connection; From 079abecd5d1ac20cf377581469e69f8b5e6d9efb Mon Sep 17 00:00:00 2001 From: Sep Taheri Date: Tue, 4 Mar 2025 16:39:21 +0000 Subject: [PATCH 4/4] CheckStyle --- .../java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java | 2 +- .../tasks/management/dao/JdbcManagementTaskDao.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java b/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java index b2054a46..acc12bb7 100644 --- a/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java +++ b/tw-tasks-core-test/src/main/java/com/transferwise/tasks/test/dao/JdbcTestTaskDao.java @@ -11,8 +11,8 @@ import com.transferwise.tasks.domain.TaskContext; import com.transferwise.tasks.domain.TaskStatus; import com.transferwise.tasks.helpers.sql.ArgumentPreparedStatementSetter; -import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.helpers.sql.SqlHelper; +import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; diff --git a/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java b/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java index 14ceda00..366de300 100644 --- a/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java +++ b/tw-tasks-management/src/main/java/com/transferwise/tasks/management/dao/JdbcManagementTaskDao.java @@ -13,8 +13,8 @@ import com.transferwise.tasks.domain.FullTaskRecord; import com.transferwise.tasks.domain.TaskStatus; import com.transferwise.tasks.helpers.sql.ArgumentPreparedStatementSetter; -import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.helpers.sql.SqlHelper; +import com.transferwise.tasks.helpers.sql.WeightedCacheKey; import com.transferwise.tasks.management.dao.JdbcManagementTaskDao.Queries.QueryBuilder; import com.transferwise.tasks.management.dao.JdbcManagementTaskDao.Queries.QueryBuilder.Op; import com.transferwise.tasks.utils.TimeUtils;