Jobs Depencies, Bug or im doing it wrong ?

Hello Community,

can anyone help me with this error ?

im stuck in this error from 5 hours and i feel like it’s a bug.

using System.Net;
using UnityEngine; 
using Unity.Networking.Transport;
using Unity.Collections; 
using Unity.Jobs;
using CWBR.ClientAndServer.Components; 
using Unity.Entities; 
using System;

using UdpCNetworkDriver = Unity.Networking.Transport.GenericNetworkDriver<Unity.Networking.Transport.IPv4UDPSocket, Unity.Networking.Transport.DefaultPipelineStageCollection>; 
using CWBR.ClientAndServer.Enums;

struct HandleConnectionsRequestsJob : IJob
{
    public UdpCNetworkDriver driver;
    public NativeList<NetworkConnection> unidentifiedConnections;
    public NativeArray<NetworkConnection> m_Connections;

    public BufferFromEntity<OutgoingReliableMessages> outgoingReliableMessagesFromEntity;
    public BufferFromEntity<OutgoingUnreliableMessages> outgoingUnreliableMessages;

    [ReadOnly] public NativeArray<Entity> playersEntities;

    [ReadOnly] public EntityCommandBuffer commandBuffer;

    public void Execute()
    {
        // CleanUpConnections !!!

        for (int i = 0; i < unidentifiedConnections.Length; i++)
        {
            if (!unidentifiedConnections[i].IsCreated)
            {
                unidentifiedConnections.RemoveAtSwapBack(i);
                --i;
            }
        }
         
        for (int i = 0; i < m_Connections.Length; i++)
        {
            if (!m_Connections[i].IsCreated )
            {
                if (m_Connections[i] != default)
                {
                    Debug.Log($"Connection index : {i} is Cleaned");
                    //TODO: Remove Connected and Add Disconnected to the Right Entity
                    m_Connections[i] = default;
                    commandBuffer.RemoveComponent<ConnectedPlayer>(playersEntities[i]);
                    commandBuffer.AddComponent<DisconnectedPlayer>(playersEntities[i]);
                    outgoingReliableMessagesFromEntity[playersEntities[i]].Clear();
                    outgoingUnreliableMessages[playersEntities[i]].Clear();
                }
            }
        }

        // Accept New Connections ( added as unidentified Connection )
        NetworkConnection c;
        while ((c = driver.Accept()) != default)
        {
            unidentifiedConnections.Add(c); 
            Debug.Log("Accepted a connection");
        }
    }
}


/// <summary>
/// Handle Identification Messaged from 
/// </summary>
struct HandleIdentificationsJob : IJob
{
    [ReadOnly] public UdpCNetworkDriver driver;
    [ReadOnly] public EntityCommandBuffer commandBuffer;
    [ReadOnly] public ComponentDataFromEntity<DisconnectedPlayer> disconnectedPlayerLookup;
    [ReadOnly] public NativeArray<Entity> playersEntities;
    [ReadOnly] public NativeArray<uint> players_SecretKey;
    [ReadOnly] public NetworkPipeline reliablePipeline;

    public NativeList<NetworkConnection> unidentifiedConnections;
    public NativeArray<NetworkConnection> m_Connections;

