Skip to content

Commit

Permalink
feat: Not touched tags optimization
Browse files Browse the repository at this point in the history
Use special set for storing not yet touched tags.
  • Loading branch information
alexkvak committed Jan 31, 2020
1 parent 3265b62 commit 076e895
Show file tree
Hide file tree
Showing 19 changed files with 3,595 additions and 1,811 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion integration/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = {
},
},
testMatch: ['<rootDir>/tests/**/*.spec.ts'],
testEnvironment: 'jsdom',
testEnvironment: 'node',
transform: {
'^.+\\.ts$': 'ts-jest',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import faker from 'faker';
import { v4 as uuid } from 'uuid';
import Redis, { Redis as RedisType } from 'ioredis';
import RedisStorageAdapter, { CACHE_PREFIX } from '../../src/adapters/redis';
import { ConnectionStatus } from '../../src/connection-status';
import RedisStorageAdapter, { CACHE_PREFIX } from '../../../src/adapters/redis';
import { ConnectionStatus } from '../../../src/connection-status';

let redis: RedisType;
let adapter: RedisStorageAdapter;
Expand Down Expand Up @@ -29,25 +29,25 @@ describe('Redis adapter', () => {

describe('set', () => {
it('set returns true if operation is successful', async () => {
const key = faker.random.uuid();
const value = faker.random.uuid();
const key = uuid();
const value = uuid();

await expect(adapter.set(key, value)).resolves.toEqual(true);
await expect(adapter.get(key)).resolves.toEqual(value);
});

it('set adds cache prefix', async () => {
const key = faker.random.uuid();
const value = faker.random.uuid();
const key = uuid();
const value = uuid();

await adapter.set(key, value);

await expect(redis.get(`${CACHE_PREFIX}:${key}`)).resolves.toEqual(value);
});

it('set calls set with cache prefix and PX mode when expires set', async () => {
const key = faker.random.uuid();
const value = faker.random.uuid();
const key = uuid();
const value = uuid();

await adapter.set(key, value, expireTimeout);
await delay(expireTimeout);
Expand All @@ -57,21 +57,21 @@ describe('Redis adapter', () => {

describe('get', () => {
it('get returns value', async () => {
const key = faker.random.uuid();
const value = faker.random.uuid();
const key = uuid();
const value = uuid();

await expect(adapter.set(key, value));
await expect(adapter.get(key)).resolves.toEqual(value);
});

it('get returns null if key does not set', async () => {
const key = faker.random.uuid();
const key = uuid();
await expect(adapter.get(key)).resolves.toBeNull();
});

it('get adds cache prefix', async () => {
const key = faker.random.uuid();
const value = faker.random.uuid();
const key = uuid();
const value = uuid();
await redis.set(`${CACHE_PREFIX}:${key}`, value);

await expect(adapter.get(key)).resolves.toEqual(value);
Expand All @@ -80,8 +80,8 @@ describe('Redis adapter', () => {

describe('del', () => {
it('del calls del with cache prefix', async () => {
const key = faker.random.uuid();
const value = faker.random.uuid();
const key = uuid();
const value = uuid();

await redis.set(`${CACHE_PREFIX}:${key}`, value);
await adapter.del(key);
Expand All @@ -90,7 +90,7 @@ describe('Redis adapter', () => {
});

it('del does nothing if key does not exist', async () => {
const key = faker.random.uuid();
const key = uuid();
const keyWithPrefix = `${CACHE_PREFIX}:${key}`;

await expect(redis.get(keyWithPrefix)).resolves.toBeNull();
Expand All @@ -101,14 +101,14 @@ describe('Redis adapter', () => {

describe('acquireLock', () => {
it('acquireLock returns true if lock is successful', async () => {
const key = faker.random.uuid();
const key = uuid();
const lockResult = await adapter.acquireLock(key);

expect(lockResult).toEqual(true);
});

it('acquireLock calls set with generated key name and in NX mode', async () => {
const key = faker.random.uuid();
const key = uuid();
const lockResult = await adapter.acquireLock(key);

expect(lockResult).toEqual(true);
Expand All @@ -120,21 +120,21 @@ describe('Redis adapter', () => {

describe('releaseLock', () => {
it('releaseLock returns false if lock does not exist', async () => {
const key = faker.random.uuid();
const key = uuid();
const releaseLockResult = await adapter.releaseLock(key);
expect(releaseLockResult).toEqual(false);
});

it('releaseLock delete lock record with appropriate key, and returns true on success', async () => {
const key = faker.random.uuid();
const key = uuid();

await redis.set(`${key}_lock`, '');
const releaseLockResult = await adapter.releaseLock(key);
expect(releaseLockResult).toEqual(true);
});

it('releaseLock delete lock record set by acquireLock', async () => {
const key = faker.random.uuid();
const key = uuid();

await adapter.acquireLock(key);

Expand All @@ -144,14 +144,14 @@ describe('Redis adapter', () => {

describe('isLockExists', () => {
it('isLockExists returns true if lock exists', async () => {
const key = faker.random.uuid();
const key = uuid();

await adapter.acquireLock(key);
await expect(adapter.isLockExists(key)).resolves.toEqual(true);
});

it('isLockExists returns false if lock does not exist', async () => {
const key = faker.random.uuid();
const key = uuid();

await expect(adapter.isLockExists(key)).resolves.toEqual(false);
});
Expand All @@ -160,8 +160,8 @@ describe('Redis adapter', () => {
describe('mset', () => {
it('mset sets values', async () => {
const values = new Map([
[faker.random.uuid(), faker.random.uuid()],
[faker.random.uuid(), faker.random.uuid()]
[uuid(), uuid()],
[uuid(), uuid()]
]);
await adapter.mset(values);

Expand All @@ -178,8 +178,8 @@ describe('Redis adapter', () => {
describe('mget', () => {
it('mget gets values', async () => {
const values = new Map([
[faker.random.uuid(), faker.random.uuid()],
[faker.random.uuid(), faker.random.uuid()]
[uuid(), uuid()],
[uuid(), uuid()]
]);

for (const [key, value] of values.entries()) {
Expand All @@ -193,21 +193,116 @@ describe('Redis adapter', () => {

it('mget returns null for non-existing keys', async () => {
const values = new Map([
[faker.random.uuid(), faker.random.uuid()],
[faker.random.uuid(), faker.random.uuid()]
[uuid(), uuid()],
[uuid(), uuid()]
]);

for (const [key, value] of values.entries()) {
await redis.set(`${CACHE_PREFIX}:${key}`, value);
}

const keys = Array.from(values.keys());
const nonExistingKey = faker.random.uuid();
const nonExistingKey = uuid();
keys.push(nonExistingKey);

const result = await adapter.mget(keys);

expect(result).toEqual([...Array.from(values.values()), null]);
});

it('fails if empty values passed', async () => {
await expect(adapter.mget([])).rejects.toThrowError('wrong number of arguments for \'mget\' command');
});
});

describe('getSetValues', () => {
it('returns values', async () => {
const key = uuid();
const value = uuid();

await redis.sadd(`${CACHE_PREFIX}:${key}`, value);

await expect(adapter.getSetValues(key)).resolves.toEqual(new Set([value]));
});

it('returns empty set for unknown key', async () => {
const key = uuid();

await expect(adapter.getSetValues(key)).resolves.toEqual(new Set([]));
});
});

describe('addToSet', () => {
it('adds value to set', async () => {
const key = uuid();
const value = uuid();

await adapter.addToSet(key, [value]);

await expect(redis.smembers(`${CACHE_PREFIX}:${key}`)).resolves.toEqual([value]);
});

it('fails if empty values passed', async () => {
await expect(adapter.addToSet(uuid(), [])).rejects.toThrowError('wrong number of arguments for \'sadd\' command');
});

it('does not fail if set does not exist', async () => {
await expect(adapter.addToSet(uuid(), [uuid()])).resolves.toBeUndefined();
});
});

describe('deleteFromSet', () => {
it('deletes value from set', async () => {
const key = uuid();
const value = uuid();

await redis.sadd(`${CACHE_PREFIX}:${key}`, value);

await adapter.deleteFromSet(key, [value]);

await expect(redis.smembers(`${CACHE_PREFIX}:${key}`)).resolves.toEqual([]);
});

it('fails if empty values passed', async () => {
const key = uuid();
const value = uuid();

await redis.sadd(`${CACHE_PREFIX}:${key}`, value);

await expect(adapter.deleteFromSet(key, [])).rejects.toThrowError('wrong number of arguments for \'srem\' command');
});

it('does not fail if set does not exist', async () => {
await expect(adapter.deleteFromSet(uuid(), [uuid()])).resolves.toBeUndefined();
});
});

describe('intersectWithSet', () => {
it('fails if empty values passed', async () => {
await expect(adapter.intersectWithSet(uuid(), [])).rejects.toThrowError('wrong number of arguments for \'sadd\' command');
});

it('does not fail if set does not exist', async () => {
await expect(adapter.intersectWithSet(uuid(), [uuid()])).resolves.toEqual(new Set());
});

it('returns original set if it does not intersect with passed one', async () => {
const key = uuid();
const value = uuid();

await redis.sadd(`${CACHE_PREFIX}:${key}`, value);

await expect(adapter.intersectWithSet(key, [uuid()])).resolves.toEqual(new Set());
});

it('returns non-empty intersection', async () => {
const key = uuid();
const value = uuid();

await redis.sadd(`${CACHE_PREFIX}:${key}`, value);
await redis.sadd(`${CACHE_PREFIX}:${uuid()}`, uuid());

await expect(adapter.intersectWithSet(key, [value, uuid()])).resolves.toEqual(new Set([value]));
});
});
});

0 comments on commit 076e895

Please sign in to comment.