- Rework Asynchronous notification handling
This commit is contained in:
Родитель
2eaa2d568f
Коммит
276c123a40
|
@ -5,8 +5,8 @@ import { Snippet } from "../../../src/Snippet";
|
|||
import { utlRemoveSessionStorage } from "@microsoft/applicationinsights-common";
|
||||
|
||||
export class AISKUSizeCheck extends AITestClass {
|
||||
private readonly MAX_RAW_SIZE = 139;
|
||||
private readonly MAX_BUNDLE_SIZE = 139;
|
||||
private readonly MAX_RAW_SIZE = 140;
|
||||
private readonly MAX_BUNDLE_SIZE = 140;
|
||||
private readonly MAX_RAW_DEFLATE_SIZE = 56;
|
||||
private readonly MAX_BUNDLE_DEFLATE_SIZE = 56;
|
||||
private readonly rawFilePath = "../dist/es5/applicationinsights-web.min.js";
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ import { AISKUSizeCheck } from "./AISKUSize.Tests";
|
|||
import { ApplicationInsightsTests } from './applicationinsights.e2e.tests';
|
||||
import { ApplicationInsightsFetchTests } from './applicationinsights.e2e.fetch.tests';
|
||||
import { CdnPackagingChecks } from './CdnPackaging.tests';
|
||||
import { GlobalTestHooks } from './GlobalTestHooks.Test';
|
||||
import { SanitizerE2ETests } from './sanitizer.e2e.tests';
|
||||
import { ValidateE2ETests } from './validate.e2e.tests';
|
||||
import { SenderE2ETests } from './sender.e2e.tests';
|
||||
|
@ -10,6 +11,7 @@ import { CdnThrottle} from "./CdnThrottle.tests";
|
|||
import { ThrottleSentMessage } from "./ThrottleSentMessage.tests";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new AISKUSizeCheck().registerTests();
|
||||
new ApplicationInsightsTests().registerTests();
|
||||
new ApplicationInsightsFetchTests().registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
import { AISKULightSizeCheck } from "./AISKULightSize.Tests";
|
||||
import { ApplicationInsightsDynamicConfigTests } from "./dynamicconfig.tests";
|
||||
import { ApplicationInsightsConfigTests } from "./config.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new AISKULightSizeCheck().registerTests();
|
||||
new ApplicationInsightsDynamicConfigTests().registerTests();
|
||||
new ApplicationInsightsConfigTests().registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { _testHookMaxUnloadHooksCb } from "@microsoft/1ds-core-js";
|
||||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -3,8 +3,10 @@ import { HttpManagerTest } from './HttpManagerTest';
|
|||
import { KillSwitchTest } from './KillSwitchTest';
|
||||
import { SerializerTest } from './SerializerTest';
|
||||
import { FileSizeCheckTest } from "./FileSizeCheckTest"
|
||||
import { GlobalTestHooks } from './GlobalTestHooks.Test';
|
||||
|
||||
export function registerTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new PostChannelTest("PostChannelTest").registerTests();
|
||||
new HttpManagerTest("HttpManagerTest").registerTests();
|
||||
new HttpManagerTest("HttpManagerTest", true).registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import { SenderTests } from "./Sender.tests";
|
||||
import { SampleTests } from "./Sample.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new SenderTests().registerTests();
|
||||
new SampleTests().registerTests();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,8 +5,10 @@ import { OfflineInMemoryBatchTests } from "./inmemorybatch.tests";
|
|||
import { OfflineBatchHandlerTests } from "./offlinebatchhandler.tests";
|
||||
import { ChannelTests } from "./channel.tests";
|
||||
import { Offlinetimer } from "./offlinetimer.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new OfflineIndexedDBTests().registerTests();
|
||||
new OfflineWebProviderTests().registerTests();
|
||||
new OfflineDbProviderTests().registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import { TeeChannelCoreTests } from "./TeeChannelCore.Tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new TeeChannelCoreTests().registerTests();
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
import { AnalyticsPluginTests } from './AnalyticsPlugin.tests';
|
||||
import { TelemetryItemCreatorTests } from './TelemetryItemCreator.tests';
|
||||
import { AnalyticsExtensionSizeCheck } from "./AnalyticsExtensionSize.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new AnalyticsPluginTests().registerTests();
|
||||
new TelemetryItemCreatorTests().registerTests();
|
||||
new AnalyticsExtensionSizeCheck().registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import { CfgSyncHelperTests } from "./cfgsynchelper.tests";
|
||||
import {CfgSyncPluginTests} from "./cfgsyncplugin.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new CfgSyncPluginTests().registerTests();
|
||||
new CfgSyncHelperTests().registerTests();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import { ClickEventTest } from './ClickEventTest';
|
||||
import { GlobalTestHooks } from './GlobalTestHooks.Test';
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new ClickEventTest().registerTests();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
import { AjaxTests, AjaxPerfTrackTests, AjaxFrozenTests } from "./ajax.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new AjaxTests().registerTests();
|
||||
new AjaxPerfTrackTests().registerTests();
|
||||
new AjaxFrozenTests().registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
import { MarkMeasureTests } from './MarkMeasureTests';
|
||||
import { GlobalTestHooks } from './GlobalTestHooks.Test';
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new MarkMeasureTests().registerTests();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -3,8 +3,10 @@ import { PropertiesTests } from "./properties.tests";
|
|||
import { SessionManagerTests } from "./SessionManager.Tests";
|
||||
import { PropertiesExtensionSizeCheck } from "./propertiesSize.tests";
|
||||
import { TelemetryContextTests } from "./TelemetryContext.Tests";
|
||||
import { GlobalTestHooks } from './GlobalTestHooks.Test';
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new PropertiesTests().registerTests();
|
||||
new SessionManagerTests(false).registerTests();
|
||||
new SessionManagerTests(true).registerTests();
|
||||
|
|
|
@ -69,7 +69,10 @@ export {
|
|||
IPayloadData, IXHROverride, OnCompleteCallback, SendPOSTFunction, IInternalOfflineSupport, _ISendPostMgrConfig, IBackendResponse, _ISenderOnComplete, SenderPostManager,
|
||||
getResponseText, formatErrorMessageXdr, formatErrorMessageXhr, prependTransports, parseResponse, convertAllHeadersToMap, _getAllResponseHeaders, _appendHeader, _IInternalXhrOverride,
|
||||
_ITimeoutOverrideWrapper, IXDomainRequest,
|
||||
TransportType
|
||||
TransportType,
|
||||
|
||||
// Test Hooks
|
||||
_testHookMaxUnloadHooksCb
|
||||
} from "@microsoft/applicationinsights-core-js";
|
||||
|
||||
export {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { AITestClass } from "@microsoft/ai-test-framework";
|
|||
import * as pako from 'pako';
|
||||
|
||||
export class FileSizeCheckTest extends AITestClass {
|
||||
private readonly MAX_BUNDLE_SIZE = 65;
|
||||
private readonly MAX_BUNDLE_SIZE = 66;
|
||||
private readonly MAX_DEFLATE_SIZE = 28;
|
||||
private readonly bundleFilePath = "../bundle/es5/ms.core.min.js";
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,10 +5,12 @@ import { DynamicProtoTests } from './DynamicProtoTests';
|
|||
import { UtilsTest } from './UtilsTest';
|
||||
import { ValueSanitizerTests } from './ValueSanitizerTests';
|
||||
import {FileSizeCheckTest} from './FileSizeCheckTest'
|
||||
import { GlobalTestHooks } from './GlobalTestHooks.Test';
|
||||
|
||||
|
||||
|
||||
export function registerTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new CoreTest('CoreTest').registerTests();
|
||||
new ESPromiseTests('ESPromiseTests').registerTests();
|
||||
new ESPromiseSchedulerTests('ESPromiseSchedulerTests').registerTests();
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "@microsoft/applicationinsights-core-js";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -5,8 +5,10 @@ import { ConnectionStringParserTests } from "./ConnectionStringParser.tests";
|
|||
import { SeverityLevelTests } from "./SeverityLevel.tests";
|
||||
import { RequestHeadersTests } from "./RequestHeaders.tests";
|
||||
import { ThrottleMgrTest } from "./ThrottleMgr.tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new ThrottleMgrTest().registerTests();
|
||||
new ApplicationInsightsTests().registerTests();
|
||||
new ExceptionTests().registerTests();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Assert, AITestClass } from "@microsoft/ai-test-framework";
|
||||
import { IConfiguration, ITelemetryPlugin, ITelemetryItem, IPlugin, IAppInsightsCore, normalizeJsName, random32, mwcRandomSeed, newId, randomValue, mwcRandom32, isNullOrUndefined, SenderPostManager, OnCompleteCallback, IPayloadData, _ISenderOnComplete, TransportType, _ISendPostMgrConfig } from "../../../src/applicationinsights-core-js"
|
||||
import { IConfiguration, ITelemetryPlugin, ITelemetryItem, IPlugin, IAppInsightsCore, normalizeJsName, random32, mwcRandomSeed, newId, randomValue, mwcRandom32, isNullOrUndefined, SenderPostManager, OnCompleteCallback, IPayloadData, _ISenderOnComplete, TransportType, _ISendPostMgrConfig, dumpObj } from "../../../src/applicationinsights-core-js"
|
||||
import { AppInsightsCore } from "../../../src/JavaScriptSDK/AppInsightsCore";
|
||||
import { IChannelControls } from "../../../src/JavaScriptSDK.Interfaces/IChannelControls";
|
||||
import { _eInternalMessageId, LoggingSeverity } from "../../../src/JavaScriptSDK.Enums/LoggingEnums";
|
||||
|
@ -19,7 +19,6 @@ export class ApplicationInsightsCoreTests extends AITestClass {
|
|||
}
|
||||
|
||||
public registerTests() {
|
||||
|
||||
this.testCase({
|
||||
name: "ApplicationInsightsCore: Initialization validates input",
|
||||
test: () => {
|
||||
|
@ -999,6 +998,30 @@ export class ApplicationInsightsCoreTests extends AITestClass {
|
|||
}
|
||||
});
|
||||
|
||||
this.testCase({
|
||||
name: 'Test Excessive unload hook detection - make sure calling getPerfMgr() does not cause excessive unload hook detection',
|
||||
test: () => {
|
||||
const appInsightsCore = new AppInsightsCore();
|
||||
const channelPlugin1 = new ChannelPlugin();
|
||||
channelPlugin1.priority = 1001;
|
||||
|
||||
const theConfig = {
|
||||
channels: [[channelPlugin1]],
|
||||
endpointUrl: "https://dc.services.visualstudio.com/v2/track",
|
||||
instrumentationKey: "",
|
||||
extensionConfig: {}
|
||||
};
|
||||
|
||||
appInsightsCore.initialize(theConfig, []);
|
||||
Assert.equal(true, appInsightsCore.isInitialized(), "Core is initialized");
|
||||
|
||||
// Send lots of notifications
|
||||
for (let lp = 0; lp < 100; lp++) {
|
||||
Assert.equal(null, appInsightsCore.getPerfMgr());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function _createBuckets(num: number) {
|
||||
// Using helper function as TypeScript 2.5.3 is complaining about new Array<number>(100).fill(0);
|
||||
let buckets: number[] = [];
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
import { Assert } from "@microsoft/ai-test-framework";
|
||||
import { _testHookMaxUnloadHooksCb } from "../../../src/JavaScriptSDK/UnloadHookContainer";
|
||||
import { dumpObj } from "@nevware21/ts-utils";
|
||||
|
||||
export class GlobalTestHooks {
|
||||
|
||||
public registerTests() {
|
||||
// Set a global maximum
|
||||
_testHookMaxUnloadHooksCb(20, (state: string, hooks: Array<any>) => {
|
||||
Assert.ok(false, "Max unload hooks exceeded [" + hooks.length + "] - " + state + " - " + dumpObj(hooks));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import '@microsoft/applicationinsights-shims';
|
||||
import { ApplicationInsightsCoreTests } from "./ApplicationInsightsCore.Tests";
|
||||
import { CookieManagerTests } from "./CookieManager.Tests";
|
||||
import { GlobalTestHooks } from "./GlobalTestHooks.Test";
|
||||
import { HelperFuncTests } from './HelperFunc.Tests';
|
||||
import { AppInsightsCoreSizeCheck } from "./AppInsightsCoreSize.Tests";
|
||||
import { EventHelperTests } from "./EventHelper.Tests";
|
||||
|
@ -12,6 +13,7 @@ import { W3cTraceParentTests } from "./W3cTraceParentTests";
|
|||
import { DynamicConfigTests } from "./DynamicConfig.Tests";
|
||||
|
||||
export function runTests() {
|
||||
new GlobalTestHooks().registerTests();
|
||||
new DynamicTests().registerTests();
|
||||
new DynamicConfigTests().registerTests();
|
||||
new ApplicationInsightsCoreTests().registerTests();
|
||||
|
|
|
@ -36,6 +36,8 @@ function _createAndUseHandler<T>(state: _IDynamicConfigHandlerState<T>, configHa
|
|||
}
|
||||
};
|
||||
|
||||
objDefine<any>(handler, "toJSON", { v: () => "WatcherHandler" + (handler.fn ? "" : "[X]") });
|
||||
|
||||
state.use(handler, configHandler);
|
||||
|
||||
return handler;
|
||||
|
|
|
@ -84,6 +84,7 @@ export const enum _eInternalMessageId {
|
|||
InvalidDurationValue = 45,
|
||||
TelemetryEnvelopeInvalid = 46,
|
||||
CreateEnvelopeError = 47,
|
||||
MaxUnloadHookExceeded = 48,
|
||||
|
||||
// User actionable
|
||||
CannotSerializeObject = 48,
|
||||
|
|
|
@ -181,7 +181,7 @@ function _addDelayedCfgListener(listeners: { rm: () => void, w: WatcherFunction<
|
|||
let theListener = _findWatcher(listeners, newWatcher).l;
|
||||
|
||||
if (!theListener) {
|
||||
theListener ={
|
||||
theListener = {
|
||||
w: newWatcher,
|
||||
rm: () => {
|
||||
let fnd = _findWatcher(listeners, newWatcher);
|
||||
|
@ -207,6 +207,36 @@ function _registerDelayedCfgListener(config: IConfiguration, listeners: { rm: ()
|
|||
});
|
||||
}
|
||||
|
||||
// Moved this outside of the closure to reduce the retained memory footprint
|
||||
function _initDebugListener(configHandler: IDynamicConfigHandler<IConfiguration>, unloadContainer: IUnloadHookContainer, notificationManager: INotificationManager, debugListener: INotificationListener) {
|
||||
// Will get recalled if any referenced config values are changed
|
||||
unloadContainer.add(configHandler.watch((details) => {
|
||||
let disableDbgExt = details.cfg.disableDbgExt;
|
||||
|
||||
if (disableDbgExt === true && debugListener) {
|
||||
// Remove any previously loaded debug listener
|
||||
notificationManager.removeNotificationListener(debugListener);
|
||||
debugListener = null;
|
||||
}
|
||||
|
||||
if (notificationManager && !debugListener && disableDbgExt !== true) {
|
||||
debugListener = getDebugListener(details.cfg);
|
||||
notificationManager.addNotificationListener(debugListener);
|
||||
}
|
||||
}));
|
||||
|
||||
return debugListener
|
||||
}
|
||||
|
||||
// Moved this outside of the closure to reduce the retained memory footprint
|
||||
function _createUnloadHook(unloadHook: IUnloadHook): IUnloadHook {
|
||||
return objDefine<IUnloadHook | any>({
|
||||
rm: () => {
|
||||
unloadHook.rm();
|
||||
}
|
||||
}, "toJSON", { v: () => "aicore::onCfgChange<" + JSON.stringify(unloadHook) + ">" });
|
||||
}
|
||||
|
||||
/**
|
||||
* @group Classes
|
||||
* @group Entrypoint
|
||||
|
@ -317,7 +347,8 @@ export class AppInsightsCore<CfgType extends IConfiguration = IConfiguration> im
|
|||
|
||||
_notificationManager = notificationManager;
|
||||
|
||||
_initDebugListener();
|
||||
// Initialize the debug listener outside of the closure to reduce the retained memory footprint
|
||||
_debugListener = _initDebugListener(_configHandler, _hookContainer, _notificationManager && _self.getNotifyMgr(), _debugListener);
|
||||
_initPerfManager();
|
||||
|
||||
_self.logger = logger;
|
||||
|
@ -444,17 +475,6 @@ export class AppInsightsCore<CfgType extends IConfiguration = IConfiguration> im
|
|||
};
|
||||
|
||||
_self.getPerfMgr = (): IPerfManager => {
|
||||
if (!_perfManager && !_cfgPerfManager) {
|
||||
_addUnloadHook(_configHandler.watch((details) => {
|
||||
if (details.cfg.enablePerfMgr) {
|
||||
let createPerfMgr = details.cfg.createPerfMgr;
|
||||
if (isFunction(createPerfMgr)) {
|
||||
_cfgPerfManager = createPerfMgr(_self, _self.getNotifyMgr());
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
return _perfManager || _cfgPerfManager || getGblPerfMgr();
|
||||
};
|
||||
|
||||
|
@ -726,11 +746,7 @@ export class AppInsightsCore<CfgType extends IConfiguration = IConfiguration> im
|
|||
unloadHook = onConfigChange(_configHandler.cfg, handler, _self.logger);
|
||||
}
|
||||
|
||||
return {
|
||||
rm: () => {
|
||||
unloadHook.rm();
|
||||
}
|
||||
}
|
||||
return _createUnloadHook(unloadHook);
|
||||
};
|
||||
|
||||
_self.getWParam = () => {
|
||||
|
@ -854,6 +870,8 @@ export class AppInsightsCore<CfgType extends IConfiguration = IConfiguration> im
|
|||
_pluginVersionString = null;
|
||||
_pluginVersionStringArr = null;
|
||||
_forceStopInternalLogPoller = false;
|
||||
_internalLogPoller = null;
|
||||
_internalLogPollerListening = false;
|
||||
}
|
||||
|
||||
function _createTelCtx(): IProcessTelemetryContext {
|
||||
|
@ -1106,40 +1124,39 @@ export class AppInsightsCore<CfgType extends IConfiguration = IConfiguration> im
|
|||
return true;
|
||||
}
|
||||
|
||||
function _initDebugListener() {
|
||||
// Lazily ensure that the notification manager is created
|
||||
!_notificationManager && _self.getNotifyMgr();
|
||||
|
||||
// Will get recalled if any referenced config values are changed
|
||||
_addUnloadHook(_configHandler.watch((details) => {
|
||||
let disableDbgExt = details.cfg.disableDbgExt;
|
||||
|
||||
if (disableDbgExt === true && _debugListener) {
|
||||
// Remove any previously loaded debug listener
|
||||
_notificationManager.removeNotificationListener(_debugListener);
|
||||
_debugListener = null;
|
||||
}
|
||||
|
||||
if (_notificationManager && !_debugListener && disableDbgExt !== true) {
|
||||
_debugListener = getDebugListener(details.cfg);
|
||||
_notificationManager.addNotificationListener(_debugListener);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
function _initPerfManager() {
|
||||
// Save the previous config based performance manager creator to avoid creating new perf manager instances if unchanged
|
||||
let prevCfgPerfMgr: (core: IAppInsightsCore, notificationManager: INotificationManager) => IPerfManager;
|
||||
|
||||
// Will get recalled if any referenced config values are changed
|
||||
_addUnloadHook(_configHandler.watch((details) => {
|
||||
let enablePerfMgr = details.cfg.enablePerfMgr;
|
||||
if (enablePerfMgr) {
|
||||
let createPerfMgr = details.cfg.createPerfMgr;
|
||||
if (prevCfgPerfMgr !== createPerfMgr) {
|
||||
if (!createPerfMgr) {
|
||||
createPerfMgr = _createPerfManager;
|
||||
}
|
||||
|
||||
if (!enablePerfMgr && _cfgPerfManager) {
|
||||
// Set the performance manager creation function if not defined
|
||||
getSetValue(details.cfg, STR_CREATE_PERF_MGR, createPerfMgr);
|
||||
prevCfgPerfMgr = createPerfMgr;
|
||||
|
||||
// Remove any existing config based performance manager
|
||||
_cfgPerfManager = null;
|
||||
}
|
||||
|
||||
// Only create the performance manager if it's not already created or manually set
|
||||
if (!_perfManager && !_cfgPerfManager && isFunction(createPerfMgr)) {
|
||||
// Create a new config based performance manager
|
||||
_cfgPerfManager = createPerfMgr(_self, _self.getNotifyMgr());
|
||||
}
|
||||
} else {
|
||||
// Remove any existing config based performance manager
|
||||
_cfgPerfManager = null;
|
||||
}
|
||||
|
||||
if (enablePerfMgr) {
|
||||
// Set the performance manager creation function if not defined
|
||||
getSetValue(details.cfg, STR_CREATE_PERF_MGR, _createPerfManager);
|
||||
|
||||
// Clear the previous cached value so it can be GC'd
|
||||
prevCfgPerfMgr = null;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under the MIT License.
|
||||
import dynamicProto from "@microsoft/dynamicproto-js";
|
||||
import { IPromise, createAllPromise, createPromise, doAwaitResponse } from "@nevware21/ts-async";
|
||||
import { arrForEach, arrIndexOf, objDefine, scheduleTimeout } from "@nevware21/ts-utils";
|
||||
import { ITimerHandler, arrForEach, arrIndexOf, objDefine, safe, scheduleTimeout } from "@nevware21/ts-utils";
|
||||
import { createDynamicConfig } from "../Config/DynamicConfig";
|
||||
import { IConfiguration } from "../JavaScriptSDK.Interfaces/IConfiguration";
|
||||
import { INotificationListener } from "../JavaScriptSDK.Interfaces/INotificationListener";
|
||||
|
@ -18,17 +18,37 @@ const defaultValues = {
|
|||
perfEvtsSendAll: false
|
||||
};
|
||||
|
||||
function _runListeners(listeners: INotificationListener[], name: string, isAsync: boolean, callback: (listener: INotificationListener) => void) {
|
||||
interface IAsyncNotifications {
|
||||
h: ITimerHandler;
|
||||
cb: Array<{ fn: (listener: INotificationListener) => void, arg: INotificationListener }>
|
||||
}
|
||||
|
||||
function _runScheduledListeners(asyncNotifications: IAsyncNotifications) {
|
||||
asyncNotifications.h = null;
|
||||
let callbacks = asyncNotifications.cb;
|
||||
asyncNotifications.cb = [];
|
||||
arrForEach(callbacks, (cb) => {
|
||||
// Run the listener in a try-catch to ensure that a single listener failing doesn't prevent the others from running
|
||||
safe(cb.fn, [cb.arg]);
|
||||
});
|
||||
}
|
||||
|
||||
// This function is used to combine the logic of running the listeners and handling the async notifications so that they don't
|
||||
// create multiple timers if there are multiple async listeners.
|
||||
function _runListeners(listeners: INotificationListener[], name: string, asyncNotifications: IAsyncNotifications | null, callback: (listener: INotificationListener) => void) {
|
||||
arrForEach(listeners, (listener) => {
|
||||
if (listener && listener[name]) {
|
||||
if (isAsync) {
|
||||
scheduleTimeout(() => callback(listener), 0);
|
||||
if (asyncNotifications) {
|
||||
// Schedule the callback to be called after the current call stack has cleared.
|
||||
asyncNotifications.cb.push({
|
||||
fn: callback,
|
||||
arg: listener
|
||||
});
|
||||
|
||||
asyncNotifications.h = asyncNotifications.h || scheduleTimeout(_runScheduledListeners, 0, asyncNotifications);
|
||||
} else {
|
||||
try {
|
||||
callback(listener);
|
||||
} catch (e) {
|
||||
// Catch errors to ensure we don't block sending the requests
|
||||
}
|
||||
// Run the listener in a try-catch to ensure that a single listener failing doesn't prevent the others from running
|
||||
safe(callback, [listener]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -44,7 +64,11 @@ export class NotificationManager implements INotificationManager {
|
|||
let perfEvtsSendAll: boolean;
|
||||
let unloadHandler: IUnloadHook;
|
||||
let _listeners: INotificationListener[] = [];
|
||||
|
||||
let _asyncNotifications: IAsyncNotifications = {
|
||||
h: null,
|
||||
cb: []
|
||||
};
|
||||
|
||||
let cfgHandler = createDynamicConfig(config, defaultValues);
|
||||
|
||||
unloadHandler = cfgHandler.watch((details) => {
|
||||
|
@ -77,7 +101,7 @@ export class NotificationManager implements INotificationManager {
|
|||
* @param events - The array of events that have been sent.
|
||||
*/
|
||||
_self.eventsSent = (events: ITelemetryItem[]): void => {
|
||||
_runListeners(_listeners, STR_EVENTS_SENT, true, (listener) => {
|
||||
_runListeners(_listeners, STR_EVENTS_SENT, _asyncNotifications, (listener) => {
|
||||
listener.eventsSent(events);
|
||||
});
|
||||
};
|
||||
|
@ -89,7 +113,7 @@ export class NotificationManager implements INotificationManager {
|
|||
* constant should be used to check the different values.
|
||||
*/
|
||||
_self.eventsDiscarded = (events: ITelemetryItem[], reason: number): void => {
|
||||
_runListeners(_listeners, STR_EVENTS_DISCARDED, true, (listener) => {
|
||||
_runListeners(_listeners, STR_EVENTS_DISCARDED, _asyncNotifications, (listener) => {
|
||||
listener.eventsDiscarded(events, reason);
|
||||
});
|
||||
};
|
||||
|
@ -100,7 +124,7 @@ export class NotificationManager implements INotificationManager {
|
|||
* @param isAsync - A flag which identifies whether the requests are being sent in an async or sync manner.
|
||||
*/
|
||||
_self.eventsSendRequest = (sendReason: number, isAsync: boolean): void => {
|
||||
_runListeners(_listeners, STR_EVENTS_SEND_REQUEST, isAsync, (listener) => {
|
||||
_runListeners(_listeners, STR_EVENTS_SEND_REQUEST, isAsync ? _asyncNotifications : null, (listener) => {
|
||||
listener.eventsSendRequest(sendReason, isAsync);
|
||||
});
|
||||
};
|
||||
|
@ -110,7 +134,7 @@ export class NotificationManager implements INotificationManager {
|
|||
|
||||
// Send all events or only parent events
|
||||
if (perfEvtsSendAll || !perfEvent.isChildEvt()) {
|
||||
_runListeners(_listeners, STR_PERF_EVENT, false, (listener) => {
|
||||
_runListeners(_listeners, STR_PERF_EVENT, null, (listener) => {
|
||||
if (perfEvent.isAsync) {
|
||||
scheduleTimeout(() => listener.perfEvent(perfEvent), 0);
|
||||
} else {
|
||||
|
@ -123,7 +147,7 @@ export class NotificationManager implements INotificationManager {
|
|||
|
||||
_self.offlineEventsStored = (events: ITelemetryItem[]): void => {
|
||||
if (events && events.length) {
|
||||
_runListeners(_listeners, STR_OFFLINE_STORE, true, (listener) => {
|
||||
_runListeners(_listeners, STR_OFFLINE_STORE, _asyncNotifications, (listener) => {
|
||||
listener.offlineEventsStored(events);
|
||||
});
|
||||
}
|
||||
|
@ -131,7 +155,7 @@ export class NotificationManager implements INotificationManager {
|
|||
|
||||
_self.offlineBatchSent = (batch: IPayloadData): void => {
|
||||
if (batch && batch.data) {
|
||||
_runListeners(_listeners, STR_OFFLINE_SENT, true, (listener) => {
|
||||
_runListeners(_listeners, STR_OFFLINE_SENT, _asyncNotifications, (listener) => {
|
||||
listener.offlineBatchSent(batch);
|
||||
});
|
||||
}
|
||||
|
@ -140,7 +164,7 @@ export class NotificationManager implements INotificationManager {
|
|||
_self.offlineBatchDrop = (cnt: number, reason?: number): void => {
|
||||
if (cnt > 0) {
|
||||
let rn = reason || 0; // default is unknown
|
||||
_runListeners(_listeners, STR_OFFLINE_DROP, true, (listener) => {
|
||||
_runListeners(_listeners, STR_OFFLINE_DROP, _asyncNotifications, (listener) => {
|
||||
listener.offlineBatchDrop(cnt, rn);
|
||||
});
|
||||
}
|
||||
|
@ -152,10 +176,15 @@ export class NotificationManager implements INotificationManager {
|
|||
unloadHandler && unloadHandler.rm();
|
||||
unloadHandler = null;
|
||||
_listeners = [];
|
||||
|
||||
// Clear any async listener
|
||||
_asyncNotifications.h && _asyncNotifications.h.cancel();
|
||||
_asyncNotifications.h = null;
|
||||
_asyncNotifications.cb = [];
|
||||
};
|
||||
|
||||
let waiting: IPromise<void>[];
|
||||
_runListeners(_listeners, "unload", false, (listener) => {
|
||||
_runListeners(_listeners, "unload", null, (listener) => {
|
||||
let asyncUnload = listener.unload(isAsync);
|
||||
if (asyncUnload) {
|
||||
if (!waiting) {
|
||||
|
|
|
@ -7,6 +7,9 @@ import { IDiagnosticLogger } from "../JavaScriptSDK.Interfaces/IDiagnosticLogger
|
|||
import { ILegacyUnloadHook, IUnloadHook } from "../JavaScriptSDK.Interfaces/IUnloadHook";
|
||||
import { _throwInternal } from "./DiagnosticLogger";
|
||||
|
||||
let _maxHooks: number | undefined;
|
||||
let _hookAddMonitor: (state: string, hooks: Array<ILegacyUnloadHook | IUnloadHook>) => void | undefined;
|
||||
|
||||
/**
|
||||
* Interface which identifiesAdd this hook so that it is automatically removed during unloading
|
||||
* @param hooks - The single hook or an array of IInstrumentHook objects
|
||||
|
@ -16,6 +19,17 @@ export interface IUnloadHookContainer {
|
|||
run: (logger?: IDiagnosticLogger) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test hook for setting the maximum number of unload hooks and calling a monitor function when the hooks are added or removed
|
||||
* This allows for automatic test failure when the maximum number of unload hooks is exceeded
|
||||
* @param maxHooks - The maximum number of unload hooks
|
||||
* @param addMonitor - The monitor function to call when hooks are added or removed
|
||||
*/
|
||||
export function _testHookMaxUnloadHooksCb(maxHooks?: number, addMonitor?: (state: string, hooks: Array<ILegacyUnloadHook | IUnloadHook>) => void) {
|
||||
_maxHooks = maxHooks;
|
||||
_hookAddMonitor = addMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a IUnloadHookContainer which can be used to remember unload hook functions to be executed during the component unloading
|
||||
* process.
|
||||
|
@ -37,11 +51,18 @@ export function createUnloadHookContainer(): IUnloadHookContainer {
|
|||
_throwInternal(logger, eLoggingSeverity.WARNING, _eInternalMessageId.PluginException, "Unloading:" + dumpObj(e));
|
||||
}
|
||||
});
|
||||
|
||||
if (_maxHooks && oldHooks.length > _maxHooks) {
|
||||
_hookAddMonitor ? _hookAddMonitor("doUnload", oldHooks) : _throwInternal(null, eLoggingSeverity.CRITICAL, _eInternalMessageId.MaxUnloadHookExceeded, "Max unload hooks exceeded. An excessive number of unload hooks has been detected.");
|
||||
}
|
||||
}
|
||||
|
||||
function _addHook(hooks: IUnloadHook | IUnloadHook[] | Iterator<IUnloadHook> | ILegacyUnloadHook | ILegacyUnloadHook[] | Iterator<ILegacyUnloadHook>) {
|
||||
if (hooks) {
|
||||
arrAppend(_hooks, hooks);
|
||||
if (_maxHooks && _hooks.length > _maxHooks) {
|
||||
_hookAddMonitor ? _hookAddMonitor("Add", _hooks) : _throwInternal(null, eLoggingSeverity.CRITICAL, _eInternalMessageId.MaxUnloadHookExceeded, "Max unload hooks exceeded. An excessive number of unload hooks has been detected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ export { getDebugListener, getDebugExt } from "./JavaScriptSDK/DbgExtensionUtils
|
|||
export { TelemetryInitializerFunction, ITelemetryInitializerHandler, ITelemetryInitializerContainer } from "./JavaScriptSDK.Interfaces/ITelemetryInitializers";
|
||||
export { createUniqueNamespace } from "./JavaScriptSDK/DataCacheHelper";
|
||||
export { UnloadHandler, IUnloadHandlerContainer, createUnloadHandlerContainer } from "./JavaScriptSDK/UnloadHandlerContainer";
|
||||
export { IUnloadHookContainer, createUnloadHookContainer } from "./JavaScriptSDK/UnloadHookContainer";
|
||||
export { IUnloadHookContainer, createUnloadHookContainer, _testHookMaxUnloadHooksCb } from "./JavaScriptSDK/UnloadHookContainer";
|
||||
export { ITelemetryUpdateState } from "./JavaScriptSDK.Interfaces/ITelemetryUpdateState";
|
||||
export { ITelemetryUnloadState } from "./JavaScriptSDK.Interfaces/ITelemetryUnloadState";
|
||||
export { IDistributedTraceContext } from "./JavaScriptSDK.Interfaces/IDistributedTraceContext";
|
||||
|
|
Загрузка…
Ссылка в новой задаче