-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Mark Sapiro wrote:
Stephen J. Turnbull wrote:
Mark Sapiro writes:
1) add_member saves the list with the first member. 2) VirginRunner gets there first, instantiates and caches the list. It then locks the list, processes the welcome and saves and unlocks the list. 3) add_member gets the lock, adds the second member and saves the list. 4) Virgin runner gets the second welcome. The list is cached, so it uses the cached instance. It then locks the list which ultimately calls MailList.__load() to refresh the list data, but __load() does
mtime = os.path.getmtime(dbfile) if mtime <= self.__timestamp: # File is not newer return None, None
Shouldn't "mtime < self.__timestamp" do the right thing (much more often)?
I didn't reply sooner because when I first saw this, I didn't read it carefully, and I didn't "get" what Stephen was saying. Then I had to think about it.
I have concluded that barring resetting of clocks backward, "mtime < self.__timestamp" is equivalent to "False". Whenever a config.pck is written or read in a process, __timestamp is set to the current mod time of the config.pck. Thus, the value of self.__timestamp for a cached list object is always <= mtime.
I have thought about this some more and have come up with the attached patch which I have tested with Max's script and propose for Mailman 2.2. The patch changes the '<=' test to '<' as Stephen suggests, but then so it won't effectively disable ever not reloading the config.pck, it changes the setting of __timestamp following a successful read from the mod time of the config.pck to the current time truncated to an int. Thus, once we've read a config.pck that's more than a second old, a subsequent load of the same object will skip rereading the config.pck if it wasn't updated in the interim. - -- Mark Sapiro <mark@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (MingW32) iD8DBQFIryLmVVuXXpU7hpMRApoCAJ9hPl/yxi8n9ZAT04s2+TCG6/rvbwCg1NJ6 HlgyY/PB3s6l7B4diGO0zb8= =5V+H -----END PGP SIGNATURE----- === modified file 'Mailman/MailList.py' --- Mailman/MailList.py 2008-08-21 21:35:20 +0000 +++ Mailman/MailList.py 2008-08-22 18:18:38 +0000 @@ -597,8 +597,11 @@ # file doesn't exist, we'll get an EnvironmentError with errno set # to ENOENT (EnvironmentError is the base class of IOError and # OSError). + # We test strictly less than here because the resolution is whole + # seconds and we have seen cases of the file being updated by + # another process in the same second. mtime = os.path.getmtime(dbfile) - if mtime <= self.__timestamp: + if mtime < self.__timestamp: # File is not newer return None, None fp = open(dbfile) @@ -616,8 +619,9 @@ return None, e finally: fp.close() - # Update timestamp - self.__timestamp = mtime + # Update the timestamp. We use current time here rather than mtime + # so the test above might succeed the next time. + self.__timestamp = int(time.time()) return dict, None def Load(self, check_version=True):