Repository: evennia/evennia

Issue:
Public Channel Breakage
#### Brief summary of issue / Description of requested feature:
We get this error periodically when trying to use our Public channel, typically after the MU has been sitting idle for some time.

    Traceback (most recent call last):
      File "/home/evennia/evennia/evennia/commands/cmdhandler.py", line 584, in _run_command
        ret = cmd.func()
      File "/home/evennia/evennia/evennia/comms/channelhandler.py", line 141, in func
        channel.msg(msg, senders=self.caller, online=True)
      File "/home/evennia/evennia/evennia/comms/comms.py", line 319, in msg
        self.distribute_message(msgobj, online=online)
      File "/home/evennia/evennia/evennia/comms/comms.py", line 248, in distribute_message
        subs = self.subscriptions.online()
      File "/home/evennia/evennia/evennia/comms/models.py", line 554, in online
        if not obj.is_connected:
      File "/home/evennia/evennia/evennia/utils/idmapper/models.py", line 166, in <lambda>
        fget = lambda cls: _get(cls, fieldname)
      File "/home/evennia/evennia/evennia/utils/idmapper/models.py", line 114, in _get
        raise ObjectDoesNotExist("Cannot access %s: Hosting object was already deleted." % fname)
    ObjectDoesNotExist: Cannot access db_is_connected: Hosting object was already deleted.
    
    An untrapped error occurred.
    (Traceback was logged 2017-07-26 13:34:30-0000).
    Traceback (most recent call last):
      File "/home/evennia/evennia/evennia/commands/cmdhandler.py", line 737, in cmdhandler
        unformatted_raw_string, cmdset, session, player)
    ErrorReported: pub test
    
    A command handler bug occurred. If this is not due to a local change,
    please file a bug report with the Evennia project, including the
    traceback and steps to reproduce.
    (Traceback was logged 2017-07-26 13:34:30-0000).

#### Steps to reproduce the issue / Reasons for adding feature:

This happens to everybody (telnet, webclient, --everybody--) obviously since it's a channels/serverside issue.  I wonder if this might be related to [chainsol's webclient/database problem](https://github.com/evennia/evennia/issues/1376) since we're also on MySQL.

A simple @reload (even from in-game) gets the channel working again.
Public Channel Breakage
#### Brief summary of issue / Description of requested feature:
We get this error periodically when trying to use our Public channel, typically after the MU has been sitting idle for some time.

    Traceback (most recent call last):
      File "/home/evennia/evennia/evennia/commands/cmdhandler.py", line 584, in _run_command
        ret = cmd.func()
      File "/home/evennia/evennia/evennia/comms/channelhandler.py", line 141, in func
        channel.msg(msg, senders=self.caller, online=True)
      File "/home/evennia/evennia/evennia/comms/comms.py", line 319, in msg
        self.distribute_message(msgobj, online=online)
      File "/home/evennia/evennia/evennia/comms/comms.py", line 248, in distribute_message
        subs = self.subscriptions.online()
      File "/home/evennia/evennia/evennia/comms/models.py", line 554, in online
        if not obj.is_connected:
      File "/home/evennia/evennia/evennia/utils/idmapper/models.py", line 166, in <lambda>
        fget = lambda cls: _get(cls, fieldname)
      File "/home/evennia/evennia/evennia/utils/idmapper/models.py", line 114, in _get
        raise ObjectDoesNotExist("Cannot access %s: Hosting object was already deleted." % fname)
    ObjectDoesNotExist: Cannot access db_is_connected: Hosting object was already deleted.
    
    An untrapped error occurred.
    (Traceback was logged 2017-07-26 13:34:30-0000).
    Traceback (most recent call last):
      File "/home/evennia/evennia/evennia/commands/cmdhandler.py", line 737, in cmdhandler
        unformatted_raw_string, cmdset, session, player)
    ErrorReported: pub test
    
    A command handler bug occurred. If this is not due to a local change,
    please file a bug report with the Evennia project, including the
    traceback and steps to reproduce.
    (Traceback was logged 2017-07-26 13:34:30-0000).

#### Steps to reproduce the issue / Reasons for adding feature:

