Next: , Previous: , Up: Persistence   [Contents][Index]


8.6 Upgrading through persistence

The design of the persistence system allows for this to be a powerful mechanism to make upgrades for object data. The very basic situation of adding a new piece of data is automatic as you can provide a default value. More complicated data upgrade is also fully supported. Lets take an example of a thermostat that represents the set temperature in fahrenheit:

(define (^thermostat bcom temperature)
  (define main-beh
    (methods
     [(get-current-temp) temperature]
     [(set-temp new-temp) ...]))
  (define (self-portrait)
    (list temperature))
  (portraitize main-beh self-portrait))

(define thermostat-env
  (make-persistence-env
   (list (list ''((house temp) ^thermostat) ^thermostat))))

Later, we want to change the thermostat object to work with the set temperature in Celsius. Normally this is a bit tricky as we have just stored an integer for the portrait data, however Goblins tags this data with a version and it can be upgraded and tagged by us too, lets take a look at how we can upgrade the above actor using this upgrade mechanism:

(define (^thermostat bcom temperature)
  (define main-beh
    (methods
     [(get-current-temp) temperature]
     [(set-temp new-temp) ...]))
  (define (self-portrait)
    (versioned 1 (list temperature)))
  (portraitize main-beh self-portrait))

(define (rehydrate-thermostat version restored-temperature)
  (define temperature
    (match version
      ;; F -> C conversion
      [0 (+ (* 9/5 restored-temperature) 32)]
      ;; C, no conversion needed.
      [1 restored-temperature]))
  (spawn ^thermostat temperature))

(define thermostat-env
  (make-persistence-env
   (list (list '((house temp) ^thermostat) ^thermostat rehydrate-thermostat))))

There are two changes here:

1. The thermostat object’s self-portrait function now versions the data with version 1. 2. We now have this rehydrate-thermostat function which takes in a version and might convert it before spawning the thermostat.

Goblins has a versioned function provided which allows the first argument to be a version tag which usually is an integer but could be any atomic serializable data such as a simple or even string and as a second argument the self-portrait data. If the self-portrait doesn’t return a versioned portrait, Goblins will assign the version 0 to that portrait data. Later you’re able to match on it and upgrade it like the example above.

With the above example newly created objects which are created using Celsius will not be need to be upgraded, but the old fahrenheit objects will be converted.


Next: Persistence stores, Previous: Persistence Environments, Up: Persistence   [Contents][Index]