pmndrs / directed

A flexible, minimal scheduler written in TypeScript
MIT License
25 stars 1 forks source link

Scheduling runnables to run first or last #13

Open krispya opened 3 months ago

krispya commented 3 months ago

I run into situations where I want something to run first or last, for example for performance profiling. Now, of course, telling two runnables to be scheduled last runs into a logic problem, only one can truly be last. But would it make sense to have built in tags, first and last where trying to scheduler before first throws an error and trying to scheduler after last throws an error? Then there would be some guarantees that these tags stick your runnables before or after game code.

akdjr commented 3 months ago

This seems like an application concern, not a library concern.

If the use case is performance profiling the entire schedule, then I'd rather add a performance package/api as this is fairly trivial to implement. Simply measure, run the schedule, then stop. If you are trying to measure a particular tag or runnable, then both of these can also be implemented as a performance api.

krispya commented 3 months ago

Capturing data about the schedule would be great. Execution time and average execution time are obvious starting points. Number of runnables too.

krispya commented 3 months ago

Maybe you can help me think of a better way to conceive of this. I have this RC:

function Simulation() {
    const world = useWorld();
    const statsApi = useStats({ extras: { Bodies: () => CONSTANTS.NBODIES } });

    useRaf(() => {
        statsApi.measure(() => {
            schedule.run({ world });
        });
        statsApi.updateStats();
    }, [world, statsApi]);

    return null;
}

It is measuring execution time and then updating the UI only after the measurement has completed. I can see moving the measuring into the library, but what about updating the UI? I wanted to turn it into a system I add to the end of whatever scheduler is loaded, but there is no way for me to guarantee this without doing something weird like looking at the schedule's sort and scheduling relative to the last runnable in the sort.

krispya commented 3 months ago

Also there are other stats that users will want to grab that don't have to do with the execution time of the schedule itself. For example, the Drei stats component: https://github.com/pmndrs/drei/blob/master/src/core/Stats.tsx

Ideally, I could grab stats for sub graphs too. For example, track how many entities were created and destroyed during 'render'.

Ctrlmonster commented 3 months ago

I've definitely run into this kinda thing before as well. I think the solution we previously discussed were system groups, where you could say X should run after group Y and group Y includes all your gameplay systems for example.

krispya commented 3 months ago

Yeah, and that is currently supported where you can schedule before and after tags and use tags to group runnables. The requirements for measuring is a bit more strict though as you don’t want to run any time after but exactly after. In other words, scheduling after a tag/group doesn’t guarantee immediacy.

A callback is a more appropriate concept here for start/end events.