Skip to content

Commit

Permalink
Merge pull request #3 from tiramisulabs/fix/redis
Browse files Browse the repository at this point in the history
Update cooldown, fix redis adapter
  • Loading branch information
MARCROCK22 authored Sep 1, 2024
2 parents 02e4e51 + c369fe2 commit 66e8dfd
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 49 deletions.
3 changes: 2 additions & 1 deletion packages/cooldown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"dev": "tsc --watch",
"build": "tsc",
"lint": "biome lint --write ./src",
"format": "biome format --write ./src"
"format": "biome format --write ./src",
"test": "node --test ./test/*"
},
"devDependencies": {
"@types/node": "^22.4.0",
Expand Down
76 changes: 39 additions & 37 deletions packages/cooldown/src/manager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { UsingClient } from 'seyfert';
import { type CooldownData, type CooldownDataInsert, Cooldowns, type CooldownType } from './resource';
import { getMilliseconds } from './clock';
import { fakePromise } from 'seyfert/lib/common';

export class CooldownManager {
resource: Cooldowns;
Expand All @@ -27,16 +28,18 @@ export class CooldownManager {
const data = this.getData(name);
if (!data) return false;

const cooldown = this.resource.get(`${name}:${data.type}:${target}`);
if (!cooldown) {
this.set(name, target, { type: data.type, interval: data.interval, remaining: data.refill - data.tokens });
return false;
}
return fakePromise(this.resource.get(`${name}:${data.type}:${target}`)).then(cooldown => {
if (!cooldown) {
return fakePromise(
this.set(name, target, { type: data.type, interval: data.interval, remaining: data.refill - data.tokens }),
).then(() => false);
}

const remaining = cooldown.remaining - data.tokens;
const remaining = cooldown.remaining - data.tokens;

if (remaining <= 0) return true;
return false;
if (remaining <= 0) return true;
return false;
});
}

/**
Expand All @@ -50,21 +53,22 @@ export class CooldownManager {
const data = this.getData(name);
if (!data) return;

const cooldown = this.resource.get(`${name}:${data.type}:${target}`);
if (!cooldown) {
this.set(name, target, {
type: data.type,
interval: data.interval,
remaining: data.refill - (tokens ?? data.tokens),
return fakePromise(this.resource.get(`${name}:${data.type}:${target}`)).then(cooldown => {
if (!cooldown) {
return fakePromise(
this.set(name, target, {
type: data.type,
interval: data.interval,
remaining: data.refill - (tokens ?? data.tokens),
}),
).then(() => true);
}

return fakePromise(this.drip(name, target, data, cooldown)).then(drip => {
if (drip.remaining >= data.tokens) return false;
return true;
});
return true;
}

const drip = this.drip(name, target, data, cooldown);

if (drip.remaining <= 0) return false;

return true;
});
}

/**
Expand All @@ -79,18 +83,17 @@ export class CooldownManager {

const refill = tokens ?? data.refill;

const cooldown = this.resource.get(`${name}:${data.type}:${target}`);
if (!cooldown) {
this.set(name, target, {
type: data.type,
interval: data.interval,
remaining: refill,
});
return true;
}

this.set(name, target, { type: data.type, interval: data.interval, remaining: refill });
return true;
return fakePromise(this.resource.get(`${name}:${data.type}:${target}`)).then(cooldown => {
if (!cooldown) {
return fakePromise(
this.set(name, target, { type: data.type, interval: data.interval, remaining: refill }),
).then(() => true);
}

return fakePromise(this.set(name, target, { type: data.type, interval: data.interval, remaining: refill })).then(
() => true,
);
});
}

/**
Expand All @@ -100,7 +103,7 @@ export class CooldownManager {
* @param data - The cooldown data to set
*/
set(name: string, target: string, data: CooldownDataInsert & { type: `${CooldownType}` }) {
this.resource.set(`${name}:${data.type}:${target}`, data);
return fakePromise(this.resource.set(`${name}:${data.type}:${target}`, data)).then(() => {});
}

/**
Expand All @@ -119,8 +122,7 @@ export class CooldownManager {
const dripAmount = deltaMS * (props.refill / props.interval);
data.remaining = Math.min(data.remaining + dripAmount, props.refill);
const result = { type: props.type, interval: props.interval, remaining: data.remaining };
this.set(name, target, result);
return result;
return fakePromise(this.set(name, target, result)).then(() => result);
}
}

Expand Down
5 changes: 3 additions & 2 deletions packages/redis-adapter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
"dev": "tsc --watch",
"build": "tsc",
"lint": "biome lint --write ./src",
"format": "biome format --write ./src"
"format": "biome format --write ./src",
"test": "node --test ./test/*"
},
"dependencies": {
"ioredis": "^5.4.1",
"iovalkey": "^0.1.0",
"seyfert": "^2.0.0"
},
"devDependencies": {
Expand Down
12 changes: 9 additions & 3 deletions packages/redis-adapter/src/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { RedisOptions } from 'ioredis';
import type { RedisOptions } from 'iovalkey';
import type { Adapter } from 'seyfert/lib/cache';
import { Redis } from 'ioredis';
import { Redis } from 'iovalkey';

interface RedisAdapterOptions {
namespace?: string;
Expand Down Expand Up @@ -63,7 +63,12 @@ export class RedisAdapter implements Adapter {
pipeline.hgetall(this.buildKey(key));
}

return (await pipeline.exec())?.filter(x => !!x[1]).map(x => toNormal(x[1] as Record<string, any>)) ?? [];
return (
(await pipeline.exec())
?.filter(x => !!x[1])
.map(x => toNormal(x[1] as Record<string, any>))
.filter(x => x) ?? []
);
}

async get(keys: string): Promise<any> {
Expand Down Expand Up @@ -150,6 +155,7 @@ export class RedisAdapter implements Adapter {
}

async bulkRemove(keys: string[]) {
if (!keys.length) return;
await this.client.del(...keys.map(x => this.buildKey(x)));
}

Expand Down
72 changes: 72 additions & 0 deletions packages/redis-adapter/test/adapter.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const { strict } = require("node:assert/strict");
const { test, describe, after, before } = require('node:test');
const { RedisAdapter } = require('../lib/adapter');

describe('RedisAdapter', async () => {
const bulk = [['key1', { value: 'value1' }], ['key2', { value: 'value2' }]]

const adapter = new RedisAdapter({
redisOptions: {
host: 'localhost',
port: 6379,
},
namespace: 'test',
});

before(async () => {
// Clean the Redis instance before each test
await adapter.flush();

});

await test('constructor', () => {
strict.strictEqual(adapter.isAsync, true);
strict.strictEqual(adapter.namespace, 'test');
});

await test('get', async () => {
const result = await adapter.get('testKey');
strict.deepStrictEqual(result, undefined);
});

await test('set', async () => {
await strict.doesNotReject(async () => {
await adapter.set('testKey', { value: 'testValue' });
});
});

await test('bulkSet', async () => {
await strict.doesNotReject(async () => {
await adapter.bulkSet(bulk);
});
});

await test('bulkGet', async () => {
const result = await adapter.bulkGet(['key1', 'key2']);
strict.deepStrictEqual(result, bulk.map(x => x[1]));
});



await test('patch', async () => {
await strict.doesNotReject(async () => {
await adapter.patch(false, 'testKey', { newValue: 'updatedValue' });
});
});

await test('bulkPatch', async () => {
await strict.doesNotReject(async () => {
await adapter.bulkPatch(false, [['key1', { newValue: 'updatedValue1' }], ['key2', { newValue: 'updatedValue2' }]]);
});
});

await test('scan', async () => {
const result = await adapter.scan('test*');
strict.strictEqual(result.length, 3);
});

after(async () => {
await adapter.flush();
await adapter.client.quit();
});
});
37 changes: 37 additions & 0 deletions packages/redis-adapter/test/cache.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
const { describe, test, after, before } = require('node:test');
const { Cache, Client } = require('seyfert');
const { RedisAdapter } = require('../lib/index');
const { doesNotReject } = require('node:assert/strict');
const { setTimeout } = require('node:timers/promises');
const { doesNotThrow } = require('node:assert/strict');

// all intents
const intents = 53608447;

describe('Test Adapter cache', async t => {
const adapter = new RedisAdapter({
redisOptions: {
host: 'localhost',
port: 6379,
},
namespace: 'test_cache',
});

test('discord cache', async () => {
doesNotThrow(async () => {
const client = new Client({ getRC: () => ({ intents }) });
client.setServices({
cache: {
adapter,
}
})
await client.cache.testAdapter();
});
await setTimeout(5000);
});

after(async () => {
await adapter.flush()
await adapter.client.quit();
});
});
12 changes: 6 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 66e8dfd

Please sign in to comment.