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

feat(scheduler-utils): add address to return. remove setTimeouts in favor of lru-cache ttl #251

Merged
merged 1 commit into from
Dec 20, 2023
Merged
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
2 changes: 1 addition & 1 deletion scheduler-utils/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Locate the `ao` Scheduler assigned to an `ao` Process.
```js
import { locate } from "@permaweb/ao-scheduler-utils";

let { url } = await locate('<process-id>');
let { url, owner } = await locate('<process-id>');
```

#### `validate`
Expand Down
35 changes: 11 additions & 24 deletions scheduler-utils/package-lock.json

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

2 changes: 1 addition & 1 deletion scheduler-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"test": "node --test ./src"
},
"dependencies": {
"mnemonist": "^0.39.6",
"lru-cache": "^10.1.0",
"ramda": "^0.29.1"
},
"devDependencies": {
Expand Down
32 changes: 23 additions & 9 deletions scheduler-utils/src/client/in-memory.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
import LruCache from 'mnemonist/lru-cache-with-delete.js'
import { LRUCache } from 'lru-cache'

/**
* @type {LruCache}
* @type {LRUCache}
*/
let internalCache
let internalSize
export function createLruCache ({ size }) {
if (internalCache) return internalCache
internalSize = size
internalCache = new LruCache(size)
internalCache = new LRUCache({
/**
* number of entries
*/
max: size,
/**
* max size of cache, as a scalar.
*
* In our case, characters (see sizeCalculation)
*/
maxSize: 1_000_000 * 5,
/**
* Simply stringify to get the bytes
*/
sizeCalculation: (v) => JSON.stringify(v).length,
allowStale: true
})
return internalCache
}

Expand All @@ -20,10 +36,9 @@ export function getByProcessWith ({ cache = internalCache }) {
}

export function setByProcessWith ({ cache = internalCache }) {
return async (process, url, ttl) => {
return async (process, { url, owner }, ttl) => {
if (!internalSize) return
setTimeout(() => cache.delete(process), ttl)
return cache.set(process, url)
return cache.set(process, { url, owner }, { ttl })
}
}

Expand All @@ -35,9 +50,8 @@ export function getByOwnerWith ({ cache = internalCache }) {
}

export function setByOwnerWith ({ cache = internalCache }) {
return async (owner, url, ttl) => {
return async (owner, { url }, ttl) => {
if (!internalSize) return
setTimeout(() => cache.delete(owner), ttl)
return cache.set(owner, url)
return cache.set(owner, { url, address: owner }, { ttl })
}
}
16 changes: 6 additions & 10 deletions scheduler-utils/src/client/in-memory.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,33 @@ describe('in-memory', () => {
const getByProcess = getByProcessWith({ cache })
test('returns the url if in cache', async () => {
assert.equal(await getByProcess(PROCESS), undefined)
cache.set(PROCESS, DOMAIN)
assert.equal(await getByProcess(PROCESS), DOMAIN)
cache.set(PROCESS, { url: DOMAIN, address: SCHEDULER })
assert.deepStrictEqual(await getByProcess(PROCESS), { url: DOMAIN, address: SCHEDULER })
})
})

describe('getByOwnerWith', () => {
const getByOwner = getByOwnerWith({ cache })
test('returns the url if in cache', async () => {
assert.equal(await getByOwner(SCHEDULER), undefined)
cache.set(SCHEDULER, DOMAIN)
assert.equal(await getByOwner(SCHEDULER), DOMAIN)
cache.set(SCHEDULER, { url: DOMAIN, address: SCHEDULER })
assert.deepStrictEqual(await getByOwner(SCHEDULER), { url: DOMAIN, address: SCHEDULER })
})
})

describe('setByProcessWith', () => {
const setByProcess = setByProcessWith({ cache })
test('sets the value in cache and removes after ttl', async () => {
test('sets the value in cache', async () => {
await setByProcess(PROCESS, DOMAIN, TEN_MS)
assert.ok(cache.has(PROCESS))
await new Promise(resolve => setTimeout(resolve, TEN_MS))
assert.equal(cache.get(PROCESS), undefined)
})
})

describe('setByOwnerWith', () => {
const setByOwner = setByOwnerWith({ cache })
test('sets the value in cache and removes after ttl', async () => {
test('sets the value in cache', async () => {
await setByOwner(SCHEDULER, DOMAIN, TEN_MS)
assert.ok(cache.has(SCHEDULER))
await new Promise(resolve => setTimeout(resolve, TEN_MS))
assert.equal(cache.get(SCHEDULER), undefined)
})
})
})
11 changes: 5 additions & 6 deletions scheduler-utils/src/locate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@ export function locateWith ({ loadProcessScheduler, cache }) {
* of decentralized sequencers
*
* @param {string} process - the id of the process
* @returns {Promise<{ url: string }>} - an object whose url field is the Scheduler Location
* @returns {Promise<{ url: string, address: string }>} - an object whose url field is the Scheduler Location
*/
return (process) =>
cache.getByProcess(process)
.then((url) => {
if (url) return url
.then((cached) => {
if (cached) return cached
return loadProcessScheduler(process)
.then((scheduler) => {
return Promise.all([
cache.setByProcess(process, scheduler.url, scheduler.ttl),
cache.setByProcess(process, { url: scheduler.url, address: scheduler.owner }, scheduler.ttl),
cache.setByOwner(scheduler.owner, scheduler.url, scheduler.ttl)
])
.then(() => scheduler.url)
.then(() => ({ url: scheduler.url, address: scheduler.owner }))
})
})
.then((url) => ({ url }))
}
9 changes: 5 additions & 4 deletions scheduler-utils/src/locate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ describe('locateWith', () => {
assert.equal(process, PROCESS)
return undefined
},
setByProcess: async (process, url, ttl) => {
setByProcess: async (process, { url, address }, ttl) => {
assert.equal(process, PROCESS)
assert.equal(url, DOMAIN)
assert.equal(address, SCHEDULER)
assert.equal(ttl, TEN_MS)
},
setByOwner: async (owner, url, ttl) => {
Expand All @@ -34,7 +35,7 @@ describe('locateWith', () => {
})

await locate(PROCESS)
.then((res) => assert.deepStrictEqual(res, { url: DOMAIN }))
.then((res) => assert.deepStrictEqual(res, { url: DOMAIN, address: SCHEDULER }))
})

test('should serve the cached value', async () => {
Expand All @@ -45,12 +46,12 @@ describe('locateWith', () => {
cache: {
getByProcess: async (process) => {
assert.equal(process, PROCESS)
return DOMAIN
return { url: DOMAIN, address: SCHEDULER }
}
}
})

await locate(PROCESS)
.then((res) => assert.deepStrictEqual(res, { url: DOMAIN }))
.then((res) => assert.deepStrictEqual(res, { url: DOMAIN, address: SCHEDULER }))
})
})
2 changes: 1 addition & 1 deletion scheduler-utils/src/raw.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe('rawWith', () => {
cache: {
getByOwner: async (walletAddress) => {
assert.equal(walletAddress, SCHEDULER)
return DOMAIN
return { url: DOMAIN, address: SCHEDULER }
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion scheduler-utils/src/validate.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('validateWith', () => {
cache: {
getByOwner: async (walletAddress) => {
assert.equal(walletAddress, SCHEDULER)
return DOMAIN
return { url: DOMAIN, address: SCHEDULER }
}
}
})
Expand Down