-
Notifications
You must be signed in to change notification settings - Fork 120
streamingInvocationContext.onCanceled called out of order when modifying stream parameters #6483
Description
Provide required information needed to triage your issue
Your Environment
- Platform [PC desktop, Mac, iOS, Office on the web]: Occurs on PC desktop and Mac
- Host [Excel, Word, PowerPoint, etc.]: Excel
- Office version number: Latest for Microsoft 365 subscription on each platform
- Operating System: Windows / macOS
- Browser (if using Office on the web): N/A
Expected behavior
I have a pretty straightforward streaming function that gives me access to an internal array of logger messages for debugging purposes. The function takes a parameter that allows me to change the logger level if need be.
So I could write:
=loggerStream() to get logger messages at whatever the default is ("Debug" in development, "Error" in production)
or:
=loggerStream("Trace") to change the logger level and get all subsequent messages at or above the "Trace" level.
Because of the simple nature of this stream, access is mutually exclusive; I don't allow multiple instances. If an attempt is made to use a second instance while the first is still active, I simply show a "Sorry, one at a time..." error message.
What I expect to happen is that, if I setup =loggerStream() and then, later, add a parameter and setup =loggerStream("Trace") by editing the original cell, the streamingInvocationContext.onCanceled method I setup will be called first to tear down the original function call before I setup the new one.
Current behavior
What is happening instead is that the new function call is installed first (resulting in an error) before the original function call is canceled. I have to delete the original first (to force cancelation) before putting in the modified call.
Steps to reproduce
- This is an approximation of the function implementation:
let streamInstalled = false;
function loggerStream(logLevel: string | null, streamingInvocationContext: StreamingInvocationContext): void {
if (!streamInstalled) {
streamInstalled = true;
streamingInvocationContext.onCanceled = () => {
streamInstalled = false;
};
streamingInvocationContext.setResult([[`Stream installed at ${logLevel ?? "default"} log level.`]]);
} else {
streamingInvocationContext.setResult([["Sorry, one at a time..."]]);
}
}
CustomFunctions.associate("loggerStream", loggerStream);- The JSON configuration entry looks like this:
{
"id": "loggerStream",
"name": "loggerStream",
"parameters": [
{
"name": "logLevel",
"type": "string",
"dimensionality": "scalar",
"optional": true
}
],
"result": {
"type": "string",
"dimensionality": "matrix"
},
"options": {
"requiresAddress": false,
"requiresParameterAddresses": false,
"excludeFromAutoComplete": true,
"volatile": false,
"stream": true
}
}- Add
=loggerStream()to any cell. You should see "Stream installed at default log level.". - Delete the contents of the cell.
- Add
=loggerStream("Trace")to any cell. You should see "Stream installed at Trace log level.". - Delete the contents of the cell.
- Add
=loggerStream()to any cell. You should see "Stream installed at default log level.". - Edit the cell, changing it to
=loggerStream("Trace"). You should see "Sorry, one at a time...".
Link to live example(s)
The above should be sufficient.
Provide additional details
None.
Context
For me, it's a minor aggravation, as it's my only use of streaming and it's for debugging only. However, I could easily imagine an environment where a stream (e.g., data from IoT devices) is streaming to a spreadsheet, and the complexity is such that the parameters passed to the stream mean that only one instance is viable, and editing the parameters in an existing streaming call would generate a message like the above. In short, where editing a stream currently results in adding the new one and then canceling the old one, it should cancel first then add.
Useful logs
None.