Skip to content

Commit

Permalink
feat: provide custom modified adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
climba03003 committed Oct 10, 2024
1 parent 49376ea commit ca4f1a1
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 4 deletions.
89 changes: 88 additions & 1 deletion packages/cronjob/lib/cronjob.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { parseExpression } from 'cron-parser'
import { JoSk } from 'josk'
import {
JoSk,
MongoAdapter as JoSkMongoAdapter,
MongoAdapterOptions as JoSkMongoAdapterOptions,
RedisAdapter
} from 'josk'
import { Collection } from 'mongodb'

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try#using_promise.try
const promiseTry = function (func: Function) {
Expand All @@ -12,6 +18,45 @@ const promiseTry = function (func: Function) {
})
}

const ensureIndex = async (collection: Collection, keys: any, opts: any) => {
try {
await collection.createIndex(keys, opts)
} catch (e: any) {
if (e.code === 85) {
let indexName
const indexes = await collection.indexes()
for (const index of indexes) {
let drop = true
for (const indexKey of Object.keys(keys)) {
if (typeof index.key[indexKey] === 'undefined') {
drop = false
break
}
}

for (const indexKey of Object.keys(index.key)) {
if (typeof keys[indexKey] === 'undefined') {
drop = false
break
}
}

if (drop) {
indexName = index.name
break
}
}

if (indexName) {
await collection.dropIndex(indexName)
await collection.createIndex(keys, opts)
}
} else {
console.info(`[INFO] [josk] [MongoAdapter] [ensureIndex] Can not set ${Object.keys(keys).join(' + ')} index on "${collection.collectionName}" collection`, { keys, opts, details: e })
}
}
}

export class CronJob extends JoSk {
async setCronJob (func: () => void | Promise<void>, cron: string, uid: string): Promise<string> {
const nextTimestamp = +parseExpression(cron).next().toDate()
Expand Down Expand Up @@ -51,3 +96,45 @@ export class CronJob extends JoSk {
}, uid)
}
}

interface MongoAdapterOptions extends JoSkMongoAdapterOptions {
collectionName?: string
}

export class MongoAdapter extends JoSkMongoAdapter {
constructor (opts: MongoAdapterOptions) {
super(opts)

// we update to use different db
if (typeof opts.collectionName === 'string') {
// remove the old collection
this.db.dropCollection(this.uniqueName).catch(console.log)
this.uniqueName = `${opts.collectionName}${this.prefix}`
this.collection = this.db.collection(this.uniqueName)
ensureIndex(this.collection, { uid: 1 }, { background: false, unique: true })
ensureIndex(this.collection, { uid: 1, isDeleted: 1 }, { background: false })
ensureIndex(this.collection, { executeAt: 1 }, { background: false })
// if no lock collection name is provided we use different one
if (!(typeof opts.lockCollectionName === 'string')) {
this.db.dropCollection(this.lockCollectionName).catch(() => {})
this.lockCollectionName = `${opts.collectionName}.lock`
this.lockCollection = this.db.collection(this.lockCollectionName)
ensureIndex(this.lockCollection, { expireAt: 1 }, { background: false, expireAfterSeconds: 1 })
ensureIndex(this.lockCollection, { uniqueName: 1 }, { background: false, unique: true })
}

// we execute the reset on init
if (opts.resetOnInit) {
this.collection.deleteMany({
isInterval: false
}).catch(() => {})

this.lockCollection.deleteMany({
uniqueName: this.uniqueName
}).catch(() => {})
}
}
}
}

export { RedisAdapter }
2 changes: 1 addition & 1 deletion packages/cronjob/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ export const fastifyCronJob = FastifyPlugin(plugin, {
encapsulate: false,
})

export { MongoAdapter, RedisAdapter } from 'josk'
export { MongoAdapter, RedisAdapter } from './cronjob'
3 changes: 2 additions & 1 deletion packages/cronjob/test/mongodb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ test('MongoAdapter', async function (t: TestContext) {

await fastify.register(fastifyCronJob, {
adapter: new MongoAdapter({
db
db,
collectionName: 'sys.timer'
})
})

Expand Down
11 changes: 10 additions & 1 deletion packages/cronjob/types/josk.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Collection, Db } from 'mongodb'

declare module 'josk' {

interface ErrorDetails {
Expand Down Expand Up @@ -86,13 +88,20 @@ declare module 'josk' {
}

export interface MongoAdapterOptions {
db: unknown
db: Db
lockCollectionName?: string
prefix?: string
resetOnInit?: boolean
}

export class MongoAdapter {
db: Db
prefix: string
uniqueName: string
lockCollectionName: string
collection: Collection
lockCollection: Collection

constructor (options: MongoAdapterOptions)

async ping (): Promise<void>
Expand Down

0 comments on commit ca4f1a1

Please sign in to comment.