Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Saving and retrieving objects in a changing environment

This is a presentation for ESUG conference 2012
by

Carlos Ferro

on 15 May 2018

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of Saving and retrieving objects in a changing environment

We work in live object environments
Be it an application, or the development environment
We always have a network of related, live objects, collaborating by sending messages
But at some point...
We want to save a part
by freezing
or serializing
Saving objects and saving code
are pretty much the same
...since our code ARE objects
Classes, metaclasses,
compiled methods
inside method dictionaries
And inside methods,
literal references
global references
(including classes)
unique objects
(true, false, nil)
To save an arbitrary group of objects
even starting from a well-defined root
(as a ProjectSession)
we need to do several cleaning operations
This is useful not only for saving
(economy of space and time)
but for retrieving also
(no need to rebuild unnecessary structures)
Basically, we should clean
all instance variables
referencing
temporary
values
or
global
values.
Also, some
references
could be
sythesized using names or identifiers
Tradition separates two scenarios
Time passes, and
life goes on...
And your objects,
and your environment,
CHANGE
Saving code
...and what you expect to be already
present when you retrieve
You have
Classes
Methods
Globals
Constant Pools
You expect to find
Superclasses
Classes
Globals
Pool constants
...and you can have
collisions on all of it
...and you should
solve them
Saving model objects
You have
Instances of model classes
Instances of common library classes
References to globals
You expect to find
Model classes
Common library classes
Globals
You cannot have name conflicts, but
you could not find the referenced
classes or globals
Most likely, you cannot
solve this automatically
Besides, everything can be in place
all names could be resolved
no apparent conflict detected
...and nevertheless be wrong!
Classes could be in different hierarchies
Globals & constants
could have
unexpected values
Classes could have changed name
Most of this can be fixed
using mappings.
Parcels
Tanker (Fuel packages)
Monticello
In the basement, we have...
ObjectDumper
ObjectLoader
An object serialization tool,
inspired in BOSS
Hooks
#afterReadActivate
#dumpingSurrogate
before exporting
can answer a different object
Bitmap>>dumpingSurrogate
self saveBitmap.
^self copy clearSurrogate
In Java serialization
you can declare transient
instance variables
after loading
adapts receiver instance variables
can return a different object
Transient variables must use
lazy initialization to fix
useful to clean transient variables
but also to encode objects by id
or expression
FacilitySpec>>afterReadActivate
super afterReadActivate.
structure ensureRequiredConnectors.
maxConnectedWells isNil ifTrue: [self initializeMaxConnectedWells].
minWellsRequired isNil ifTrue: [self initializeMinWellsRequired]
It has no warranted order
It is individual, object per object
It gets complex when several versions pass
and changes go on and on
You need a unique and consistent
source of version number
PVRApplication class>>currentVersion
^10.201
PetroVR suite includes several different
tools, with different model objects
PVRReader>>readFrom: aStream
self
readVersion;
readModel;
checkModel.
model notNil ifTrue: [self migrateToCurrentVersion].
^model
PVRReader>>migrateToCurrentVersion
objectFiler saveMissingVariables.
model := self migrator migrate: model fromVersion: version.
objectFiler releaseMissingVariables
We work with many
incremental migrations
PVRReader>>readModel
self initializeMappings; loadRequiredLibraries.
model := objectReader loadFrom: stream loadMaps: mappings
We had to add logic for composing the maps
Class A
Class B
Class C
renamed
renamed
ProjectMigrator>>migrateTo519
Specific cases and examples
FML Expressions and model names

