views:

43

answers:

1

I've written a gevent-based program that allows its web clients to quickly exchange messages through it (so it works like a hub).

Since I only support polling mechanism at this moment, I've written it to store messages that need to be delivered to a specific client in its 'inbox' at the server side. While the client list is stored in MySQL, these inboxes are stored in memcache for faster access. When a client connects to the hub, it pulls all the messages that have accumulated in its inbox.

The question
The problem is that once upon a short while the recipients do not receive their messages when pulling the contents of their inbox - they receive an empty array.
What puzzles me even more is that if I restart the hub, the messages that were not received by the clients will suddenly materialize and get delivered to their destinations.
Can you point me if there's a glaring defect in my code? Do you have any explanation to this effect?

push is the method that gets executed to place a message into a client's inbox. pull is the method that retrieves the list of all the accumulated messages as a list and returns it to the main processing function.

def __push(self, domain, message, tid=None):
    if tid:
        try:
            messages = self.mc.get("%s_inbox" % tid.encode('utf8'))
        except:
            logging.error("__push memcached failure", exc_info=1)
        if messages:
            messages = fromjson(messages)
            messages.append(message)
            self.mc.set("%s_inbox" % tid.encode('utf8'), tojson(messages))
            print "Pushed to", "%s_inbox" % tid.encode('utf8')


def __pull(self, tid):
    try:
        messages = self.mc.get("%s_inbox" % tid.encode('utf8'))
        if messages:
            self.mc.set("%s_inbox" % tid.encode('utf8'), "[]")
            return fromjson(messages)
        else:
            return []
    except:
        logging.error("__pull failure", exc_info=1)
        return []
A: 

I think I got it: it's a bug in the python-memcache module.

David Parunakian