All files / src decorators.ts

100% Statements 46/46
66.67% Branches 4/6
100% Functions 15/15
100% Lines 44/44
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 8510x 10x 10x     10x 21x 21x     10x 7x   7x 41x 40x 40x   1x       7x     10x 29x 29x   1x 1x 1x 1x 1x 1x   1x   1x 1x 1x   1x                 1x     1x         10x 32x 32x 32x 100x 100x       32x       10x 26x 26x 26x 85x 85x       26x      
import {performance} from 'perf_hooks';
import {ERROR_CODES, PuzzleError} from "./errors";
import {startSegment} from 'newrelic';
 
 
export const sealed = (constructor: Function) => {
    Object.seal(constructor);
    Object.seal(constructor.prototype);
};
 
export const callableOnce = (target: any, name: string, descriptor: PropertyDescriptor) => {
    const newDescriptor = Object.assign({}, descriptor);
 
    newDescriptor.value = function (this: any) {
        if (!this[`___callableOnce__${name}___`]) {
            descriptor.value.apply(this, arguments);
            this[`___callableOnce__${name}___`] = true;
        } else {
            throw new PuzzleError(ERROR_CODES.CALLABLE_ONCE_CALLED_MORE_THAN_ONE_TIME, target.constructor.name, name);
        }
    };
 
    return newDescriptor;
};
 
export const benchmark = (enabled: boolean, logger: (input: any) => void) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        if (!enabled) return descriptor;
 
        console.log(`Attaching benchmark to ${propertyKey}`);
        const newDescriptor = Object.assign({}, descriptor);
        newDescriptor.value = function (this: any) {
            const old_time = performance.now();
            const m0 = process.memoryUsage();
            const c0 = process.cpuUsage();
 
            const returnValue = descriptor.value.apply(this, arguments);
 
            const new_time = performance.now();
            const m1 = process.memoryUsage();
            const diffCPU = process.cpuUsage(c0);
 
            logger({
                benchmarking: `${this.constructor.name} - ${propertyKey}`,
                ram: `${(m1.rss - m0.rss) / 1048576} mb`,
                heapTotal: `${(m1.heapTotal - m0.heapTotal) / 1048576} mb`,
                heapUsed: `${(m1.heapUsed - m0.heapUsed) / 1048576} mb`,
                cpu: `${(diffCPU.user + diffCPU.system) / 1000000} s`,
                spendTime: `${(new_time - old_time)} ms`
            });
 
            return returnValue;
        };
 
        return newDescriptor;
    };
};
 
 
export const nrSegment = (segmentName: string, record: boolean = true) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        const original = descriptor.value;
        descriptor.value = function (...args: any[]) {
            return startSegment(segmentName, record, () => {
                return original.apply(this, args);
            });
        };
 
        return descriptor;
    };
};
 
export const nrSegmentAsync = (segmentName: string, record: boolean = true) => {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
        const original = descriptor.value;
        descriptor.value = async function (...args: any[]) {
            return await startSegment(segmentName, record, async () => {
                return await original.apply(this, args);
            });
        };
 
        return descriptor;
    };
};