Skip to content
This repository was archived by the owner on Dec 1, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 (5 bits) from previously 8 (3 bits).

## 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

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version=1.50.1
version=1.50.2
org.gradle.internal.http.socketTimeout=120000
Original file line number Diff line number Diff line change
Expand Up @@ -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.CacheKey;
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;
Expand Down Expand Up @@ -76,7 +76,7 @@ private static class Queries {
private final JdbcTemplate jdbcTemplate;
private final Queries queries;
private final ITaskSqlMapper sqlMapper;
private final ConcurrentHashMap<CacheKey, String> sqlCache;
private final ConcurrentHashMap<WeightedCacheKey, String> sqlCache;
private final ITaskDaoDataSerializer taskDataSerializer;
private final JsonConverter jsonConverter = new DefaultJsonConverter(new ObjectMapper());

Expand All @@ -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)
Expand Down Expand Up @@ -181,7 +181,7 @@ public List<Task> 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.CacheKey;
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;
Expand Down Expand Up @@ -80,7 +80,7 @@ public abstract class JdbcTaskDao implements ITaskDao, InitializingBean {
@Autowired
protected ObjectMapper objectMapper;

private final ConcurrentHashMap<CacheKey, String> sqlCache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<WeightedCacheKey, String> sqlCache = new ConcurrentHashMap<>();

private final JdbcTemplate jdbcTemplate;
private final ITaskSqlMapper sqlMapper;
Expand Down Expand Up @@ -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)
);

Expand Down Expand Up @@ -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)
);

Expand All @@ -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)
);

Expand All @@ -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)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
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 {
public final class WeightedCacheKey {

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;
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;
this.weightsSum = (weights << LEFT_SHIFT) + weight2;
}
}
}
Original file line number Diff line number Diff line change
@@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.CacheKey;
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;
Expand Down Expand Up @@ -146,7 +146,7 @@ enum Op {
private final JdbcTemplate jdbcTemplate;
private final Queries queries;
private final ITaskSqlMapper sqlMapper;
private final ConcurrentHashMap<CacheKey, String> queriesCache;
private final ConcurrentHashMap<WeightedCacheKey, String> queriesCache;
private final ITaskDaoDataSerializer taskDataSerializer;

public JdbcManagementTaskDao(DataSource dataSource, ITwTaskTables tables, ITaskSqlMapper sqlMapper, ITaskDaoDataSerializer taskDataSerializer) {
Expand Down Expand Up @@ -278,7 +278,7 @@ public List<FullTaskRecord> getTasks(List<UUID> 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)
);

Expand Down