This happens to everybody (telnet, webclient, --everybody--) obviously since it's a channels/serverside issue.  I wonder if this might be related to [chainsol's webclient/database problem](https://github.com/evennia/evennia/issues/1376) since we're also on MySQL.

A simple @reload (even from in-game) gets the channel working again.
Public Channel Breakage
#### Brief summary of issue / Description of requested feature:
We get this error periodically when trying to use our Public channel, typically after the MU has been sitting idle for some time.

    Traceback (most recent call last):
      File "/home/evennia/evennia/evennia/commands/cmdhandler.py", line 584, in _run_command
        ret = cmd.func()
      File "/home/evennia/evennia/evennia/comms/channelhandler.py", line 141, in func
        channel.msg(msg, senders=self.caller, online=True)
      File "/home/evennia/evennia/evennia/comms/comms.py", line 319, in msg
        self.distribute_message(msgobj, online=online)
      File "/home/evennia/evennia/evennia/comms/comms.py", line 248, in distribute_message
        subs = self.subscriptions.online()
      File "/home/evennia/evennia/evennia/comms/models.py", line 554, in online
        if not obj.is_connected:
      File "/home/evennia/evennia/evennia/utils/idmapper/models.py", line 166, in <lambda>
        fget = lambda cls: _get(cls, fieldname)
      File "/home/evennia/evennia/evennia/utils/idmapper/models.py", line 114, in _get
        raise ObjectDoesNotExist("Cannot access %s: Hosting object was already deleted." % fname)
    ObjectDoesNotExist: Cannot access db_is_connected: Hosting object was already deleted.
    
    An untrapped error occurred.
    (Traceback was logged 2017-07-26 13:34:30-0000).
    Traceback (most recent call last):
      File "/home/evennia/evennia/evennia/commands/cmdhandler.py", line 737, in cmdhandler
        unformatted_raw_string, cmdset, session, player)
    ErrorReported: pub test
    
    A command handler bug occurred. If this is not due to a local change,
    please file a bug report with the Evennia project, including the
    traceback and steps to reproduce.
    (Traceback was logged 2017-07-26 13:34:30-0000).

#### Steps to reproduce the issue / Reasons for adding feature:

This happens to everybody (telnet, webclient, --everybody--) obviously since it's a channels/serverside issue.  I wonder if this might be related to [chainsol's webclient/database problem](https://github.com/evennia/evennia/issues/1376) since we're also on MySQL.

A simple @reload (even from in-game) gets the channel working again.


Discussion:
@tekmunkey, if you want to test this, set the MySQL timeout lower - log in to the MySQL prompt, and send this:
`SET GLOBAL wait_timeout=30`
if your issue comes back in 30 seconds, you know it's related, haha.
This one looks like my bad. I added an online check for subscribers not too long ago, but forgot to check if the objects were deleted. Lemme see if I can fix this.
@tekmunkey, if you want to test this, set the MySQL timeout lower - log in to the MySQL prompt, and send this:
`SET GLOBAL wait_timeout=30`
if your issue comes back in 30 seconds, you know it's related, haha.
This one looks like my bad. I added an online check for subscribers not too long ago, but forgot to check if the objects were deleted. Lemme see if I can fix this.
@tekmunkey, if you want to test this, set the MySQL timeout lower - log in to the MySQL prompt, and send this:
`SET GLOBAL wait_timeout=30`
if your issue comes back in 30 seconds, you know it's related, haha.
This one looks like my bad. I added an online check for subscribers not too long ago, but forgot to check if the objects were deleted. Lemme see if I can fix this.

Resolving patch:
diff --git a/evennia/comms/models.py b/evennia/comms/models.py
--- a/evennia/comms/models.py
+++ b/evennia/comms/models.py
@@ -453,8 +453,10 @@ def __init__(self, obj):
         self._cache = None
 
     def _recache(self):
-        self._cache = {player : True for player in self.obj.db_subscriptions.all()}
-        self._cache.update({obj : True for obj in self.obj.db_object_subscriptions.all()})
+        self._cache = {player: True for player in self.obj.db_subscriptions.all()
+                       if hasattr(player, 'pk') and player.pk}
+        self._cache.update({obj: True for obj in self.obj.db_object_subscriptions.all()
+                            if hasattr(obj, 'pk') and obj.pk})
 
     def has(self, entity):
         """
@@ -546,14 +548,23 @@ def online(self):
                 are puppeted by an online player.
         """
         subs = []
+        recache_needed = False
         for obj in self.all():
-            if hasattr(obj, 'player'):
-                if not obj.player:
+            from django.core.exceptions import ObjectDoesNotExist
+            try:
+                if hasattr(obj, 'player'):
+                    if not obj.player:
+                        continue
+                    obj = obj.player
+                if not obj.is_connected:
                     continue
-                obj = obj.player
-            if not obj.is_connected:
+            except ObjectDoesNotExist:
+                # a subscribed object has already been deleted. Mark that we need a recache and ignore it
+                recache_needed = True
                 continue
             subs.append(obj)
+        if recache_needed:
+            self._recache()
         return subs
 
     def clear(self):


Test patch: