Null exception with InterestArea.ReceiveItemSnapshot

mstultz
edited June 2011 in Photon Server
I'm running into an issue with Interest Areas after an MmoItem has been destroyed. All MmoItems are using the MmoWorld's IFiber. This choice was made to reduce some worry/design choices regarding thread safety. I think we got this idea from Boris, on the forums (maybe: viewtopic.php?f=5&t=393&p=1992&hilit=fiber#p1992).

After disposing an MmoItem, I'd sometimes see some null exceptions in the log:
2011-06-09 15:17:12,266 [9] ERROR Photon.MmoDemo.Server.PhotonApplication - System.ArgumentNullException: Value cannot be null.
Parameter name: key
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at Photon.SocketServer.Mmo.InterestArea.ReceiveItemSnapshot(ItemSnapshot message) in c:\svncontent\photon-socketserver-sdk\src\Photon.SocketServer\Mmo\InterestArea.cs:line 494
   at Photon.SocketServer.Mmo.Messages.ItemSnapshotRequest.OnItemReceive(Item item) in c:\svncontent\photon-socketserver-sdk\src\Photon.SocketServer\Mmo\Messages\ItemSnapshotRequest.cs:line 84
2011-06-09 15:17:12,272 [9] ERROR Photon.MmoDemo.Server.PhotonApplication - System.ArgumentNullException: Value cannot be null.
Parameter name: key
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at Photon.SocketServer.Mmo.InterestArea.ReceiveItemSnapshot(ItemSnapshot message) in c:\svncontent\photon-socketserver-sdk\src\Photon.SocketServer\Mmo\InterestArea.cs:line 494
   at Photon.SocketServer.Mmo.Messages.ItemSnapshotRequest.OnItemReceive(Item item) in c:\svncontent\photon-socketserver-sdk\src\Photon.SocketServer\Mmo\Messages\ItemSnapshotRequest.cs:line 84
2011-06-09 15:17:12,273 [9] ERROR Photon.MmoDemo.Server.PhotonApplication - System.ArgumentNullException: Value cannot be null.
Parameter name: key
   at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
   at Photon.SocketServer.Mmo.InterestArea.ReceiveItemSnapshot(ItemSnapshot message) in c:\svncontent\photon-socketserver-sdk\src\Photon.SocketServer\Mmo\InterestArea.cs:line 494
   at Photon.SocketServer.Mmo.Messages.ItemSnapshotRequest.OnItemReceive(Item item) in c:\svncontent\photon-socketserver-sdk\src\Photon.SocketServer\Mmo\Messages\ItemSnapshotRequest.cs:line 84

My first thought was that we are piggy-backing on the MmoWorld's fiber, and something like EnqueueItemSnapshotRequest's "this.fiber.Enqueue" would pose issues since the MmoItem's Dispose does not dispose of the fiber. A coworker pointed out that the null exception itself is probably due to the current world region being set to null in the Item's Dispose method. Sure enough, in a derived class, prior to calling Item's Dispose(), I saved off the current world region, and then reset it after calling Item.Dispose(). This removed the null exceptions listed above.

Can you comment about the two things I just mentioned? Is there a better way to do what we want to do?

Comments

  • The cause is indeed that the CurrentWorldRegion is set to null.
    The code does not expect that an ItemSnapshotRequest message can be received after the subscription to the CurrentWorldRegion has been disposed.
    Avoiding the exception the way you described it is no solution since this introduces a memory leak.
    My first thought was that this is caused by a Dispose() call from the wrong fiber.. It works for the standard implementation because the items use the same fibers the peers use. So first step is to get it thread safe: override Item.Dispose(bool) and enqueue the base.Dispose(bool) to the item fiber.
    On second thought there might still be a possibility to receive ItemSnapshotRequests after the subscription has been disposed: they might already wait in the fiber before Dispose() had a chance to unsubscribe. I double-checked and there is no way you can fix it yourself, i have to fix it in the base class.
    I'll post an updated dll.
  • please let me know if this dll solves it.

    CHANGED: deleted file as it was not working
  • Yeah, I thought I could just override Item's Dispose, but it needs to clean up some private/internal things.

    I'm trying to copy these .DLL's over, but am receiving this error when restarting the server:
    8356: 12:13:24.189 - ERROR: Failed to start application: "MmoDemo" in app domain: 2
    8356: 12:13:24.190 - CService::OnException() - Exception: CManagedHost::StartApplication() - Failed to start application in AppDomain: 2 - Could not load file or assembly 'Photon.SocketServer, Version=2.4.8.1448, Culture=neutral, PublicKeyToken=48c2fa3b6988090e' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
    

    Am I doing something wrong? Also, thanks for the prompt reply.
  • Did you compile again?
  • Ah, I did originally but was receiving the same errors, and then I did a straight copy. Re-compiling, it appears that I am still receiving the same ArgumentNullException errors.
  • Really? That would be odd since I added a null check to that line.
    Please post your log.
  • You know what? I'm an idiot. I was copying into the deploy and not the lib folder (duh).

    Is this DLL referencing a newer version of ExitGamesLibs than is available? It's giving me an error for 0.9.9.0 versus my 0.9.7.1.
  • :(
    you are using photon 2.6? If not please update.. If yes I'll have to post the other dll(s) later (Monday maybe even) - i'm currently not at my computer.
  • Yeah, I am running 2.6.
    If yes I'll have to post the other dll(s) later (Monday maybe even) - i'm currently not at my computer.
    No problem! Have a good weekend.
  • Just sent you a PM with a download link.
    If anyone else experiences the same null-reference issue please send me a PM.
  • The changes Boris made have fixed the issue on my end.