Adding Worknotes From a Script (ServiceNow)

I recently had a need to add work notes to a bunch of old incidents (to let the users know that they had changed and why they had been changed). My first approach was just to add a record to the sys_journal_field table.

At first blush, that seemed to work, but then a co-worker pointed out that the work note was showing up in the history tab with the wrong user, and at the wrong time.

It appears that the automation responsible for populating work notes into the activities feed in the history tab didn’t like me just inserting a record into that table.

I ended up using this code, which seems to do the trick of getting the work note into the sys_journal_field table, and pushing it into the activities feed correctly as well.

incidents['work_notes'].setJournalEntry("The text you want to appear in your work note...);

Impersonating a user from a server script (ServiceNow)

I recently needed to add a bunch of work notes to old incidents, but the comments needed to show up as being posted by someone else. This worked quite handily:

var impUser = new GlideImpersonate();
impUser.impersonate('6816f79cc0a8012341c5a33be123beaa1');

The sys_id in the code will obviously need to be changed to the user in your environment that you’re wanting to impersonate.

If Statements Have Their Own Scope

I just ran into a bug that was the result of thinking that the block inside the body of an if statement had the same scope as the code outside of the if statement.

To clarify, the ‘{}’ in an if statement has its one scope, meaning that it can see the variables from the code outside of the ‘{}’, but that that exterior code is unable to see into the scope of the if statement.

Return Statements & Adding Event Listeners

I’ve been working with TCP connections lately, which means that upon connection from the client, my server needs to create a bunch of event listeners for things like .on(‘data’, and .on(‘timeout’

I also need to go through some logic to determine what I should do after connection, but before data or timeout. In my first pass, I created the event listeners towards the bottom of the .on(‘connection’ function.

That worked great until I started using return statements to change the flow inside of the .on(‘connection’ function. Once I did that, I started running into issues because the return statement resulted in the event listeners never being declared.

The lesson there for me is that I’m nearly always going to be best off setting up an event listener earlier rather than later. A niaeve concern might be that the on data listener will fire off before you get to the rest of your on connect function, but all the on data listener does is let stuff be placed on the event table, and then eventually be moved down to the event queue.

Nothing will be pulled off of the event queue though until the current function has finished running. So, you’re generally going to be just fine…unless maybe your current function is an async/await function, in which case it is possible that you’ll set up the event listeners, and then shift the function to the event table, allowing the on data listeners to fire off and get pulled onto the call stack before the original function resolves its asynchronous call and is placed back on the call stack.

Layers inside of layers, so my revised rule of thumb is to place any event listeners right after my await call. I hope that is helpful!

Async/Await Performance Implications – Part 2

In my last post, I discussed the fact that Async/Await pushes the async function onto the event table when the executing thread hits an await call. On the face of it, that means that a program using async/await doesn’t ‘freeze up’ when an asynchronous operation occurs.

I also pointed out that while the whole program doesn’t freeze, the async function is paused while it waits on the await line.

The next question is what that last bit means from a performance standpoint. Here is an example piece of code using callbacks, and setTimeout to simulate an API call or other asynchronous event:

const timeoutFunction = () => {
    setTimeout(()=> {
        console.log("Done");
    }, 5000)

    setTimeout(()=> {
        console.log("Done");
    }, 5000)

    setTimeout(()=> {
        console.log("Done");
    }, 5000)
}
timeoutFunction();

As far as output goes, there is a 5-second pause, and then three instances of “Done” being logged out right away, one right after the other.

Contrast that with this code:

const asyncTimeout = () => {
    return new Promise(function(resolve, reject) {
        setTimeout(resolve, 5000);
    }).then(() => {
        console.log("Done");
    })
}

const testAsync = async () => {
    await asyncTimeout();
    await asyncTimeout();
    await asyncTimeout();
}

testAsync();

This second block of code results in a 5-second pause, the logging of “Done”, another 5-second pause, the logging of “Done”, another 5-second pause, and then finally the third logging of “Done”.

Much like the second block of code in my last blog post, we can see that inside of the async function, execution is paused at each await statement, which means that you have 3 separate, 5-second pauses as compared to the first code-block using callback functions, in which the three, 5-second pauses have a nearly 100% overlap.

In summary:
As most of you have no-doubt already deduced, using async/await for a single asynchronous call has no performance hit against doing that same asynchronous operation as a callback.

When doing multiple asynchronous operations in a single function, if the asynchronous calls build on each other (meaning that data from the first call is needed to make the second call), then you lose nothing performance-wise by using async/await, and likely dramatically simplify how you construct your code.

However, if you need to make multiple un-related asynchronous calls, then you’re better off not putting them all in the same async function because doing so eliminates any overlap in the wait for the asynchronous calls to report back.

Async/Await Performance Implications

It seems like every time I come across a explanation of Async/Await in JavaScript, the author cautions against using it because it ‘can slow things down because your code has to wait for the await call to finish before it can move forward’ or something to that effect.

That statement has always made me nervous. I’m at a point in my current project where it would be really convenient to use async/await, but I didn’t want to do that if it was going to result in my entire application freezing for a second or two while the await statement is resolved.

That seemed very unlikely, but I decided it was time to do some experimenting to make sure that I understood just exactly where the boundry of the performance hit started and ended.

Here is my first experiment:

const { Resolver } = require('dns').promises;
const resolver = new Resolver();

const ip = '204.79.197.212';

const resolveDNS = async (ip) => {
    try {
        let hostname = await resolver.reverse(ip);
        console.log(hostname);
    } catch (error) {
        console.log("Error: " + error);
    }
    
}

resolveDNS(ip);
console.log("Hey there.")

The code is just using the built-in NodeJS dns library to do a reverse lookup on an ip address that corresponds to hotmail.com.

If execution really froze the way some of those internet posts seemed to imply it might be doing, then the output would have been the hostname, followed by the “Hey there.” console.log.

Actual Output:
Hey there.
[ ‘a-0010.a-msedge.net’ ]

That’s very good, because it means that ‘everything’ doesn’t freeze up while waiting for the reverse dns call to resolve. Instead, it looks like once the code hits the await statement, it just shifts that function onto the event table where it waits until the dns query resolves, at which point it’s placed onto the event queue.

In the meantime though, the program is free to continue on executing unrelated pieces of code while it waits.

I next ran this experiment:

const { Resolver } = require('dns').promises;
const resolver = new Resolver();

const ip = '204.79.197.212';
const ip2 = '204.79.197.211'

const resolveDNS = async (ip, ip2) => {
    try {
        let hostname = await resolver.reverse(ip);
        console.log(hostname);
        let hostname2 = await resolver.reverse(ip2);
        console.log(hostname2); 
    } catch (error) {
        console.log("Error: " + error);
    }
    
}

for(let i=0; i<5; i++) {
    resolveDNS(ip, ip2);
}

console.log("Hey there.")

Actual Output:
Hey there.
[ 'a-0010.a-msedge.net' ]
[ 'a-0010.a-msedge.net' ]
[ 'a-0010.a-msedge.net' ]
[ 'a-0010.a-msedge.net' ]
[ 'a-0010.a-msedge.net' ]
[ 'a-0009.a-msedge.net' ]
[ 'a-0009.a-msedge.net' ]
[ 'a-0009.a-msedge.net' ]
[ 'a-0009.a-msedge.net' ]
[ 'a-0009.a-msedge.net' ]

Again, it the "Hey there." statement is being run before any of the dns queries are resolved. It's interesting though that all of the '0010' queries are resolving before any of the '0009' queries show up.

That indicates to me that the entire stack isn't being shifted onto the event table when execution hits the 'await'. Rather, just the 'async' function is being shifted to the event table, which allows the for loop to continue to the next iteration.

So we load up the event table with 5 calls to resolve the first ip address. Then we log out the "Hey there." statement. Then the first ip query resolves, and the async function is moved down to the event queue and then onto the call stack.

That first lookup (a '0010') is printed, and then the code hits the second 'await' line and that function is moved back onto the event table to wait while the query on the second ip address is resolved.

By that point, the other 4 queries on the first ip address have all resolved and been shifted down to the event queue and then into the call stack in turn.

They each then get to the second 'await' statement and get shifted back onto the event table to wait for the resolution on the lookup for the second ip address.

At this point, the "Hey there." has been logged, and the 5 '0010' lookups have also been logged to the console. Shortly after that, events are registered indicating that the queries for the second ip address are coming back, and each of those functions are shifted down to the event queue and then onto the call stack so that the '0009' statements can be logged.

So, with those two code snippets we've proved that when code hits an 'await' statement, it doesn't freeze all execution, just execution of the async function containing the 'await' statement. I'm already over my word-count target for this blog post, so next week I'll expound on what all of this means and where it's safe to use async/await, and where doing so will potentially result in a performance hit.

Pretty Print Code on WordPress

You may have noticed that my code snippets used to be very ugly, and lately are less-so.

That is because I found out about pretty-print.

There are a few different options for doing pretty-print, but I got started based on this blog post. If you do a find for “How to Write Code Snippets in your Blog”, you’ll find the right spot without too much problem

SMTP Standard(s)

I recently had occasion to need to learn more about how SMTP works. It’s interesting sometimes how you can look, and look, and look without finding anything that explains what you need to understand at the right level, and then all of a sudden you find a ton of different resources that are perfect.

For anyone who is in the same boat, it appears that RFC5321 is the correct standard that deals with SMTP. Keep in mind that there is errata to the standard, and that it links out to dozens of other standards, so it’s not something that is particularly fast or easy to digest.

I really, really liked the description I found here of how SMTP works at a high level.

Logging objects in NodeJS

I’ve logged objects out to the console previously and had them show up, but today I logged on object out and got “[Object]” instead of the key value pairs I was expecting.

It turns out that NodeJS will only log up to two levels of nesting. If you want to log out on object with more than two levels of nesting, then the best bet is to stringify it.

Like so:

console.log(JSON.stringify(obj, null, 2))

That will indent the levels for you and everything. Hat tip to https://nodejs.dev/how-to-log-an-object-in-nodejs for teaching me that.