Making metaclass transient proved to be more difficult than making fields of RubyClass and RubyModule transient (methods, cref, and classProviders). Here is what I have currently:

RubyModule
one new transient ivar: 'isNotPersistent' whose default is true ... transient makes it false when it is reloaded from the database
        superclass, methods, cref and classProviders ivars are transient
getMethods(), getCref() and classProviders() are lazily initialized ... for example

    public Map getMethods() {
        if(methods == null && !this.isNotPersistent) {
methods = Ruby.getDefaultInstance().getClass (classId).getMethods();
        }
        return methods;
    }

The accessors are not used everywhere. I use them only when an already instantiated object needs them. They are not called in the constructors. Direct reference is used there as before. Also, note that isNotPersistent (above) prevents recursion when the class would be referring to itself (when it is not an object's metaclass loaded from the db)

RubyClass
        runtime, marshal and allocator are transient
getRuntime(), getMarshal(), and getAllocator() are lazily initialized as above

So when an object is persisted, it drags along its metaclass, but only the metaclass's classId is stored in the database. Everything else is transient. When it is referenced and faults in from the database, it brings its (incomplete) copy of the metaclass with it. On first method invocation, it lazily copies the methods from the original class (shown above). Same for the other nulled-out ivars.

So far, everything seems to work. But I have some questsions about the runtime. When Rails is running multiple runtimes, does it maintain a pool of them or does it instantiate a new runtime every time it needs one. I currently have only one runtime. It's a singleton and I use Ruby.getDefaultInstance() to fetch it when I need it. I realize this is not the best strategy, but it seems that even if I grab the runtime that is created in Main, there will still be only one in the VM. Should there be a pool of them and should I getNextRuntime() ... or something like that?

Reply via email to