model allVariablesDo: [:var |
(var hasFmlFunction and: [var functionString includesString: 'Start date'])
ifTrue: [| exp |
exp := var calcFunction fmlExpression.
exp variableNamesDo: [:v |
(v refersToJob and: [v lastName = 'Start date']) ifTrue: [
v lastName: 'Expected Start Date'.
var calcFunction fromFmlExpression: exp]]]].
model allJobs do: [:j |
(j instVarNamed: 'startGuess') name: 'Expected Start Date']
ProjectMigrator>>migrateTo9102
| oldNames names |
oldNames := OrderedCollection new.
names := OrderedCollection new.
model excessActions select: [:e | e isExpansion] thenDo: [:e | | v |
v := e threshold.
v name = 'Unused capacity' ifFalse: [
oldNames add: v modelName.
v name: 'Unused capacity'.
names add: v modelName]].
names notEmpty ifTrue: [self renameVarsNamed: oldNames to: names].
evolved into general
services
Note that methods should be idempotent!
ProjectMigrator>>migrateTo10107
| aux |
model simpleReservoirs
select: [:r | r isGasReservoir]
thenDo: [:r | r oil solutionGOR deactivate].
aux := FacilityModelMigrator new.
model facilities do: [:f | aux migrate: f structure fromVersion: version]
Bussiness modeling change
Forced initialization of new variables
ProjectMigrator>>migrateTo91
model simpleReservoirs do: [:r | | plan pattern |
plan := r depletionPlan.
plan wellReservesThreshold isNil
ifTrue: [plan initializeWellReservesThreshold].
(plan instVarNamed: 'batch') isNil ifTrue: [plan batch: false]]
Changes in representation
Internal changes in selectors
ProjectMigrator>>migrateTo9301
| percentages wrong |
percentages := model percentageSensitivitySpec percentages.
wrong := percentages columnSpecOf: #baseValue.
wrong notNil ifTrue: [wrong selector: #displayValue]
Changes in codification
ProjectMigrator>>migrateTo8107
model wells
select: [:w | w recompletionPolicy == #autoDrillCompletions]
thenDo: [:w | w recompletionPolicy: #autoComplete]
ProjectMigrator>>migrateTo8109
model heatingWells do: [:h | | decline |
decline := InjectorPerformanceSpec new.
decline fluid: h injectionFluid; owner: h.
h instVarNamed: 'decline' put: decline]
Adding ranges to variables
ProjectMigrator>>migrateTo8302
model declines
select: [:d | d decline class == GasDeliverabilityDeclineSpec]
thenDo: [:d |
d decline flowExponent range: (Range open: 0.0 close: 10.0).
d decline flowCoefficient range: Range positive]
Changes of classes
ProjectMigrator>>migrateTo7206
model facilities
select: [:f | f isPowerPlant and: [f isCogenerator]]
thenDo: [:f |
f changeClassTo: SteamPlantSpec.
f initializeExternalFluidSource.
f structure: (f structure copyTo: SteamPlantModel new).
f structure initializeConverter]
Adding description to variables
ProjectMigrator>>migrateTo7207
model allJobs do: [:job |
job isInfillDrilling ifTrue: [
job cost opEx
messageFunctionOn: #computeOpEx
description: 'Calculated as Number of Wells * the prototype''s OpEx.'].
job isRigMobilization ifTrue: [
job cost opEx
messageFunctionOn: #computeOpEx
description: 'Calculated from mobilization/demobilization costs defined for the rig type']]
We added support for missingVariables
so we can extract data from discarded
or renamed instance variables
ProjectMigrator>>migrateTo7303
model wells do: [:w | | missing location point |
location := w location.
missing := location propertyAt: #missingVariables.
missing notNil ifTrue: [
point := missing at: 'logical' ifAbsent: nil.
point notNil ifTrue: [location x: point x y: point y z: 0.0]]]
Because, sometimes, we let user decide
We have built Migration Issues
ProjectMigrator>>migrateTo62
model facilities do: [:f | | issue |
(f hasDowntimeDefined and: [f usesSequentialAllocation]) ifTrue: [
issue := self
addMigrationIssueBecause: f modelName
, ' has Downtime defined which is currently unsupported with sequential choking'.
issue
addOption: 'Disable downtime'
receiver: f maintenanceProgram downtime
selector: #deactivate
description: 'Turn off the Downtime defined at ' , f name;
addOption: 'Use proportional choke distribution'
receiver: f
selector: #cancelSequentialAllocation
description: 'Change to proportional choking all facilities up and down-stream '
, f name;
addEmptyOption]]
We can move variables to different objects
ProjectMigrator>>migrateTo6214
model reservoirs do: [:r | | missingVariables oil gas |
missingVariables := r propertyAt: #missingVariables.
missingVariables notNil ifTrue: [
oil := missingVariables at: 'oil'.
gas := missingVariables at: 'gas'.
r fluids
instVarNamed: 'oil' put: oil;
instVarNamed: 'gas' put: gas]]
Sometimes, objects must be fixed
BEFORE we start the migration,
because base services would not work otherwise.
We introduced the fixBrokenObjects mechanism
ProjectMigrator>>fixBrokenObjectsIn8303
model connections
do: [:c | c capacity isNil ifTrue: [c reinitializeCapacity]]
Project Migrator>>fixBrokenObjectsBeforeMigration
PVRApplication current allVersions do: [:v | | selector |
(PVRApplication isVersion: version pre: v) ifTrue: [
selector := ('fixBrokenObjectsIn'
, (v printString reject: [:c | #($. $,) includes: c]))
asSymbol.
(self respondsTo: selector) ifTrue: [self perform: selector]]]
A common problem:
tracking the version number
THIS kind of mappings
Missing variables
Migration Issues
Two stages and fixing broken objects
Variables and Fml
According to what you
have when you save
Saving Code
Saving Model Objects
Globals could have unexpected values
Classes could have changed shape
adding variables
removing variables
renaming variables
Variable semantics or business
rules could change
DepletionPlan
instanceVariableNames: .... threshold batch ...
initialize
super initialize.
.. .. ..
self initializeWellReservesThreshold.
batch := false.
aHeatingWell
aVariable
anInjector
Performance
Spec
decline
decline
FacilitySpec
PowerPlantSpec
Cogenerator
SteamPlantSpec
aLocation
x
y
aPoint
logical
nil
physical
aLocation
x
y
z
A medium-size project from a client
contains 8248 objects (2950 literals)
of 164 classes.
A tiny demo project contains 4086 objects
(1844 literals) of 175 classes
Class A
oil
gas
aReservoir
oil
gas
aReservoir
aReservoirFluids
Full transcript