@@ -5,6 +5,11 @@ import { LedgerClient } from '../ledger-client'
55
66import { LRUCache } from 'typescript-lru-cache'
77import { ACSContainer , ACSKey } from './acs-container.js'
8+ import {
9+ DEFAULT_MAX_CACHE_SIZE ,
10+ DEFAULT_ENTRY_EXPIRATION_TIME ,
11+ SharedACSCacheStats ,
12+ } from './acs-shared-cache.js'
813import { WSSupport } from './ws-support.js'
914import { PartyId } from '@canton-network/core-types'
1015import { Logger } from 'pino'
@@ -17,54 +22,55 @@ export type AcsHelperOptions = {
1722 includeCreatedEventBlob ?: boolean
1823}
1924
20- const DEFAULT_MAX_CACHE_SIZE = 50
21- const DEFAULT_ENTRY_EXPIRATION_TIME = 10 * 60 * 1000
22-
2325export class ACSHelper {
2426 private contractsSet : LRUCache < string , ACSContainer >
2527 private readonly apiInstance : LedgerClient
2628 private readonly wsSupport : WSSupport | undefined
2729 private readonly logger : Logger
2830 private includeCreatedEventBlob : boolean
29- private hits = 0
30- private misses = 0
31- private evictions = 0
32- private totalLookuptime = 0
3331 private totalCacheServeTime = 0
3432
3533 constructor (
3634 apiInstance : LedgerClient ,
3735 _logger : Logger ,
38- options ?: AcsHelperOptions
36+ options ?: AcsHelperOptions ,
37+ sharedCache ?: LRUCache < string , ACSContainer >
3938 ) {
40- this . contractsSet = new LRUCache ( {
41- maxSize : options ?. maxCacheSize ?? DEFAULT_MAX_CACHE_SIZE ,
42- entryExpirationTimeInMS :
43- options ?. entryExpirationTime ?? DEFAULT_ENTRY_EXPIRATION_TIME , // 10 minutes
44- onEntryEvicted : ( entry ) => {
45- this . logger . debug (
46- `entry ${ entry . key } isExpired = ${ entry . isExpired } . evicting entry.`
47- )
48- this . evictions ++
49- } ,
50- } )
39+ this . contractsSet =
40+ sharedCache ??
41+ new LRUCache ( {
42+ maxSize : options ?. maxCacheSize ?? DEFAULT_MAX_CACHE_SIZE ,
43+ entryExpirationTimeInMS :
44+ options ?. entryExpirationTime ??
45+ DEFAULT_ENTRY_EXPIRATION_TIME , // 10 minutes
46+ onEntryEvicted : ( entry ) => {
47+ this . logger . debug (
48+ `entry ${ entry . key } isExpired = ${ entry . isExpired } . evicting entry.`
49+ )
50+ SharedACSCacheStats . evictions ++
51+ } ,
52+ } )
5153 this . apiInstance = apiInstance
5254 this . wsSupport = options ?. wsSupport
5355 this . logger = _logger . child ( { component : 'ACSHelper' } )
5456 this . includeCreatedEventBlob = options ?. includeCreatedEventBlob ?? true
5557 }
5658
5759 getCacheStats ( ) {
58- const totalCalls = this . hits + this . misses
59- const hitRate = totalCalls ? ( this . hits / totalCalls ) * 100 : 0
60+ const totalCalls = SharedACSCacheStats . hits + SharedACSCacheStats . misses
61+ const hitRate = totalCalls
62+ ? ( SharedACSCacheStats . hits / totalCalls ) * 100
63+ : 0
6064 const avgLookupTime =
61- totalCalls > 0 ? this . totalLookuptime / totalCalls : 0
65+ totalCalls > 0
66+ ? SharedACSCacheStats . totalLookupTime / totalCalls
67+ : 0
6268
6369 return {
6470 totalCalls,
65- hits : this . hits ,
66- misses : this . misses ,
67- evictions : this . evictions ,
71+ hits : SharedACSCacheStats . hits ,
72+ misses : SharedACSCacheStats . misses ,
73+ evictions : SharedACSCacheStats . evictions ,
6874 cacheSize : this . contractsSet . size ,
6975 hitRate : hitRate . toFixed ( 2 ) + '%' ,
7076 averageLookupTime : avgLookupTime . toFixed ( 3 ) + ' ms' ,
@@ -80,25 +86,26 @@ export class ACSHelper {
8086 return { party, templateId, interfaceId }
8187 }
8288
83- private static keyToString ( key : ACSKey ) : string {
84- return `${ key . party ? key . party : 'ANY' } _T:${ key . templateId ?? '()' } _I:${ key . interfaceId ?? '()' } `
89+ private static keyToString ( key : ACSKey , ledgerBaseUrl : string ) : string {
90+ return `${ ledgerBaseUrl } _ ${ key . party ? key . party : 'ANY' } _T:${ key . templateId ?? '()' } _I:${ key . interfaceId ?? '()' } `
8591 }
8692
8793 private findACSContainer ( key : ACSKey ) : ACSContainer {
88- const keyStr = ACSHelper . keyToString ( key )
94+ const keyStr = ACSHelper . keyToString ( key , this . apiInstance . baseUrl . href )
95+ // this.logger.info(`ACS KEY ${keyStr}`)
8996 const start = performance . now ( )
9097 const existing = this . contractsSet . get ( keyStr )
9198 const end = performance . now ( )
92- this . totalLookuptime += end - start
99+ SharedACSCacheStats . totalLookupTime += end - start
93100
94101 if ( existing ) {
95- this . hits ++
102+ SharedACSCacheStats . hits ++
96103 this . logger . debug ( 'cache hit' )
97104 return existing
98105 }
99106
100107 this . logger . debug ( 'cache miss' )
101- this . misses ++
108+ SharedACSCacheStats . misses ++
102109 const newContainer = new ACSContainer ( undefined , {
103110 includeCreatedEventBlob : this . includeCreatedEventBlob ,
104111 } )
@@ -123,8 +130,12 @@ export class ACSHelper {
123130 )
124131 const end = performance . now ( )
125132
126- if ( this . contractsSet . has ( ACSHelper . keyToString ( key ) ) ) {
127- this . totalCacheServeTime += end - start
133+ if (
134+ this . contractsSet . has (
135+ ACSHelper . keyToString ( key , this . apiInstance . baseUrl . href )
136+ )
137+ ) {
138+ SharedACSCacheStats . totalCacheServeTime += end - start
128139 }
129140
130141 return result
@@ -148,8 +159,12 @@ export class ACSHelper {
148159
149160 const end = performance . now ( )
150161
151- if ( this . contractsSet . has ( ACSHelper . keyToString ( key ) ) ) {
152- this . totalCacheServeTime += end - start
162+ if (
163+ this . contractsSet . has (
164+ ACSHelper . keyToString ( key , this . apiInstance . baseUrl . href )
165+ )
166+ ) {
167+ SharedACSCacheStats . totalCacheServeTime += end - start
153168 }
154169
155170 return result
0 commit comments