Mon 10 Apr 2006
Not travelling around western Europe has done wonders for Cypress’s TODO list.
Most of my work lately has been going into designing (and redesigning) and implementing the Controller-side watch_module system. Put simply, this subsystem revolves around solving the first problem I outlined in the project introduction: how to ensure things like cache purity in the face of auto-reloaded modules.
This problem took a good while to solve, mostly because of ideological issues. To get into that, we first need a little background:
Cypress was originally conceived as a framework that would host other, higher-level applications. The goal was that these applications could run on top of Cypress without any modification whatsoever, totally ignorant of the fact that Cypress was running below them. Cypress would act as a mediator, sitting between the hosted application and the Python interpreter, intercepting module imports.
This import-interception was how Cypress was going to solve the three issues I mentioned in the project introduction. Cypress would redirect import requests to a specified revision control system (issue #2), periodically querying to find out which modules had changed since the last query and reloading the applicable chunks of code (issue #1); by having each application be hosted by its own instance of some
Controllerclass, any number of applications could run on top of the same Cypress libraries (issue #3).
The part that was getting in the way was the goal of letting applications be ignorant of Cypress. I ran into this problem: say module M caches instances of a class C from module N. What happens when N is modified, changing the definition of class C? Module M’s cache now contains instances of both the old and new version of class C, leading to cache poisoning.
The solution that I’m going forward with tarnishes some of that ideological purity in exchange for more application-side power. If an application needs to know when a given module changes, it can call the watch_module method to tell Cypress, “call this object when anything happens to module foo.bar“. Given a module name and a callable, applications can now be signalled when the named module is edited, renamed or even deleted, giving the hosted code a chance to clear object caches, etc.
A more comprehensive design document is available from Cypress’s SVN repository.