Skip to content

Commit

Permalink
feat: add support for defining listeners as ioc container bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Jun 27, 2019
1 parent c6667fc commit d4415eb
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
4 changes: 2 additions & 2 deletions adonis-typings/redis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ declare module '@ioc:Adonis/Addons/Redis' {
* Redis pub/sub methods
*/
export interface RedisPubSubContract {
subscribe (channel: string, handler: PubSubChannelHandler): void
psubscribe (pattern: string, handler: PubSubPatternHandler): void
subscribe (channel: string, handler: PubSubChannelHandler | string): void
psubscribe (pattern: string, handler: PubSubPatternHandler | string): void
unsubscribe (channel: string): void
punsubscribe (pattern: string): void
}
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"tag": "next"
},
"devDependencies": {
"@adonisjs/fold": "^6.0.3",
"@adonisjs/mrm-preset": "^2.0.3",
"@types/node": "^12.0.10",
"commitizen": "^3.1.1",
Expand Down
28 changes: 25 additions & 3 deletions src/AbstractFactory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import * as Emitter from 'emittery'
import { Redis, Cluster } from 'ioredis'
import { Exception } from '@poppinss/utils'
import { Exception, parseIocReference } from '@poppinss/utils'
import { PubSubChannelHandler, PubSubPatternHandler } from '@ioc:Adonis/Addons/Redis'

/**
Expand All @@ -25,6 +25,20 @@ export abstract class AbstractFactory<T extends (Redis | Cluster)> extends Emitt
protected $subscriptions: Map<string, PubSubChannelHandler> = new Map()
protected $psubscriptions: Map<string, PubSubPatternHandler> = new Map()

private _namespace: string = 'App/Listeners'

/**
* Returns an anonymous function by parsing the IoC container
* binding.
*/
private _resolveIoCBinding (handler: string): PubSubChannelHandler | PubSubPatternHandler {
const parsed = parseIocReference(handler, this._namespace)
return function dynamicEventHandler (...args: any[]) {
const instance = global[Symbol.for('ioc.make')](parsed.namespace)
return global[Symbol.for('ioc.call')](instance, parsed.method, args)
}
}

/**
* Returns status of the main connection
*/
Expand Down Expand Up @@ -180,7 +194,7 @@ export abstract class AbstractFactory<T extends (Redis | Cluster)> extends Emitt
* Subscribe to a given channel to receive Redis pub/sub events. A
* new subscriber connection will be created/managed automatically.
*/
public subscribe (channel: string, handler: PubSubChannelHandler): void {
public subscribe (channel: string, handler: PubSubChannelHandler | string): void {
/**
* Make the subscriber connection. The method results in a noop when
* subscriber connection already exists.
Expand Down Expand Up @@ -209,6 +223,10 @@ export abstract class AbstractFactory<T extends (Redis | Cluster)> extends Emitt
return
}

if (typeof (handler) === 'string') {
handler = this._resolveIoCBinding(handler) as PubSubChannelHandler
}

this.emit('subscription:ready', count)
this.$subscriptions.set(channel, handler)
})
Expand All @@ -225,7 +243,7 @@ export abstract class AbstractFactory<T extends (Redis | Cluster)> extends Emitt
/**
* Make redis subscription for a pattern
*/
public psubscribe (pattern: string, handler: PubSubPatternHandler): void {
public psubscribe (pattern: string, handler: PubSubPatternHandler | string): void {
/**
* Make the subscriber connection. The method results in a noop when
* subscriber connection already exists.
Expand Down Expand Up @@ -254,6 +272,10 @@ export abstract class AbstractFactory<T extends (Redis | Cluster)> extends Emitt
return
}

if (typeof (handler) === 'string') {
handler = this._resolveIoCBinding(handler) as PubSubPatternHandler
}

this.emit('psubscription:ready', count)
this.$psubscriptions.set(pattern, handler)
})
Expand Down
30 changes: 30 additions & 0 deletions test/redis-factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
/// <reference path="../adonis-typings/redis.ts" />

import * as test from 'japa'
import { Ioc } from '@adonisjs/fold'
import { RedisFactory } from '../src/RedisFactory'
import { RedisFactoryContract } from '@ioc:Adonis/Addons/Redis'

Expand Down Expand Up @@ -326,4 +327,33 @@ test.group('Redis factory - PSubscribe', () => {
})
})
})

test('bind IoC container binding as subscriber', async (assert, done) => {
const factory = new RedisFactory('main', {
host: process.env.REDIS_HOST,
port: Number(process.env.REDIS_PORT),
}) as unknown as RedisFactoryContract

class RedisListeners {
public async onNews (channel: string, message: string) {
assert.equal(channel, 'news:prime')
assert.equal(message, 'breaking news at 9')
await factory.quit()
done()
}
}

const ioc = new Ioc()
ioc.bind('App/Listeners/RedisListeners', () => {
return new RedisListeners()
})
global[Symbol.for('ioc.make')] = ioc.make.bind(ioc)
global[Symbol.for('ioc.call')] = ioc.call.bind(ioc)

factory.psubscribe('news:*', 'RedisListeners.onNews')

factory.on('psubscription:ready', () => {
factory.publish('news:prime', 'breaking news at 9')
})
})
})

0 comments on commit d4415eb

Please sign in to comment.