    public void Execute()
    {
        // check for Identification Messages
        for (var i = 0; i < unidentifiedConnections.Length; i++)
        {
            // Remove if Connection has been Canceled before the Identification
            if (!unidentifiedConnections[i].IsCreated)
            {
                Debug.Log("TODO: Handle Disconnected Players From ReceiveStreamsJob");
                unidentifiedConnections.RemoveAtSwapBack(i);
                --i;
                continue;
            }

            NetworkEvent.Type cmd;
            while ((cmd = driver.PopEventForConnection(unidentifiedConnections[i], out var stream)) != NetworkEvent.Type.Empty)
            {
                // Data Received
                if (cmd == NetworkEvent.Type.Data)
                {
                    // This Context should be used for All Operations concerning this Stream
                    var readerCtx = default(DataStreamReader.Context);

                    var messageId = stream.ReadByte(ref readerCtx);

                    // TODO: Implement a more Elegant way to read Messages
                    if (messageId == MessageBufferIndexes.IdentificationId)
                    {
                        var secretKey = stream.ReadUInt(ref readerCtx);

                        // Player Identified 
                        int playerIndex = NativeArrayExtensions.IndexOf(players_SecretKey, secretKey);
                        if (playerIndex >= 0)
                        {
                            // Set Connection in Connections Array
                            m_Connections[playerIndex] = unidentifiedConnections[i];


                            // Add ConnectedPlayer Component to the Player Entity
                            commandBuffer.AddComponent(playersEntities[playerIndex], new ConnectedPlayer { Id = (byte)playerIndex });

                            // Check if This player entity is containing the DisconnectedPlayer Component 
                            if (disconnectedPlayerLookup.Exists(playersEntities[playerIndex]))
                                commandBuffer.RemoveComponent<DisconnectedPlayer>(playersEntities[playerIndex]);


                            // Notify Player that his identified
                            using (var writer = new DataStreamWriter(1, Allocator.Temp))
                            {
                                writer.Write(MessageBufferIndexes.IdentificationSuccess);
                                driver.Send(reliablePipeline, m_Connections[playerIndex], writer);
                                Debug.Log("Player Successfully Identified");
                            }

                        }

                        // Player Failed his identification
                        else
                        {
                            Debug.Log("Player Failed the Identification");

                            //TODO: Handle Fake Identification 

                            // Close this Connection
                            // unidentifiedConnections[i].Close(driver); 

                            // Notify Player that he Failed the identification
                            using (var writer = new DataStreamWriter(1, Allocator.Temp))
                            {
                                writer.Write(MessageBufferIndexes.IdentificationFailed);
                                driver.Send(reliablePipeline, m_Connections[playerIndex], writer);
                                Debug.Log("Player Successfully Identified");
                            }
                        }


                        // Remove this Connection from the Unidentified Connections List
                        unidentifiedConnections.RemoveAtSwapBack(i);
                        --i;
                        break;
                    }
                    else
                    {
                        // TODO: Handle Messages From UnIdentified Players
                        Debug.Log("Unexpected Message from UnIdentified Player");
                    }


                }
                // in Case the Client Request For disconnection before the Identification
                else if (cmd == NetworkEvent.Type.Disconnect)
                {
                    unidentifiedConnections.RemoveAtSwapBack(i);
                    --i;
                    break;
                }
            }// While end!
        }// for end!
    }
}




 
/// <summary>
/// Send Streams to Clients
/// </summary>
//[BurstCompile] // Disabled only when testing 
[RequireComponentTag(typeof(OutgoingUnreliableMessages))]
public struct SendUnreliableMessagesJob : IJobForEachWithEntity<ConnectedPlayer>
{
    public UdpCNetworkDriver.Concurrent driver; 
    [ReadOnly] public NetworkPipeline unreliablePipeline;

    [NativeDisableParallelForRestriction] public BufferFromEntity<OutgoingUnreliableMessages> outGoingBufferFromEntity;
    [ReadOnly] [NativeDisableParallelForRestriction] public NativeArray<NetworkConnection> connections;

    public void Execute(Entity entity, int index, ref ConnectedPlayer connectionId)
    {
        var connection = connections[connectionId.Id];
        if (!connection.IsCreated)
        {
            Debug.Log("connection is not Created");
            return;
        } 
        var ouGoingDynamicBuffer = outGoingBufferFromEntity[entity];
         
        if (ouGoingDynamicBuffer.Length == 0)
        {
            Debug.Log("Empty OutgoingUnreliableMessages buffer");
            return;
        }

        using(var tmp = new DataStreamWriter(ouGoingDynamicBuffer.Length, Allocator.Temp))
        {
            unsafe
            {
                tmp.WriteBytes((byte*)ouGoingDynamicBuffer.GetUnsafePtr(), ouGoingDynamicBuffer.Length);
            }
            driver.Send(unreliablePipeline, connection, tmp);
            ouGoingDynamicBuffer.Clear();
        } 

        /*
        IntPtr pointer;
        unsafe
        { 
            pointer = (IntPtr) NativeSliceUnsafeUtility.GetUnsafeReadOnlyPtr(ouGoingBufferFromEntity[entity].AsNativeArray().Slice().SliceConvert<byte>());
        }
        driver.Send(unreliablePipeline, connection, pointer, ouGoingDynamicBuffer.Capacity);
        ouGoingDynamicBuffer.Clear();*/
    }
     
}


