1
+ import { Bus as RlanzBus } from '@rlanz/bus'
1
2
import { createId } from '@paralleldrive/cuid2'
3
+ import type { Transport } from '@rlanz/bus/types/main'
2
4
3
- import { RetryQueue } from './retry_queue.js'
4
5
import { CacheBusMessageType } from '../types/bus.js'
5
6
import type { LocalCache } from '../cache/facades/local_cache.js'
6
7
import { BusMessageReceived } from '../events/bus/bus_message_received.js'
7
8
import { BusMessagePublished } from '../events/bus/bus_message_published.js'
8
- import type { BusDriver , BusOptions , CacheBusMessage , Emitter , Logger } from '../types/main.js'
9
+ import type { BusOptions , CacheBusMessage , Emitter , Logger } from '../types/main.js'
9
10
10
11
/**
11
12
* The bus is used to notify other processes about cache changes.
@@ -17,94 +18,51 @@ import type { BusDriver, BusOptions, CacheBusMessage, Emitter, Logger } from '..
17
18
* local cache accordingly.
18
19
*/
19
20
export class Bus {
20
- /**
21
- * The underlying bus driver
22
- */
23
- #driver: BusDriver
24
-
25
21
/**
26
22
* The local cache that will be updated when a message is received
27
23
*/
28
24
#cache?: LocalCache
29
25
30
- /**
31
- * The logger to use
32
- */
33
- #logger: Logger
34
-
35
- /**
36
- * Emitter
37
- */
38
- #emitter: Emitter
39
-
40
26
/**
41
27
* A unique identifier for this bus instance
42
28
* that is used to prevent the bus from
43
29
* emitting events to itself
44
30
*/
45
31
#busId = createId ( )
46
-
47
- /**
48
- * The channel name to use
49
- */
32
+ #bus: RlanzBus
33
+ #logger: Logger
34
+ #emitter: Emitter
50
35
#channelName = 'bentocache.notifications'
51
36
52
- /**
53
- * The error retry queue holds messages that failed to be sent
54
- */
55
- #errorRetryQueue = new RetryQueue ( )
56
-
57
37
constructor (
58
- driver : BusDriver ,
38
+ driver : Transport ,
59
39
cache : LocalCache ,
60
40
logger : Logger ,
61
41
emitter : Emitter ,
62
42
options : BusOptions = { } ,
63
43
) {
64
- this . #driver = driver
65
44
this . #cache = cache
66
45
this . #emitter = emitter
67
46
this . #logger = logger . child ( { context : 'bentocache.bus' } )
68
- this . #errorRetryQueue = new RetryQueue ( options . retryQueue ?. enabled , options . retryQueue ?. maxSize )
69
47
70
- driver
71
- . setId ( this . #busId)
72
- . setLogger ( this . #logger)
73
- . onReconnect ( ( ) => this . #onReconnect( ) )
74
- }
48
+ this . #bus = new RlanzBus ( driver , {
49
+ retryQueue : { ...options . retryQueue , removeDuplicates : true , retryInterval : false } ,
50
+ } )
75
51
76
- /**
77
- * Process the error retry queue
78
- */
79
- async #processErrorRetryQueue( ) {
80
- this . #logger. debug (
81
- `starting error retry queue processing with ${ this . #errorRetryQueue. size ( ) } messages` ,
52
+ this . #bus. subscribe < CacheBusMessage & { [ key : string ] : any } > (
53
+ this . #channelName,
54
+ this . #onMessage. bind ( this ) ,
82
55
)
83
-
84
- await this . #errorRetryQueue. process ( async ( message ) => {
85
- await this . publish ( message )
86
- return true
87
- } )
88
56
}
89
57
90
58
/**
91
59
* When a message is received through the bus.
92
60
* This is where we update the local cache.
93
61
*/
94
62
async #onMessage( message : CacheBusMessage ) {
95
- /**
96
- * Since we received a message from the bus, we assume that
97
- * the Bus is working. So we can try process the error retry queue if
98
- * there are any messages in it.
99
- */
100
- await this . #processErrorRetryQueue( )
101
-
102
63
this . #logger. trace ( { keys : message . keys , type : message . type } , 'received message from bus' )
103
64
this . #emitter. emit ( 'bus:message:received' , new BusMessageReceived ( message ) )
104
65
105
- /**
106
- * Process the message
107
- */
108
66
if ( message . type === CacheBusMessageType . Delete ) {
109
67
for ( const key of message . keys ) this . #cache?. delete ( key )
110
68
}
@@ -118,52 +76,19 @@ export class Bus {
118
76
}
119
77
}
120
78
121
- /**
122
- * When the bus driver reconnects after a disconnection
123
- */
124
- async #onReconnect( ) {
125
- this . #logger. debug ( 'bus driver reconnected' )
126
- await this . #processErrorRetryQueue( )
127
- }
128
-
129
- /**
130
- * Subscribe to the bus channel
131
- */
132
- async subscribe ( ) {
133
- this . #driver. subscribe ( this . #channelName, this . #onMessage. bind ( this ) )
134
- }
135
-
136
79
/**
137
80
* Publish a message to the bus channel
138
81
*
139
82
* @returns true if the message was published, false if not
140
83
*/
141
84
async publish ( message : Omit < CacheBusMessage , 'busId' > ) : Promise < boolean > {
142
- const fullMessage = { ...message , busId : this . #busId }
143
-
144
85
try {
145
- this . #logger. trace ( { keys : message . keys , type : message . type } , 'publishing message to bus' )
146
-
147
- /**
148
- * Publish the message to the bus using the underlying driver
149
- */
150
- await this . #driver. publish ( this . #channelName, fullMessage )
151
-
152
- /**
153
- * Emit the bus:message:published event
154
- */
86
+ const fullMessage = { ...message , busId : this . #busId }
87
+ await this . #bus. publish ( this . #channelName, message )
155
88
this . #emitter. emit ( 'bus:message:published' , new BusMessagePublished ( fullMessage ) )
156
89
return true
157
90
} catch ( error ) {
158
- this . #logger. error ( error , 'failed to publish message to bus' )
159
-
160
- /**
161
- * Add to the error retry queue
162
- */
163
- const wasAdded = this . #errorRetryQueue. enqueue ( fullMessage )
164
- if ( ! wasAdded ) return false
165
-
166
- this . #logger. debug ( message , 'added message to error retry queue' )
91
+ this . #logger. error ( { error } , 'failed to publish message to bus' )
167
92
return false
168
93
}
169
94
}
@@ -172,6 +97,6 @@ export class Bus {
172
97
* Disconnect the bus
173
98
*/
174
99
async disconnect ( ) : Promise < void > {
175
- this . #driver . disconnect ( )
100
+ await this . #bus . disconnect ( )
176
101
}
177
102
}
0 commit comments