pvl.irker.irc: handle concurrent JOIN/PART better, by removing channel on send(PART), and ignore recv(PART) during join
authorTero Marttila <terom@paivola.fi>
Fri, 25 Jan 2013 22:02:55 +0200
changeset 168 4e120851ff52
parent 167 f4f77bc8d8af
child 169 a81ca751664d
pvl.irker.irc: handle concurrent JOIN/PART better, by removing channel on send(PART), and ignore recv(PART) during join
pvl/irker/irc.py
--- a/pvl/irker/irc.py	Tue Jan 22 01:58:33 2013 +0200
+++ b/pvl/irker/irc.py	Fri Jan 25 22:02:55 2013 +0200
@@ -51,6 +51,9 @@
 
         self.encoding = encoding
 
+        # TODO: separate join/part state
+        #self.joining = self.parting = None
+
     def encode (self, unicode) :
         if unicode :
             return unicode.encode(self.encoding)
@@ -70,8 +73,13 @@
         """
             Remove channel from our list of channels.
         """
+        
+        # send the PART
+        self.client.leave(self.channel, self.encode(msg))
 
-        self.client.leave(self.channel, self.encode(msg))
+        # ...and then immediately forget the channel, in case we rejoin before getting the part back
+        # TODO: self.joining/parting
+        self.client._close_channel(self.channel)
 
     def errback (self, failure) :
         """
@@ -177,7 +185,7 @@
 
             Returns a deferred that callbacks with the IRCChannel once joined, or errbacks.
         """
-
+        
         irc.IRCClient.join(self, channel, key=key)
 
         d = self._channels[normalize(channel)] = defer.Deferred()
@@ -199,9 +207,18 @@
         del self._channels[normalize(channel)]
 
     def left (self, channel) :
-        log.msg('IRCClient.left', channel)
+        if normalize(channel) in self._channels :
+            if isinstance(self._channels[normalize(channel)], defer.Deferred) :
+                log.msg('IRCClient.left: part during join:', channel)
 
-        self._close_channel(channel)
+            else :
+                log.msg('IRCClient.left: unexpected part:', channel)
+                self._close_channel(channel)
+
+            # XXX: assume this is: send PART, send JOIN, receive PART, receive JOIN
+            #self._close_channel(channel)
+        else :
+            log.msg("IRCClient.left: parted channel:", channel)
 
     def kickedFrom (self, channel, kicker, message) :
         log.msg('IRCClient.kicked', channel, kicker, message)