/// <summary>
/// Send RPCs to Clients
/// </summary>
//[BurstCompile] // Disabled only when testing 
[RequireComponentTag(typeof(OutgoingReliableMessages))]
public struct SendReliableMessagesJob : IJobForEachWithEntity<ConnectedPlayer>
{
    public UdpCNetworkDriver.Concurrent driver;
    [NativeDisableParallelForRestriction] public BufferFromEntity<OutgoingReliableMessages> outGoingBufferFromEntity;
    [ReadOnly] public NetworkPipeline ReliablePipeline;
    [ReadOnly] [NativeDisableParallelForRestriction] public NativeArray<NetworkConnection> connections;

    public void Execute(Entity entity, int index, ref ConnectedPlayer connectionId)
    {
        var connection = connections[connectionId.Id];
        if (!connection.IsCreated)
        {
            Debug.Log("SendReliableMessagesJob connection is Unexpectedly disconnected");
            return;
        }
        var outGoingDynamicBuffer = outGoingBufferFromEntity[entity];

        if (outGoingDynamicBuffer.Length == 0)
        {
            // Debug.Log("Empty OutgoingUnreliableMessages buffer");
            return;
        }

        using (var tmp = new DataStreamWriter(outGoingDynamicBuffer.Length, Allocator.Temp))
        {
            unsafe
            {
                tmp.WriteBytes((byte*)outGoingDynamicBuffer.GetUnsafePtr(), outGoingDynamicBuffer.Length);
            }
            driver.Send(ReliablePipeline, connection, tmp);
            outGoingDynamicBuffer.Clear();
        } 
    }

}




/// <summary>
/// Send RPCs to Clients
/// </summary>
//[BurstCompile] // Disabled only when testing 
struct ReceiveMessagesPacketsJob : IJobForEachWithEntity<ConnectedPlayer>
{
    public UdpCNetworkDriver.Concurrent driver;
    [ReadOnly] [NativeDisableParallelForRestriction] public NativeArray<NetworkConnection> connections; 

    public void Execute(Entity entity, int index, ref ConnectedPlayer connectedPlayer)
    {
        if (!connections[connectedPlayer.Id].IsCreated)
        {
            Debug.Log("TODO: Handle Disconnected Players From ReceiveStreamsJob");
            return;
        }

        NetworkEvent.Type cmd;
        while ((cmd = driver.PopEventForConnection(connections[connectedPlayer.Id], out var stream)) != NetworkEvent.Type.Empty)
        {
            // Data Received
            if (cmd == NetworkEvent.Type.Data)
            {
                // This Context should be used for All Operations concerning this Stream
                var readerCtx = default(DataStreamReader.Context);
                 
                var messageId =  stream.ReadByte(ref readerCtx);

                // TODO: Implement an Elegant way to read Messages 
                Debug.Log($"Message Received From playerId {connectedPlayer.Id} with MessageId : {messageId}");

                /*
                uint number = stream.ReadUInt(ref readerCtx);

                Debug.Log("Got " + number + " from the Client adding + 2 to it.");
                number += 2;

                driver.Send();


                using (var writer = new DataStreamWriter(4, Allocator.Temp))
                { 
                    writer.Write(number); 
                }*/
            }
            else if (cmd == NetworkEvent.Type.Disconnect)
            {
                Debug.Log("Client disconnected from server");
                //connections[connectedPlayer.Id] = default(NetworkConnection);
            }
        }

    }
}


/// <summary>
/// Manage Connection Requests Comming From Clients.
/// Send/Receive RPCs, Streams From Server to Clients. 
/// </summary>
public class ServerManagerSystem : JobComponentSystem
{
   
    public NativeList<NetworkConnection> unidentifiedConnections;
    public NativeArray<uint> players_SecretKey; // these kays are generated From Nakama
    public NativeArray<NetworkConnection> m_Connections; // this array is holding all Players EndPoints (used to Identify Which Connection relies on which player + Sending Messages)
    public NativeArray<Entity> playersEntities;

    public BeginInitializationEntityCommandBufferSystem beginInitializationEntityCommandBufferSystem;
    public UdpCNetworkDriver m_Driver;
    public UdpCNetworkDriver.Concurrent m_ConcurentDriver;
    private NetworkPipeline unreliablePipeline;
    private NetworkPipeline reliablePipeline;
     
    string IP = "127.0.0.1";
    ushort Port = 9000;


    protected override void OnCreate()
    {
        Debug.Log("===========  Server Started!  ==============");

        unidentifiedConnections = new NativeList<NetworkConnection>(32, Allocator.Persistent);
        m_Connections = new NativeArray<NetworkConnection>(32, Allocator.Persistent);
        players_SecretKey = new NativeArray<uint>(32, Allocator.Persistent);
        playersEntities = new NativeArray<Entity>(32, Allocator.Persistent);

        //Test 
        m_Connections[0] = default;
        players_SecretKey[0] = 10101;
        playersEntities[0] = EntityManager.CreateEntity();
        var rnd = new Unity.Mathematics.Random((uint)DateTime.Now.Millisecond);
        for (var i=1; i < 32; i++)
        {
            m_Connections[i] = default;
            players_SecretKey[i] = rnd.NextUInt();
            playersEntities[i] = EntityManager.CreateEntity(); 
        }
        //EndTest



        // m_Driver = new UdpNetworkDriver(new SimulatorUtility.Parameters {MaxPacketSize = packetSize, MaxPacketCount = 30, PacketDelayMs = 25, PacketDropPercentage = 10 /*PacketDropInterval = 100*/}, new ReliableUtility.Parameters { WindowSize = 32 });
        m_Driver = new UdpCNetworkDriver(new INetworkParameter[0]);

        unreliablePipeline = m_Driver.CreatePipeline(typeof(UnreliableSequencedPipelineStage), typeof(SimulatorPipelineStage));
        //unreliablePipeline = m_Driver.CreatePipeline(typeof(UnreliableSequencedPipelineStage));

        reliablePipeline = m_Driver.CreatePipeline(typeof(ReliableSequencedPipelineStage), typeof(SimulatorPipelineStage));
        //reliablePipeline = m_Driver.CreatePipeline(typeof(ReliableSequencedPipelineStage));

        //TODO:  The Server should start Listening after Getting the Port from Console 
        StartListening(IP , Port);

        m_ConcurentDriver = m_Driver.ToConcurrent();
        beginInitializationEntityCommandBufferSystem = World.Active.GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();

         
    }


    /// <summary>
    /// This Function should be used when the server is ready to accept Players
    /// </summary>
    /// <param name="IP"></param>
    /// <param name="Port"></param>
    public void StartListening(string IP, ushort Port)
    { 
        if (m_Driver.Bind(NetworkEndPoint.Parse(IP, Port)) != 0)
            Debug.Log($"Failed to bind to port {Port}");
        else
        { 
            m_Driver.Listen();
            Debug.Log("Server Listening!");
        }
    }
     

    protected override void OnDestroy()
    { 
        // Make sure we run our jobs to completion before exiting. 
        unidentifiedConnections.Dispose();
        players_SecretKey.Dispose();
        m_Connections.Dispose();
        playersEntities.Dispose();
        m_Driver.Dispose();
    }
     
    protected override JobHandle OnUpdate(JobHandle inputDeps)
    { 
        inputDeps = m_Driver.ScheduleUpdate(inputDeps);

        var commandBuffer = beginInitializationEntityCommandBufferSystem.CreateCommandBuffer();
        // Check Connections (Fill Unidentified Connections)
        var connectionJob = new HandleConnectionsRequestsJob
        {
            driver = m_Driver,
            unidentifiedConnections = unidentifiedConnections,
            commandBuffer = commandBuffer,
            m_Connections = m_Connections,
            playersEntities = playersEntities,
            outgoingReliableMessagesFromEntity = GetBufferFromEntity<OutgoingReliableMessages>(),
            outgoingUnreliableMessages = GetBufferFromEntity<OutgoingUnreliableMessages>(),
        }.Schedule(inputDeps);

        // Handle Identifications Job
        var identificationJobHandle = new HandleIdentificationsJob
        {
            driver = m_Driver,
            commandBuffer = commandBuffer,
            unidentifiedConnections = unidentifiedConnections,
            disconnectedPlayerLookup = GetComponentDataFromEntity<DisconnectedPlayer>(true),
            playersEntities =  playersEntities,
            m_Connections = m_Connections,
            players_SecretKey = players_SecretKey,
            reliablePipeline = reliablePipeline,
        }.Schedule(connectionJob);


        // Sending Messages 

        var SendReliableMessagesJobHandle = new SendReliableMessagesJob
        {
            driver = m_Driver.ToConcurrent(),
            ReliablePipeline = reliablePipeline,
            outGoingBufferFromEntity = GetBufferFromEntity<OutgoingReliableMessages>(isReadOnly: false),
            connections = m_Connections,
        }.Schedule(this, identificationJobHandle);

        var SendUnreliableMessagesJobHandle = new SendUnreliableMessagesJob
        {
            driver = m_Driver.ToConcurrent(),
            unreliablePipeline = unreliablePipeline,
            outGoingBufferFromEntity = GetBufferFromEntity<OutgoingUnreliableMessages>(isReadOnly: false),
            connections = m_Connections,
        }.Schedule(this, identificationJobHandle);

        var ReceiveMessagesPacketsJobHandle = new ReceiveMessagesPacketsJob
        {
            driver = m_Driver.ToConcurrent(),
            connections = m_Connections,
        }.Schedule(this, identificationJobHandle);

        var finalHandle = JobHandle.CombineDependencies(SendUnreliableMessagesJobHandle, SendReliableMessagesJobHandle, ReceiveMessagesPacketsJobHandle);

        beginInitializationEntityCommandBufferSystem.AddJobHandleForProducer(finalHandle); 
        return finalHandle;
    }
}

StackTraces:

InvalidOperationException: The previously scheduled job HandleConnectionsRequestsJob writes to the NativeArray HandleConnectionsRequestsJob.driver.m_EventQueue.m_ConnectionEventHeadTail. You must call JobHandle.Complete() on the job HandleConnectionsRequestsJob, before you can write to the NativeArray safely.
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x28b181d8240 + 0x00052> in <c254d6bddee24edb8742cd1c78b0db19>:0
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at C:/buildslave/unity/build/Runtime/Export/Jobs/AtomicSafetyHandle.bindings.cs:158)
Unity.Networking.Transport.NetworkEventQueue+Concurrent+ConcurrentConnectionQueue..ctor (Unity.Collections.NativeList`1[T] queue) (at Packages/com.unity.transport/Runtime/NetworkEventQueue.cs:186)
Unity.Networking.Transport.NetworkEventQueue.ToConcurrent () (at Packages/com.unity.transport/Runtime/NetworkEventQueue.cs:162)
Unity.Networking.Transport.GenericNetworkDriver`2[T,TNetworkPipelineStageCollection].ToConcurrent () (at Packages/com.unity.transport/Runtime/NetworkDriver.cs:33)
ServerManagerSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Scripts/ServerManagerSystem.cs:513)
Unity.Entities.JobComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:933)
Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:602)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/Stubs/Unity/Debug.cs:25)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:606)
Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ScriptBehaviourUpdateOrder.cs:144)
ArgumentException: The previously scheduled job HandleIdentificationsJob writes to the NativeArray HandleIdentificationsJob.commandBuffer. You must call JobHandle.Complete() on the job HandleIdentificationsJob, before you can write to the NativeArray safely.
EntityCommandBuffer was recorded in ServerManagerSystem and played back in Unity.Entities.BeginInitializationEntityCommandBufferSystem.
  at (wrapper managed-to-native) Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut_Injected(Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle&)
  at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x28b181d8240 + 0x00052> in <c254d6bddee24edb8742cd1c78b0db19>:0
  at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) [0x0002e] in C:\buildslave\unity\build\Runtime\Export\Jobs\AtomicSafetyHandle.bindings.cs:158
  at Unity.Entities.EntityCommandBuffer.EnforceSingleThreadOwnership () [0x0001a] in C:\Unity_Projects\UnityTransport\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\EntityCommandBuffer.cs:756
  at Unity.Entities.EntityCommandBuffer.Playback (Unity.Entities.EntityManager mgr) [0x00014] in C:\Unity_Projects\UnityTransport\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\EntityCommandBuffer.cs:1080
  at Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) [0x00061] in C:\Unity_Projects\UnityTransport\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\ComponentSystem.cs:1243
Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:1304)
Unity.Entities.EntityCommandBufferSystem.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:1211)
Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:602)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/Stubs/Unity/Debug.cs:25)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:606)
Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ScriptBehaviourUpdateOrder.cs:144)

Show full stack trace

1 Like

First thing:
beginInitializationEntityCommandBufferSystem.CreateCommandBuffer()
You using ECB in job but not put this job handle to producer, it’s missing dependency for ECB, in this case it’s will playback without waiting your job ending.

beginInitializationEntityCommandBufferSystem.AddJobHandleForProducer(handle);
1 Like

yep i forgot this part :stuck_out_tongue:
now OnUpdate ends like this

var finalHandle = JobHandle.CombineDependencies(SendUnreliableMessagesJobHandle, SendReliableMessagesJobHandle, ReceiveMessagesPacketsJobHandle);
beginInitializationEntityCommandBufferSystem.AddJobHandleForProducer(finalHandle);
return finalHandle;

but still getting the same errors:

InvalidOperationException: The previously scheduled job HandleConnectionsRequestsJob writes to the NativeArray HandleConnectionsRequestsJob.driver.m_EventQueue.m_ConnectionEventHeadTail. You must call JobHandle.Complete() on the job HandleConnectionsRequestsJob, before you can write to the NativeArray safely.
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x2b7e46cfc10 + 0x00052> in <c254d6bddee24edb8742cd1c78b0db19>:0
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at C:/buildslave/unity/build/Runtime/Export/Jobs/AtomicSafetyHandle.bindings.cs:158)
Unity.Networking.Transport.NetworkEventQueue+Concurrent+ConcurrentConnectionQueue..ctor (Unity.Collections.NativeList`1[T] queue) (at Packages/com.unity.transport/Runtime/NetworkEventQueue.cs:186)
Unity.Networking.Transport.NetworkEventQueue.ToConcurrent () (at Packages/com.unity.transport/Runtime/NetworkEventQueue.cs:162)
Unity.Networking.Transport.GenericNetworkDriver`2[T,TNetworkPipelineStageCollection].ToConcurrent () (at Packages/com.unity.transport/Runtime/NetworkDriver.cs:33)
ServerManagerSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Scripts/ServerManagerSystem.cs:513)
Unity.Entities.JobComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:933)
Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:602)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/Stubs/Unity/Debug.cs:25)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:606)
Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ScriptBehaviourUpdateOrder.cs:144)
ArgumentException: The previously scheduled job HandleIdentificationsJob writes to the NativeArray HandleIdentificationsJob.commandBuffer. You must call JobHandle.Complete() on the job HandleIdentificationsJob, before you can write to the NativeArray safely.
EntityCommandBuffer was recorded in ServerManagerSystem and played back in Unity.Entities.BeginInitializationEntityCommandBufferSystem.
  at (wrapper managed-to-native) Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut_Injected(Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle&)
  at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x2b7e46cfc10 + 0x00052> in <c254d6bddee24edb8742cd1c78b0db19>:0
  at Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) [0x0002e] in C:\buildslave\unity\build\Runtime\Export\Jobs\AtomicSafetyHandle.bindings.cs:158
  at Unity.Entities.EntityCommandBuffer.EnforceSingleThreadOwnership () [0x0001a] in C:\Unity_Projects\UnityTransport\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\EntityCommandBuffer.cs:756
  at Unity.Entities.EntityCommandBuffer.Playback (Unity.Entities.EntityManager mgr) [0x00014] in C:\Unity_Projects\UnityTransport\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\EntityCommandBuffer.cs:1080
  at Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) [0x00061] in C:\Unity_Projects\UnityTransport\Library\PackageCache\com.unity.entities@0.1.1-preview\Unity.Entities\ComponentSystem.cs:1243
