[Bro-Dev] 'async' update and proposal

Johanna Amann johanna at icir.org
Fri Jan 26 21:25:30 PST 2018


> I don't think skipping "async" this would be a big deal for anything,
> as the cases where the new behaviour may actually lead to significant
> differences should be rare.

After pondering this for a while I am a bit afraid that skipping async
completely might lead to quite hard to debug problems in scripts.

At the moments, Bro scripts are basically predictable - e.g. once an event
is executed you know that everything in that event happens before anything
else is executed.

Having asynchronous functions (obviously) changes that - now other things
will execute while you wait for something to happen. Without an async
keyword, users basically have no direct way to determine if a function
will run to the end without interruption. This can be especially
problematic if you manipulate data structures in an event that have to be
present in later events (as it is now commonly done in scripts).

Consider e.g. an example like the following

event protocol_event_1(...)
	{
	c$proto$la = function_call;
	}

event protocol_event_end(...)
	{
	Log::write([....c$proto$la...]);
	}

If I understand everything correctly, in this case it is not guaranteed
to be present - it still might be waiting for function_call (if it is
asynchronous). This might not be a problem for cases in which functions
that obviously need DNS lookups are used - but if this is hidden between a
few layers of indirection it will get really hard to reason about this.

I actually think that it makes sense to be more explicit there. So -
require async in front of all bifs, etc that are asynchronous. And if a
user creates a function that in turn calls an asynchronous function, I
think we should require that function to be called using async too. Either
a user knows that a function uses an asynchronous function, or the script
interpreter will raise an error message telling them that the async
keyword is required here because an async function is in the call stack.
While this might be a bit painful at times I think this still is better
because it makes the script writer aware that things might be interrupted
at this point.

So - my argument is basically exactly the reverse of yours - if an async
function is somewhere in the call stack I definitely would want to know
about this when writing my script - otherwhise I can see really nasty bugs
happening.

If we want to make it more explicit that a function is potentially
asynchronous, we also could consider requiring the function definition to
mark this explicitly, e.g. just by adding the async keyword in front:

async function lookup(name: string) : set[addr] {
	local addrs = async lookup_hostname(name);
	return addrs;
}

...but that is not strictly necessary and does not look that pretty.

Johanna


More information about the bro-dev mailing list