@@ -2,8 +2,19 @@ interface LocalSubscriptionStoreOptions {
22 heartBeatInterval ?: number ;
33}
44
5+ export type LocalSubscriptionStoreSubscription = {
6+ message : any ,
7+ state : any ,
8+ timestamp : Date ,
9+ } ;
10+
11+ export type LocalSubscriptionStoreConnection = {
12+ subscriptions : Map < string , LocalSubscriptionStoreSubscription > ,
13+ authContext ?: any ,
14+ } ;
15+
516export class LocalSubscriptionStore {
6- protected connections = { } ;
17+ protected readonly connections : Map < string , LocalSubscriptionStoreConnection > = new Map ( ) ;
718
819 protected readonly hearBeatInterval : number ;
920
@@ -12,60 +23,68 @@ export class LocalSubscriptionStore {
1223 }
1324
1425 public async getSubscription ( connectionId : string , subscriptionId : string ) {
15- const connection = this . getConnection ( connectionId ) ;
16- return connection . subscriptions [ subscriptionId ] ;
26+ const connection = this . getConnectionOrCreate ( connectionId ) ;
27+ return connection . subscriptions . get ( subscriptionId ) ;
1728 }
1829
1930 public async subscribe ( connectionId : string , subscriptionId : string , subscription ) {
20- const connection = this . getConnection ( connectionId ) ;
21- connection . subscriptions [ subscriptionId ] = {
31+ const connection = this . getConnectionOrCreate ( connectionId ) ;
32+ connection . subscriptions . set ( subscriptionId , {
2233 ...subscription ,
2334 timestamp : new Date ( )
24- } ;
35+ } ) ;
2536 }
2637
2738 public async unsubscribe ( connectionId : string , subscriptionId : string ) {
28- const connection = this . getConnection ( connectionId ) ;
29- delete connection . subscriptions [ subscriptionId ] ;
39+ const connection = this . getConnectionOrCreate ( connectionId ) ;
40+ connection . subscriptions . delete ( subscriptionId ) ;
3041 }
3142
32- public async getAllSubscriptions ( ) {
33- return Object . keys ( this . connections ) . map ( connectionId => {
34- Object . keys ( this . connections [ connectionId ] . subscriptions ) . filter (
35- subscriptionId => new Date ( ) . getTime ( ) -
36- this . connections [ connectionId ] . subscriptions [ subscriptionId ] . timestamp . getTime ( ) >
37- this . hearBeatInterval * 4 * 1000
38- ) . forEach ( subscriptionId => { delete this . connections [ connectionId ] . subscriptions [ subscriptionId ] ; } ) ;
39-
40- return Object . keys ( this . connections [ connectionId ] . subscriptions )
41- . map ( subscriptionId => ( {
42- connectionId,
43- ...this . connections [ connectionId ] . subscriptions [ subscriptionId ]
44- } ) ) ;
45- } ) . reduce ( ( a , b ) => a . concat ( b ) , [ ] ) ;
43+ public getAllSubscriptions ( ) {
44+ const now = Date . now ( ) ;
45+ const staleThreshold = this . hearBeatInterval * 4 * 1000 ;
46+ const result : Array < { connectionId : string } & LocalSubscriptionStoreSubscription > = [ ] ;
47+
48+ for ( const [ connectionId , connection ] of this . connections ) {
49+ for ( const [ subscriptionId , subscription ] of connection . subscriptions ) {
50+ if ( now - subscription . timestamp . getTime ( ) > staleThreshold ) {
51+ connection . subscriptions . delete ( subscriptionId ) ;
52+ }
53+ }
54+
55+ for ( const [ , subscription ] of connection . subscriptions ) {
56+ result . push ( { connectionId, ...subscription } ) ;
57+ }
58+ }
59+
60+ return result ;
4661 }
4762
48- public async cleanupSubscriptions ( connectionId : string ) {
49- delete this . connections [ connectionId ] ;
63+ public async disconnect ( connectionId : string ) {
64+ this . connections . delete ( connectionId ) ;
5065 }
5166
5267 public async getAuthContext ( connectionId : string ) {
53- return this . getConnection ( connectionId ) . authContext ;
68+ return this . getConnectionOrCreate ( connectionId ) . authContext ;
5469 }
5570
5671 public async setAuthContext ( connectionId : string , authContext ) {
57- this . getConnection ( connectionId ) . authContext = authContext ;
72+ this . getConnectionOrCreate ( connectionId ) . authContext = authContext ;
5873 }
5974
60- protected getConnection ( connectionId : string ) {
61- if ( ! this . connections [ connectionId ] ) {
62- this . connections [ connectionId ] = { subscriptions : { } } ;
75+ protected getConnectionOrCreate ( connectionId : string ) : LocalSubscriptionStoreConnection {
76+ const connect = this . connections . get ( connectionId ) ;
77+ if ( connect ) {
78+ return connect ;
6379 }
6480
65- return this . connections [ connectionId ] ;
81+ const connection = { subscriptions : new Map ( ) } ;
82+ this . connections . set ( connectionId , connection ) ;
83+
84+ return connection ;
6685 }
6786
6887 public clear ( ) {
69- this . connections = { } ;
88+ this . connections . clear ( ) ;
7089 }
7190}
0 commit comments