Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Fix issues related to dynamic config listeners during unloading #2058

Merged
merged 2 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions AISKU/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ See [Breaking Changes](./BETA_BREAKING_CHANGES.md)
| Version | Full Size | Raw Minified | GZip Size
|---------|-----------|--------------|-------------
| [<nightly3>](https://github.com/microsoft/ApplicationInsights-JS/tree/main/AISKU) | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.3-nightly3.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.3-nightly3.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.3-nightly3.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.3-nightly3.min.js.svg?compression=gzip&softmax=30000&max=35000)
| <nightly> | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.min.js.svg?compression=gzip&softmax=30000&max=35000)
| 2.8.12: | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.min.js.svg?compression=gzip&softmax=30000&max=35000)
| 3.0.0: | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.3.0.0.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.3.0.0.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.3.0.0.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.3.0.0.min.js.svg?compression=gzip&softmax=30000&max=35000)
| [<nightly>](https://github.com/microsoft/ApplicationInsights-JS/tree/master/AISKU) | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/nightly/ai.2-nightly.min.js.svg?compression=gzip&softmax=30000&max=35000)
| [2.8.12](https://github.com/microsoft/ApplicationInsights-JS/tree/master/AISKU): | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.12.min.js.svg?compression=gzip&softmax=30000&max=35000)
| 2.8.11: | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.11.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.11.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.11.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.11.min.js.svg?compression=gzip&softmax=30000&max=35000)
| 2.8.10: | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.10.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.10.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.10.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.10.min.js.svg?compression=gzip&softmax=30000&max=35000)
| 2.8.9: | [![full size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.9.js.svg?label=full%20size&color=blue)](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.9.js.svg?label=full%20size&color=blue)| ![minified size size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.9.min.js.svg?label=minified%20size&color=darkorchid) | ![gzip size](https://img.badgesize.io/https://js.monitor.azure.com/scripts/b/ai.2.8.9.min.js.svg?compression=gzip&softmax=30000&max=35000)
Expand Down
6 changes: 3 additions & 3 deletions AISKU/Tests/Manual/HelloWorld.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ <h1 class="display-4">Welcome</h1>
<textarea id="log" style="width:45%; min-height: 400px;"></textarea>
<textarea id="cfg" style="width:50%; min-height: 400px;"></textarea>
</div>
</div>

<script>
//Promise = null;
var _message = {
log: "",
cfg: ""
Expand All @@ -69,7 +69,7 @@ <h1 class="display-4">Welcome</h1>
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> -->

<!-- <script src="file://./ai.2.8.0.js"></script> -->
<script src="http://localhost:9001/AISKU/browser/es5/ai.2.js"></script>
<script src="http://localhost:9001/AISKU/browser/es5/ai.3.js"></script>
<!-- <script src="https://js.monitor.azure.com/scripts/b/ai.2.7.4.js" crossorigin="anonymous"></script> -->
<!-- <script src="https://js.monitor.azure.com/scripts/b/ai.2.8.0.js" crossorigin="anonymous"></script> -->
<!-- <script>
Expand All @@ -83,7 +83,7 @@ <h1 class="display-4">Welcome</h1>
// ld: 0, // Defines the load delay (in ms) before attempting to load the sdk. -1 = block page load and add to head. (default) = 0ms load after timeout,
// useXhr: 1, // Use XHR instead of fetch to report failures (if available),
// crossOrigin: "anonymous", // When supplied this will add the provided value as the cross origin attribute on the script tag
// onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument -- the sdk instance (DO NOT ADD anything to the sdk.queue -- As they won't get called)
// onInit: null, // Once the application insights instance has loaded and initialized this callback function will be called with 1 argument - the sdk instance (DO NOT ADD anything to the sdk.queue - As they won't get called)
cfg: { // Application Insights Configuration
connectionString: "InstrumentationKey=" + instrumentationKey + ";IngestionEndpoint=http://localhost:9001",
//extensions: [reactPlugin],
Expand Down
8 changes: 4 additions & 4 deletions AISKU/Tests/Unit/src/AISKUSize.Tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { Snippet } from "../../../src/Snippet";
import { utlRemoveSessionStorage } from "@microsoft/applicationinsights-common";

export class AISKUSizeCheck extends AITestClass {
private readonly MAX_RAW_SIZE = 119;
private readonly MAX_BUNDLE_SIZE = 119;
private readonly MAX_RAW_DEFLATE_SIZE = 47;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 47;
private readonly MAX_RAW_SIZE = 122;
private readonly MAX_BUNDLE_SIZE = 122;
private readonly MAX_RAW_DEFLATE_SIZE = 50;
private readonly MAX_BUNDLE_DEFLATE_SIZE = 50;
private readonly rawFilePath = "../dist/es5/applicationinsights-web.min.js";
// Automatically updated by version scripts
private readonly currentVer = "3.0.0";
Expand Down
3 changes: 2 additions & 1 deletion AISKU/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@
"@microsoft/applicationinsights-core-js": "3.0.0",
"@microsoft/applicationinsights-dependencies-js": "3.0.0",
"@microsoft/applicationinsights-properties-js": "3.0.0",
"@nevware21/ts-utils": ">= 0.9.4 < 2.x"
"@nevware21/ts-utils": ">= 0.9.5 < 2.x",
"@nevware21/ts-async": ">= 0.2.4 < 2.x"
},
"license": "MIT"
}
79 changes: 66 additions & 13 deletions AISKU/src/AISku.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ import {
AppInsightsCore, IAppInsightsCore, IChannelControls, IConfigDefaults, IConfiguration, ICookieMgr, ICustomProperties, IDiagnosticLogger,
IDistributedTraceContext, IDynamicConfigHandler, ILoadedPlugin, INotificationManager, IPlugin, ITelemetryInitializerHandler,
ITelemetryItem, ITelemetryPlugin, ITelemetryUnloadState, IUnloadHook, UnloadHandler, WatcherFunction, _eInternalMessageId,
_throwInternal, addPageHideEventListener, addPageUnloadEventListener, arrForEach, arrIndexOf, cfgDfValidate, createDynamicConfig,
createUniqueNamespace, doPerf, eLoggingSeverity, hasDocument, hasWindow, isArray, isFunction, isNullOrUndefined, isReactNative, isString,
mergeEvtNamespace, objForEachKey, onConfigChange, proxyAssign, proxyFunctions, removePageHideEventListener,
removePageUnloadEventListener
_throwInternal, addPageHideEventListener, addPageUnloadEventListener, cfgDfValidate, createDynamicConfig, createUniqueNamespace, doPerf,
eLoggingSeverity, hasDocument, hasWindow, isArray, isFunction, isNullOrUndefined, isReactNative, isString, mergeEvtNamespace,
onConfigChange, proxyAssign, proxyFunctions, removePageHideEventListener, removePageUnloadEventListener
} from "@microsoft/applicationinsights-core-js";
import {
AjaxPlugin as DependenciesPlugin, DependencyInitializerFunction, DependencyListenerFunction, IDependencyInitializerHandler,
IDependencyListenerHandler
} from "@microsoft/applicationinsights-dependencies-js";
import { PropertiesPlugin } from "@microsoft/applicationinsights-properties-js";
import { objDefine, strIndexOf, throwUnsupported } from "@nevware21/ts-utils";
import { IPromise, createPromise } from "@nevware21/ts-async";
import { arrForEach, arrIndexOf, objDefine, objForEachKey, strIndexOf, throwUnsupported } from "@nevware21/ts-utils";
import { IApplicationInsights } from "./IApplicationInsights";
import {
STR_ADD_TELEMETRY_INITIALIZER, STR_CLEAR_AUTHENTICATED_USER_CONTEXT, STR_EVT_NAMESPACE, STR_GET_COOKIE_MGR, STR_GET_PLUGIN,
Expand Down Expand Up @@ -169,12 +169,36 @@ export class AppInsightsSku implements IApplicationInsights {

_self.snippet = snippet;

_self.flush = (async: boolean = true) => {
_self.flush = (async: boolean = true, callBack?: () => void) => {
let result: void | IPromise<void>;

doPerf(_core, () => "AISKU.flush", () => {
if (async && !callBack) {
result = createPromise((resolve) => {
callBack = resolve;
});
}

let waiting = 1;
const flushDone = () => {
waiting --;
if (waiting === 0) {
callBack();
}
};

arrForEach(_core.getChannels(), channel => {
channel.flush(async);
if (channel) {
waiting++;
channel.flush(async, flushDone);
}
});

// decrement the initial "waiting"
flushDone();
}, null, async);

return result;
};

_self.onunloadFlush = (async: boolean = true) => {
Expand Down Expand Up @@ -352,8 +376,15 @@ export class AppInsightsSku implements IApplicationInsights {
return _sender;
};

_self.unload = (isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void => {
_self.unload = (isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void | IPromise<ITelemetryUnloadState> => {
let unloadDone = false;
let result: IPromise<ITelemetryUnloadState>;
if (isAsync && !unloadComplete) {
result = createPromise<ITelemetryUnloadState>((resolve) => {
// Set the callback to the promise resolve callback
unloadComplete = resolve;
});
}

function _unloadCallback(unloadState: ITelemetryUnloadState) {
if (!unloadDone) {
Expand All @@ -369,6 +400,8 @@ export class AppInsightsSku implements IApplicationInsights {
_removePageEventHandlers();

_core.unload && _core.unload(isAsync, _unloadCallback, cbTimeout);

return result;
};

proxyFunctions(_self, _analyticsPlugin, [
Expand Down Expand Up @@ -602,11 +635,20 @@ export class AppInsightsSku implements IApplicationInsights {
// Misc

/**
* Manually trigger an immediate send of all telemetry still in the buffer.
* @param [async=true]
* @memberof Initialization
* Attempt to flush data immediately; If executing asynchronously (the default) and
* you DO NOT pass a callback function then a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
* will be returned which will resolve once the flush is complete. The actual implementation of the `IPromise`
* will be a native Promise (if supported) or the default as supplied by [ts-async library](https://github.com/nevware21/ts-async)
* @param async - send data asynchronously when true
* @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
* If the caller doesn't return true the caller should assume that it may never be called.
* @returns - If a callback is provided `true` to indicate that callback will be called after the flush is complete otherwise the caller
* should assume that any provided callback will never be called, Nothing or if occurring asynchronously a
* [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) which will be resolved once the unload is complete,
* the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) will only be returned when no callback is provided
* and async is true.
*/
public flush(async: boolean = true) {
public flush(async?: boolean, callBack?: () => void): void | IPromise<void> {
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
}

Expand Down Expand Up @@ -673,8 +715,19 @@ export class AppInsightsSku implements IApplicationInsights {
* approach is to create a new instance and initialize that instance.
* This is due to possible unexpected side effects caused by plugins not supporting unload / teardown, unable
* to successfully remove any global references or they may just be completing the unload process asynchronously.
* If you pass isAsync as true and do not provide
* If you pass isAsync as `true` (also the default) and DO NOT pass a callback function then an [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
* will be returned which will resolve once the unload is complete. The actual implementation of the `IPromise`
* will be a native Promise (if supported) or the default as supplied by [ts-async library](https://github.com/nevware21/ts-async)
* @param isAsync - Can the unload be performed asynchronously (default)
* @param unloadComplete - An optional callback that will be called once the unload has completed
* @param cbTimeout - An optional timeout to wait for any flush operations to complete before proceeding with the
* unload. Defaults to 5 seconds.
* @return Nothing or if occurring asynchronously a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
* which will be resolved once the unload is complete, the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
* will only be returned when no callback is provided and isAsync is true
*/
public unload(isAsync?: boolean, unloadComplete?: () => void): void {
public unload(isAsync?: boolean, unloadComplete?: (unloadState: ITelemetryUnloadState) => void, cbTimeout?: number): void | IPromise<ITelemetryUnloadState> {
// @DynamicProtoStub -- DO NOT add any code as this will be removed during packaging
return null;
}
Expand Down
Loading