This repository has been archived by the owner on Nov 1, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: cron for merge offer and offer arrange invocation trigger
- Loading branch information
1 parent
47e6ced
commit 935835e
Showing
18 changed files
with
1,683 additions
and
2,075 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import all from 'it-all' | ||
import * as AggregateAPI from '@web3-storage/aggregate-api' | ||
|
||
import { ArrangedOfferStore, ArrangedOffer } from './tables/arranged-offer-store' | ||
|
||
const STAT_TO_ARRANGE = 'queued' | ||
|
||
export async function mutateOffersToArrange (arrangedOfferStore: ArrangedOfferStore, aggregateStore: AggregateAPI.AggregateStore) { | ||
const offersQueued = await all(arrangedOfferStore.list(STAT_TO_ARRANGE)) | ||
|
||
const offersToArrange = (await Promise.all( | ||
offersQueued.map(async (commitmentProof) => { | ||
const aggregate = await aggregateStore.get(commitmentProof) | ||
if (!aggregate) { | ||
return { | ||
commitmentProof, | ||
stat: STAT_TO_ARRANGE | ||
} | ||
} else { | ||
// TODO: state | ||
return { | ||
commitmentProof, | ||
stat: 'accepted' | ||
} | ||
} | ||
}) | ||
)).filter(offer => offer.stat !== STAT_TO_ARRANGE) as ArrangedOffer[] | ||
|
||
await arrangedOfferStore.batchSet(offersToArrange) | ||
return offersToArrange | ||
} | ||
|
||
// TODO: arrange offers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import all from 'it-all' | ||
|
||
import { OfferStore } from './buckets/offer-store' | ||
|
||
export async function mergeOffers (date: Date, offerStore: OfferStore) { | ||
const d = getPreviousUtcDateName(date) | ||
const offers = (await all(offerStore.list(d))) | ||
await offerStore.putMergedOffers(d, offers) | ||
|
||
return d | ||
} | ||
|
||
function getPreviousUtcDateName(date: Date) { | ||
// normalize date to multiple of 15 minutes | ||
const currentMinute = date.getUTCMinutes() | ||
const factor = Math.floor(currentMinute / 15) // difference between previous and next | ||
const additionalTime = ((factor * 15) - currentMinute) * 60000 | ||
|
||
const nDate = new Date(date.getTime() + additionalTime) | ||
|
||
return `${nDate.getUTCFullYear()}-${nDate.getUTCMonth()}-${nDate.getUTCDay()} ${nDate.getUTCHours()}:${nDate.getUTCMinutes()}:00` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/classes/transactwriteitemscommand.html | ||
export const MAX_TRANSACT_WRITE_ITEMS = 100 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { test } from './helpers/context.js' | ||
import { | ||
createS3, | ||
createBucket, | ||
createDynamodDb, | ||
createTable, | ||
} from './helpers/resources.js' | ||
import { CID } from 'multiformats/cid' | ||
import { generateOffers, createAggregateStore } from './helpers/offers.js' | ||
|
||
import { arrangedOfferTableProps } from '../tables/index.js' | ||
import { mutateOffersToArrange } from '../arrange-offers.js' | ||
import { useOfferStore } from '../buckets/offer-store.js' | ||
import { useArrangedOfferStore } from '../tables/arranged-offer-store.js' | ||
|
||
test.before(async (t) => { | ||
Object.assign(t.context, { | ||
dynamo: await createDynamodDb(), | ||
s3: (await createS3()).client, | ||
}) | ||
}) | ||
|
||
test('can arrange multiple offers', async t => { | ||
const { dynamo, s3 } = t.context | ||
const bucketName = await createBucket(s3) | ||
|
||
const aggregateStore = createAggregateStore() | ||
const arrangedOfferStore = useArrangedOfferStore( | ||
dynamo, | ||
await createTable(dynamo, arrangedOfferTableProps) | ||
) | ||
const offerStore = useOfferStore(s3, bucketName, arrangedOfferStore) | ||
const offers = (await generateOffers(10, 10)) | ||
|
||
const dateToFront = new Date() | ||
dateToFront.setMinutes(dateToFront.getMinutes() + 15) | ||
const dataSegments = [ | ||
'baga6ea4seaqcq4xx7rqx2lsrm6iky7qqk5jh7pbaj5bgdu22afhp4fodvccb6bq', | ||
'baga6ea4seaqhisghxrl4yntcsxtoc6rany2fjtbxgcnhhztkh5myy2mbs4nk2ki' | ||
].map(s => CID.parse(s)) | ||
await Promise.all( | ||
dataSegments.map(commitmentProof => offerStore.queue({ commitmentProof, offers })) | ||
) | ||
|
||
// @ts-expect-error set one segment aggregate | ||
aggregateStore.set(dataSegments[0]) | ||
const resWithFirstSegment = await mutateOffersToArrange(arrangedOfferStore, aggregateStore) | ||
t.is(resWithFirstSegment.length, 1) | ||
t.is(resWithFirstSegment[0].commitmentProof.toString(), dataSegments[0].toString()) | ||
|
||
const resWithoutReadySegments = await mutateOffersToArrange(arrangedOfferStore, aggregateStore) | ||
t.is(resWithoutReadySegments.length, 0) | ||
|
||
// @ts-expect-error set second segment aggregate | ||
aggregateStore.set(dataSegments[1]) | ||
const resWithSecondSegment = await mutateOffersToArrange(arrangedOfferStore, aggregateStore) | ||
t.is(resWithSecondSegment.length, 1) | ||
t.is(resWithSecondSegment[0].commitmentProof.toString(), dataSegments[1].toString()) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import * as AggregateAPI from '@web3-storage/aggregate-api' | ||
|
||
import { randomCARs } from './utils.js' | ||
|
||
/** | ||
* @param {number} length | ||
* @param {number} size | ||
*/ | ||
export async function generateOffers(length, size) { | ||
return (await randomCARs(length, size)) | ||
// Inflate size for testing within range | ||
.map((car) => ({ | ||
...car, | ||
size: car.size * 10e5, | ||
})) | ||
} | ||
|
||
/** | ||
* @returns {AggregateAPI.AggregateStore} | ||
*/ | ||
export function createAggregateStore() { | ||
const aggregates = new Set() | ||
|
||
return { | ||
get: async (commitmentProof) => { | ||
if (aggregates.has(commitmentProof.toString())) { | ||
return Promise.resolve(['success']) | ||
} | ||
return Promise.resolve(undefined) | ||
}, | ||
// @ts-expect-error not in interface | ||
set: async (commitmentProof) => { | ||
aggregates.add(commitmentProof.toString()) | ||
|
||
return Promise.resolve() | ||
} | ||
} | ||
} |
Oops, something went wrong.