(s.sync) with a Routine inside a Routine

Dear users and developers,

I usually use s.waitForBoot, but this time I have made a block of code like the following to show how s.sync works in a routine:

(
Routine.run {
	var helloPost;
	
	"\nOSCFunc.trace started\n".postln;
	OSCFunc.trace(hideStatusMsg: true);
	
	"\nsending s.boot\n".postln;
	s.boot;
	
	helloPost = fork {
		inf.do{ |i|
			("\n\t\t\t\t\t\t\t\t\t\t----------hello"+ i ++"----------\n").postln;
			1.wait
		}
	};
	
	"\nsending s.sync\n".postln;
	s.sync;
	
	"\nafter receiving \synced from the server\n".postln;
	
	"\nstop OSCFunc.trace\n".postln;
	OSCFunc.trace(false);
	
	"\nstop helloPost\n".postln;
	helloPost.stop;
}
)

This code works as expected when evaluated while sever is already running:

-> a Routine

OSCFunc.trace started


sending s.boot

server 'localhost' already running

sending s.sync


										----------hello 0.0----------

OSC Message Received:
	time: 233311.75022425
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /synced, 1017 ]


after receiving synced from the server


stop OSCFunc.trace


stop helloPost

However, evaluating the code when the local server is not running does not work as expected because the routine associated with the local variable helloPost does not stop. Also, two lines of code using the .postln method do not work.

I am curious as to why this happens. Is there a reason for this, or have I coded something wrong with a misunderstanding?

-> a Routine

OSCFunc.trace started


sending s.boot


sending s.sync


										----------hello 0.0----------

Booting server 'localhost' on address 127.0.0.1:57110.
VSTPlugin 0.5.4
read cache file /Users/prko/.VSTPlugin/cache.ini
Found 0 LADSPA plugins
Number of Devices: 7
   0 : "CalDigit Thunderbolt 3 Audio"
   1 : "CalDigit Thunderbolt 3 Audio"
   2 : "MacBook Pro Microphone"
   3 : "MacBook Pro Speakers"
   4 : "ZoomAudioD"
   5 : "Aggregate Device"
   6 : "Multi-Output Device"

"MacBook Pro Microphone" Input Device
   Streams: 1
      0  channels 1

"MacBook Pro Speakers" Output Device
   Streams: 1
      0  channels 2

SC_AudioDriver: sample rate = 44100.000000, driver's block size = 512
SuperCollider 3 server ready.

										----------hello 1.0----------

Requested notification messages from server 'localhost'
OSC Message Received:
	time: 233152.2037405
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /done, /notify, 0, 1 ]

localhost: server process's maxLogins (1) matches with my options.
localhost: keeping clientID (0) as confirmed by server process.
OSC Message Received:
	time: 233152.24647517
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /done, /d_recv ]


[ ... many similar messages are ommited ... ]


OSC Message Received:
	time: 233152.485656
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /d_removed, bufGrainRLPF2 ]

OSC Message Received:
	time: 233152.48569442
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /done, /d_recv ]

OSC Message Received:
	time: 233152.48573204
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /synced, 1012 ]

OSC Message Received:
	time: 233152.51299783
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /synced, 1013 ]

OSC Message Received:
	time: 233152.63855867
	address: a NetAddr(127.0.0.1, 57110)
	recvPort: 57120
	msg: [ /synced, 1014 ]

Shared memory server interface initialized

										----------hello 3.0----------


										----------hello 4.0----------


										----------hello 5.0----------

Not too sure, someone will correct me if I’m wrong, but I think s.boot sets the server into ‘booting’ mode, meaning it hasn’t yet booted. When you sync, you are just waiting for the server to be in booting mode, not booted. What you need, is to wait for the server to finish booting, i.e., s.waitForBoot. If you really don’t want to use it to wrap your code, then hang and unhang a Condition.

1 Like

s.sync requires the server to be fully booted first. You can’t use sync to wait for the server to boot.

hjh

1 Like

Thanks!

Thanks to your help, I have corrected my mistake in two ways, as follows:

  1. To show the workflow using s.sync, Buffer.read is now used:
(
Routine.run {
	var helloPost;

	"\nOSCFunc.trace started\n".postln;
	OSCFunc.trace(hideStatusMsg: true);

	Buffer.freeAll(s);

	"\nsending a request to the local server\n".postln;
	100.do { Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav") };

	helloPost = fork {
		inf.do{ |i|
			("\n\t\t\t\t\t\t\t\t\t\t----------hello"+ i ++"----------\n").postln;
			0.1.wait
		}
	};

	"\nsending s.sync\n".postln;
	s.sync;

	"\nafter receiving \synced from the server\n".postln;

	"\nstop OSCFunc.trace\n".postln;
	OSCFunc.trace(false);

	"\nstop helloPost\n".postln;
	helloPost.stop;
}
)
  1. To illustrate, the server is booted without using ```s.waitForBoot``:
(
Routine.run {
	var helloPost;

	"\nOSCFunc.trace started\n".postln;
	OSCFunc.trace(hideStatusMsg: true);

	"\nsending s.boot\n".postln;
	s.bootSync;

	helloPost = fork {
		inf.do{ |i|
			("\n\t\t\t\t\t\t\t\t\t\t----------hello"+ i ++"----------\n").postln;
			1.wait
		}
	};

	"\nsending s.sync\n".postln;
	s.sync;

	"\nafter receiving \synced from the server\n".postln;

	"\nstop OSCFunc.trace\n".postln;
	OSCFunc.trace(false);

	"\nstop helloPost\n".postln;
	helloPost.stop;
}
)

Yes, that’s a good way.

s.sync refers specifically to asynchronous server commands, and only to this situation. If the server isn’t booted yet, then 1/ by definition it cannot be processing asynchronous commands that it can’t have received yet and 2/ it isn’t listening to OSC input yet, so it can’t be aware of the /sync command (therefore it won’t reply – it’s like asking your partner a question while they’re asleep, and expecting an answer when they wake up – “but I asked you earlier!”).

hjh

2 Likes