refactor: make BlockHeightSwCache methods async

This commit is contained in:
ppedziwiatr
2021-08-31 16:08:34 +02:00
committed by Piotr Pędziwiatr
parent 55854ed45a
commit 9a88a27c2b
7 changed files with 37 additions and 31 deletions

View File

@@ -8,27 +8,27 @@ export interface BlockHeightSwCache<V = any> {
/**
* returns cached value for the highest available in cache block that is not higher than `blockHeight`.
*/
getLessOrEqual(key: string, blockHeight: number): BlockHeightCacheResult<V> | null;
getLessOrEqual(key: string, blockHeight: number): Promise<BlockHeightCacheResult<V> | null>;
/**
* returns latest value stored for given key
*/
getLast(key: string): BlockHeightCacheResult<V> | null;
getLast(key: string): Promise<BlockHeightCacheResult<V> | null>;
/**
* returns value for the key and exact blockHeight
*/
get(key: string, blockHeight: number): BlockHeightCacheResult<V> | null;
get(key: string, blockHeight: number): Promise<BlockHeightCacheResult<V> | null>;
/**
* puts new value in cache under given {@link BlockHeightKey.key} and {@link BlockHeightKey.blockHeight}.
*/
put(blockHeightKey: BlockHeightKey, value: V);
put(blockHeightKey: BlockHeightKey, value: V): Promise<void>;
/**
* checks whether cache has any value stored for given cache key
*/
contains(key: string);
contains(key: string): Promise<boolean>;
}
export class BlockHeightKey {

View File

@@ -28,6 +28,8 @@ const logger = LoggerFactory.INST.create(__filename);
* --1.cache.bson
* --323332.cache.bson
* ...etc.
*
* Note: this is not performance-optimized for reading LARGE amount of contracts ;-)
*/
export class BsonFileBlockHeightSwCache<V = any> implements BlockHeightSwCache<V> {
// TODO: not sure why I'm using "string" as type for blockHeight...:-)
@@ -111,8 +113,8 @@ export class BsonFileBlockHeightSwCache<V = any> implements BlockHeightSwCache<V
}
}
getLast(key: string): BlockHeightCacheResult<V> | null {
if (!this.contains(key)) {
async getLast(key: string): Promise<BlockHeightCacheResult<V> | null> {
if (!(await this.contains(key))) {
return null;
}
@@ -132,8 +134,8 @@ export class BsonFileBlockHeightSwCache<V = any> implements BlockHeightSwCache<V
};
}
getLessOrEqual(key: string, blockHeight: number): BlockHeightCacheResult<V> | null {
if (!this.contains(key)) {
async getLessOrEqual(key: string, blockHeight: number): Promise<BlockHeightCacheResult<V> | null> {
if (!(await this.contains(key))) {
return null;
}
@@ -159,8 +161,8 @@ export class BsonFileBlockHeightSwCache<V = any> implements BlockHeightSwCache<V
};
}
put({ cacheKey, blockHeight }: BlockHeightKey, value: V) {
if (!this.contains(cacheKey)) {
async put({ cacheKey, blockHeight }: BlockHeightKey, value: V): Promise<void> {
if (!(await this.contains(cacheKey))) {
this.storage[cacheKey] = {};
}
@@ -179,11 +181,11 @@ export class BsonFileBlockHeightSwCache<V = any> implements BlockHeightSwCache<V
}
}
contains(key: string) {
async contains(key: string): Promise<boolean> {
return Object.prototype.hasOwnProperty.call(this.storage, key);
}
get(key: string, blockHeight: number): BlockHeightCacheResult<V> | null {
async get(key: string, blockHeight: number): Promise<BlockHeightCacheResult<V> | null> {
throw new Error('Not implemented yet');
}
}

View File

@@ -6,8 +6,8 @@ import { BlockHeightCacheResult, BlockHeightKey, BlockHeightSwCache } from '@sma
export class MemBlockHeightSwCache<V = any> implements BlockHeightSwCache<V> {
private storage: { [key: string]: Map<number, V> } = {};
getLast(key: string): BlockHeightCacheResult<V> | null {
if (!this.contains(key)) {
async getLast(key: string): Promise<BlockHeightCacheResult<V> | null> {
if (!(await this.contains(key))) {
return null;
}
@@ -23,8 +23,8 @@ export class MemBlockHeightSwCache<V = any> implements BlockHeightSwCache<V> {
};
}
getLessOrEqual(key: string, blockHeight: number): BlockHeightCacheResult<V> | null {
if (!this.contains(key)) {
async getLessOrEqual(key: string, blockHeight: number): Promise<BlockHeightCacheResult<V> | null> {
if (!(await this.contains(key))) {
return null;
}
@@ -44,20 +44,20 @@ export class MemBlockHeightSwCache<V = any> implements BlockHeightSwCache<V> {
};
}
put({ cacheKey, blockHeight }: BlockHeightKey, value: V) {
if (!this.contains(cacheKey)) {
async put({ cacheKey, blockHeight }: BlockHeightKey, value: V): Promise<void> {
if (!(await this.contains(cacheKey))) {
this.storage[cacheKey] = new Map();
}
this.storage[cacheKey].set(blockHeight, value);
}
contains(key: string) {
async contains(key: string): Promise<boolean> {
return Object.prototype.hasOwnProperty.call(this.storage, key);
}
get(key: string, blockHeight: number): BlockHeightCacheResult<V> | null {
if (!this.contains(key)) {
async get(key: string, blockHeight: number): Promise<BlockHeightCacheResult<V> | null> {
if (!(await this.contains(key))) {
return null;
}

View File

@@ -14,7 +14,7 @@ export interface StateEvaluator {
currentInteraction: GQLNodeInterface,
executionContext: ExecutionContext<State>,
state: EvalStateResult<State>
);
): Promise<void>;
}
export class EvalStateResult<State> {

View File

@@ -117,7 +117,11 @@ export class DefaultStateEvaluator implements StateEvaluator {
}
logger.debug('Interaction evaluation', singleInteractionBenchmark.elapsed());
this.onStateUpdate<State>(currentInteraction, executionContext, new EvalStateResult(currentState, validity));
await this.onStateUpdate<State>(
currentInteraction,
executionContext,
new EvalStateResult(currentState, validity)
);
}
console.debug('State evaluation total:', stateEvaluationBenchmark.elapsed());
return new EvalStateResult<State>(currentState, validity);
@@ -154,7 +158,7 @@ export class DefaultStateEvaluator implements StateEvaluator {
return missingInteraction.node.tags[contractIndex + 1];
}
onStateUpdate<State>(
async onStateUpdate<State>(
currentInteraction: GQLNodeInterface,
executionContext: ExecutionContext<State, unknown>,
state: EvalStateResult<State>

View File

@@ -21,14 +21,14 @@ export class CacheableContractInteractionsLoader implements InteractionsLoader {
blockHeight
});
const cached = this.cache.get(contractId, blockHeight);
const cached = await this.cache.get(contractId, blockHeight);
if (cached !== null) {
logger.debug('InteractionsLoader - hit from cache!');
return cached.cachedValue;
} else {
const result = await this.baseImplementation.load(contractId, blockHeight);
this.cache.put(new BlockHeightKey(contractId, blockHeight), result);
await this.cache.put(new BlockHeightKey(contractId, blockHeight), result);
return result;
}
}

View File

@@ -42,10 +42,10 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
// if there was anything to cache...
if (sortedInteractionsUpToBlock.length > 0) {
// get latest available cache for the requested block height
cachedState = this.cache.getLessOrEqual(
cachedState = (await this.cache.getLessOrEqual(
executionContext.contractDefinition.txId,
requestedBlockHeight
) as BlockHeightCacheResult<EvalStateResult<State>>;
)) as BlockHeightCacheResult<EvalStateResult<State>>;
if (cachedState != null) {
logger.debug(`Cached state for ${executionContext.contractDefinition.txId}`, {
@@ -104,12 +104,12 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
);
}
onStateUpdate<State>(
async onStateUpdate<State>(
currentInteraction: GQLNodeInterface,
executionContext: ExecutionContext<State>,
state: EvalStateResult<State>
) {
this.cache.put(
await this.cache.put(
new BlockHeightKey(executionContext.contractDefinition.txId, currentInteraction.block.height),
state
);