ServerBoot.add and thisProcess. nowExecutingPath

Hello,

Is there a specific reason why thisProcess. nowExecutingPath', thisProcess. nowExecutingPath.dirname, etc do not work with ServerBoot.add`?
A code example can be found here:

You need to evaluate thisProcess.nowExecutingPath first, outside ServerBoot.add

(
var soundFolder = thisProcess.nowExecutingPath;// +/+ "BW2 Exports";
ServerBoot.add({
	Buffer.freeAll; // I am not sure if it is necessary.	
	soundFolder.postln;

...

thisProcess.nowExecutingPath returns the path to a file executing interactively by the interpreter.

when you call add on ServerBoot the function you pass as an argument is added to ServerBoot.objects - when the server boots, that function is evaluated, but it is not evaluated interactively

1 Like

Thank you very much!

I understand it word for wordā€¦ However, I do not seem to really understand it because I have the following question:
Can interactivity be implemented in the future or not? Is it logical that the interpreter does not interactively evaluate the part of the code that belongs to ServerBoot.objects? Honestly, I thought it was a bug at first glance.

Itā€™s inside a synchronous process (inside a Routine), so the language blocks the following message until the previous one is completed. With s.sync, it also ensures the server is ready.

Also remember, the server does seomthing, but you canā€™t forget the language, the one who is sending timed/scheduled messages to the server.

So this scheduling confusion you said is figured out by the language.

Kind of

1 Like

yes looking into it further Iā€™m not sure I have understood it correctly!

I tried doing:

ServerTree.add({thisProcess.dump})

and doing Cmd-.

and then comparing it to thisProcess.dump

you will see that the in one case the current thread is Main with the correct nowExecutingPath and in the other it is a Routine with nowExecutingPath = nil

Iā€™m going to read around in AbstractServerAction Kernel Thread and Main to see if I can understand this better - I think that Thread sets its executingPath via a primitive _Thread_Init and it may be that that an nil value is what we are ending up with in this case

One question here is, what are the semantics of nowExecutingPath?

  • Should it always point back to the location where the line of code was defined?
  • Or should it refer to the context at the moment of execution?

I wanted to foreground this question because itā€™s being assumed that the first meaning is (ā€œobviouslyā€?) better. Maybeā€¦? Probablyā€¦? But it might also not be quite so obvious.

If I create a file, say, ā€œ23-1217-nowexec-proto.scdā€:

(
	testFunction: {
		thisProcess.nowExecutingPath
	}
)

And a second file in the same location, ā€œ23-1217-nowexec-caller.scdā€:

a = (thisProcess.nowExecutingPath.dirname +/+ "23-1217-nowexec-proto.scd").load;

a.testFunction;

ā€¦ which path should be returned? ā€œxxx-protoā€ or ā€œxxx-callerā€?

The current behavior is to return the callerā€™s path. From one point of view, thatā€™s a stretch: the line of code accessing the current path is written into the ā€œprotoā€ file. But, you hit cmd-return in the caller file, andā€¦ maybe itā€™s useful to know that?

In any case, if itā€™s desired to refer always to the location where the function was defined, then I think the only solution is to move filenameSymbol out of Method and into FunctionDef, and change the C++ compiler code to fill in this variable at compile time. Then the nowExecutingPath method would have to trace back to the currently active FunctionDef.

(If a method calls nowExecutingPath, should it be the location where the method was defined, or the user code that called the method?)

Edit: Or perhaps keep both. If all functions are tagged with their path, then thisFunction.filenameSymbol would (shouldā€¦?) give you the location-where-defined, and it may not be necessary to change/break the current semantic of nowExecutingPath.

A Routineā€™s path is set at the moment of creation.

Has your ServerTree.add code file created the routine that runs during server initialization?

Nopeā€¦ so, how would the (internally-produced) Routine know about your file?

(I think the difference for Routines is that they last for a relatively long time, while Function execution is assumed to be instantaneous.)

In any case, it needs to be understood (and perhaps better documented) that nowExecutingPath operates with a synchronous time scope. It gives you access to the current user-code path (not method definitions) within the block that is running synchronously in response to a cmd-return. If that block defines actions that will happen later, nowExecutingPath does not cover this, except for Routines that are created synchronously within the block. If you need the path to be available for later operations, then (currently) it is the userā€™s responsibility to grab the path and stash it in a variable on their own.

hjh

3 Likes

thanks James that makes perfect sense

ā€¦indeed if I interpret

CmdPeriod.run

it does set nowExecutingPath

1 Like

I made a PR based on this thread:

If there is anything I should revise, please let me know.

Thanks for your response and advice!