Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

"The previously scheduled job..." error due to order of update of systems and Monobehaviours

Discussion in 'Entity Component System' started by Abbrew, Apr 1, 2019.

  1. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    I'm trying to coordinate one Monobehaviour (PhysicsQuery) and two systems (PreloaderSystem and ActorSystem) forced to update inside their respective Monobehaviour wrappers, like this
    Code (CSharp):
    1. public class PreloaderRunner : MonoBehaviour
    2. {
    3.     private void Update()
    4.     {
    5.         World.Active.GetOrCreateManager<PreloaderUpdateGroup>().Update();
    6.     }
    7. }
    8.  
    I used the script ordering function under Project Settings to set the ordering of the three Monobehaviours to PhysicsQuery -> PreloaderSystem -> ActorSystem. The rationale is that I want to schedule all possible physics queries in PreloaderSystem and have the calculations take place in worker threads while ActorSystem does its own work. The order is basically
    1. PhysicsQuery copies all data from PreloaderSystem.
    2. PreloaderSystem schedules a new batch of physics calculations
    3. ActorSystem uses the results from PhysicsQuery to calculate movement, decisions, shooting, in the main thread while PreloaderSystem's jobs are running in the background
    This SHOULD prevent scheduling errors, but I'm receiving errors saying that Unity cannot schedule a job in PhysicsQuery due to a job from PreloaderSystem being already scheduled. This shouldn't be possible! Project Settings specifies that PhysicsQuery runs before PreloaderSystem, and all of PreloaderSystem's jobs should be completed by the EndFrameBarrier. Even the Profiler shows that the order of execution is as specified. What could be the reason for this scheduling conflict? Are the PreloaderSystem jobs from the previous frame somehow still running in the current frame as PhysicsQuery prepares to read from PreloaderSystem's NativeContainers?
     
  2. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    So according to https://github.com/BrianWill/LearnUnity/blob/master/ecs-jobs/ecs_jobs.md JobHandle.Complete() is called right before the JobComponentSystem's next OnUpdate, not at the end of the frame. As a result, in my example, once a new frame begins and PhysicsQuery starts reading from PreloaderSystem's NativeContainers, the previous frame's jobs that write to PreloaderSystem's NativeContainers may still be running, causing the dependency conflict. Is this correct? If so, would it be a good idea to use EntityManager.GetOrCreateManager<PreloaderRunner>() inside PhysicsQuery to retrieve PreloaderRunner's last inputDeps and call complete on it?
     
    chrismarch likes this.
  3. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    AddJobHandleForProducer fixes the issue. I created a class PreloaderSyncBufferSystem that inherits from EntityCommandBufferSystem and had each system in PreloaderSystemGroup get the PreloaderSyncBufferSystem instance, and call AddJobHandleForProducer(inputDeps). Next I forced PreloaderSyncBufferSystem to run under a Monobehaviour after ActorSystem. The order of update is now PhysicsQuery -> PreloaderSystem -> ActorSystem -> PreloaderSyncBufferSystem (where all of PreloaderSystem's jobs are forced to complete)