Unity.Entities.EntityCommandBufferSystem.FlushPendingBuffers (System.Boolean playBack) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:1304)
Unity.Entities.EntityCommandBufferSystem.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:1211)
Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:602)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/Stubs/Unity/Debug.cs:25)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:606)
Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ScriptBehaviourUpdateOrder.cs:144)

Also suggest you beginInitializationEntityCommandBufferSystem.CreateCommandBuffer() before jobs and put one created ECB to all jobs.

did it, but still same errors.

do you think it’s a bug from unity ?

cause even if i add the finalHandle.Complete(); before the return it still give the same erros, it seems like the JobHandles are not correctly merged and some of their jobs still running from the last frame while new ones starts in the current frame.

[i updated my code in the first post by adding the AddJobHandleForProducer and using a single CB]

I’m pretty certain calling m_Driver.ToConcurrent() after already scheduling it in a job will be your issue.

pretty much the same thing I posted here: NativeQueue<T>.ParallelWriter Dependency Issues [preview-0.1.1]

@Opeth001 show 513 line of you code (from stack trace) it’s SendReliableMessage job scheduling? If yes, @tertle can be right.

i changed my OnUpdate Function:

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        inputDeps = m_Driver.ScheduleUpdate(inputDeps);

        var commandBuffer = beginInitializationEntityCommandBufferSystem.CreateCommandBuffer();

        // initializing Messaging Jobs
        var SendReliableMessagesJob = new SendReliableMessagesJob
        {
            driver = m_Driver.ToConcurrent(),
            ReliablePipeline = reliablePipeline,
            outGoingBufferFromEntity = GetBufferFromEntity<OutgoingReliableMessages>(isReadOnly: false),
            connections = m_Connections,
        };

        var SendUnreliableMessagesJob = new SendUnreliableMessagesJob
        {
            driver = m_Driver.ToConcurrent(),
            unreliablePipeline = unreliablePipeline,
            outGoingBufferFromEntity = GetBufferFromEntity<OutgoingUnreliableMessages>(isReadOnly: false),
            connections = m_Connections,
        };

        var ReceiveMessagesPacketsJob = new ReceiveMessagesPacketsJob
        {
            driver = m_Driver.ToConcurrent(),
            connections = m_Connections,
        };

        


        // Check Connections (Fill Unidentified Connections)
        var connectionJob = new HandleConnectionsRequestsJob
        {
            driver = m_Driver,
            unidentifiedConnections = unidentifiedConnections,
            commandBuffer = commandBuffer,
            m_Connections = m_Connections,
            playersEntities = playersEntities,
            outgoingReliableMessagesFromEntity = GetBufferFromEntity<OutgoingReliableMessages>(),
            outgoingUnreliableMessages = GetBufferFromEntity<OutgoingUnreliableMessages>(),
        }.Schedule(inputDeps);

        // Handle Identifications Job
        var identificationJobHandle = new HandleIdentificationsJob
        {
            driver = m_Driver,
            commandBuffer = commandBuffer,
            unidentifiedConnections = unidentifiedConnections,
            disconnectedPlayerLookup = GetComponentDataFromEntity<DisconnectedPlayer>(true),
            playersEntities =  playersEntities,
            m_Connections = m_Connections,
            players_SecretKey = players_SecretKey,
            reliablePipeline = reliablePipeline,
        }.Schedule(connectionJob);


        // Sending Messages
