TempoClock reschedule at inf

Wondering if this is a bug?

Something seems to happen when my scheduling function returns inf:

TempoClock.new.sched(0, {
	"sched".postln;
	inf;
})

The function never reschedules as expected, and nothing seems to be blocked and SuperCollider apparently works as normal, but watching the activity monitor on my mac I see that SuperCollider CPU consume suddenly jumps to 100% and stays there, and after a while the fan starts spinning up.

It is rescheduled… just, you would never be able to observe it. It would be wrong for SC to awaken a function at some point finitely in the future when you instructed to reschedule it for infinitely far ahead.

I can reproduce this – likely a bug?

But the fix might simply be to throw an error upon inf rescheduling, because it’s a meaningless thing to do.

hjh

1 Like

By the way, CondVar.waitFor(inf) already does exactly this.

Apologise for a slow follow-up, and thanks for testing!

I see the sensible fix to throw an error upon inf rescheduling, however I wouldn’t mind it working as it does now since sometimes an expression can return inf, which was the case for me. It already works in practice as I would expect except for the sudden CPU consume, which might be the result of another kind of bug, perhaps?

So the next step then is to make a bug report?

Almost forgot this one…

While I understand what you’re saying, I think I can’t agree.

If you’re scheduling an action, then you expect it to execute at some point. If you schedule something in a way that it can never execute, this is a mistake.

In case of mistakes, the options as developers are A/ throw an error, B/ post a warning but try to continue, or C/ fail silently. To decide between A and C… how serious is the mistake? How likely is it for someone to make this mistake and expect a different result? In your case “it’s fine.” But I can easily imagine another user accidentally generating an inf scheduling interval and, in the absence of any error/warning report, being confused that it never happens. To be honest, I think this is more likely than your scenario.

The case in the initial post was rescheduling (function returns a scheduling interval). I’m guessing that the desired behavior in the inf case is simply not to reschedule at all. There is already a way to do that – return nil. I think the code would be clearer if it had an explicit test for a stop condition, and returned nil in that case, rather than relying on a specific response to a special-case floating-point value. (Among other reasons – the scheduling behavior of a nil return will never change in SC – we rely on it in too many places! – but an inf return might change. Future-proofing!)

hjh

I’m happy to leave the decision on whether to throw an error to someone else. For future proofing, if it’s a thing that might change, I absolutely see the point. I use inf here and there where perhaps I shouldn’t, like the ‘end’ argument in Phasor. I suspect something non-inf is going to jump up and bite me there at some point :slight_smile:

About it being a mistake though, I will only say that it was not a mistake when I wrote that code, rather it all became a simpler expression, and for my part no more a mistake than writing, say;

rrand(0, 3).do({
	// some work
});

rather than:

a = rrand(0, 3);

if (a != 0) {
	a.do({
		// some work
	});
};

which also won’t evaluate on some instances and doesn’t throw an error.

But, more than this discussion, I’m concerned about the strange CPU bug which seems like very strange behaviour. That stayed with me for a long time without me noticing it, since everything worked fine. I thought it was just my code that was CPU intensive. Are we sure to catch all instances of that?

For instance, this will create the same CPU spike on my machine:

Pbind(
	'type', 'rest',
	'dur', Pseq([1, inf, 2]).trace
).play

Does this eventually call the same method?

Of course, that’s definitely a bug and needs to be prevented. I believe the best way is to prevent an inf scheduling time from ever going into the queue in the first place. It’s easy to do that without requiring the user to write if expressions. (The question is whether an error should accompany this. My gut feeling is that it does warrant an error, but I’m open to being convinced otherwise.)

I believe that the issue is not the method being called, but the time value being put into the queue. If you try to put an inf time value in, from anywhere, by whatever means, the result should be expected to be the same.

hjh