/* Line 488 */        var finalHandle = JobHandle.CombineDependencies(
            SendReliableMessagesJob.Schedule(this, identificationJobHandle),
            SendUnreliableMessagesJob.Schedule(this, identificationJobHandle),
            ReceiveMessagesPacketsJob.Schedule(this, identificationJobHandle)
            );

        beginInitializationEntityCommandBufferSystem.AddJobHandleForProducer(finalHandle);
        return finalHandle;
    }

Yes it seems logic but still getting this error:

InvalidOperationException: The previously scheduled job SendReliableMessagesJob writes to the NativeArray SendReliableMessagesJob.Data.driver.m_Logger.m_PendingLog. You are trying to schedule a new job SendUnreliableMessagesJob, which writes to the same NativeArray (via SendUnreliableMessagesJob.Data.driver.m_Logger.m_PendingLog). To guarantee safety, you must include SendReliableMessagesJob as a dependency of the newly scheduled job.
Unity.Entities.JobForEachExtensions.Schedule (System.Void* fullData, Unity.Collections.NativeArray`1[T] prefilterData, System.Int32 unfilteredLength, System.Int32 innerloopBatchCount, System.Boolean isParallelFor, System.Boolean isFiltered, Unity.Entities.JobForEachExtensions+JobForEachCache& cache, System.Void* deferredCountData, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/IJobForEach.cs:431)
Unity.Entities.JobForEachExtensions.ScheduleInternal_EC[T] (T& jobData, Unity.Entities.ComponentSystemBase system, Unity.Entities.EntityQuery query, System.Int32 innerloopBatchCount, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/IJobForEach.gen.cs:1607)
Unity.Entities.JobForEachExtensions.Schedule[T] (T jobData, Unity.Entities.ComponentSystemBase system, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/IJobForEach.gen.cs:805)
ServerManagerSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Scripts/ServerManagerSystem.cs:488)
Unity.Entities.JobComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:933)
Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.ComponentSystemGroup.OnUpdate () (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:602)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/Stubs/Unity/Debug.cs:25)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystemGroup.cs:606)
Unity.Entities.ComponentSystem:InternalUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:800)
Unity.Entities.ComponentSystemBase:Update() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ComponentSystem.cs:284)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at Library/PackageCache/com.unity.entities@0.1.1-preview/Unity.Entities/ScriptBehaviourUpdateOrder.cs:144)

Oh wait. You are scheduling these in parallel.

SendUnreliableMessagesJob
SendReliableMessagesJob
ReceiveMessagesPacketsJob

var finalHandle = JobHandle.CombineDependencies(
            SendReliableMessagesJob.Schedule(this, identificationJobHandle),
            SendUnreliableMessagesJob.Schedule(this, identificationJobHandle),
            ReceiveMessagesPacketsJob.Schedule(this, identificationJobHandle)
            );

But your exception clearly states that

writes to the NativeArray SendReliableMessagesJob.Data.driver.m_Logger.m_PendingLog.

is an array and telling you this is not allowed.

Even if it’s fine this is not supported by the safety system as ToConcurrent only works with the safety system if the job is parallel, not if you schedule parallel jobs. In the cases for containers that would be safe, you’d need to turn off the safety system.

1 Like

i didnt know about this :stuck_out_tongue:
i just disabled the JobsDebbuger and im not getting Errors Anymore.

can you please give more details please? are they errors or just debugs in red ?

I meant to answer long ago, but I only look on mobile and it is hard to look at the extensive code.

Unless this has changed in recent versions:
1 job can write in parallel to a concurrent container
2 jobs in parallel cannot write to a concurrent container

You will find old threads about this, was discussed before