ReadStrategy details

Florian Minjat florian.minjat at gmail.com
Fri Jul 6 09:14:04 UTC 2007


Hi again Chris,

Chris Muller wrote:
> Hi Florian, recall from http://wiki.squeak.org/squeak/2638:
> 
> "The minimumDepth is how far it reads for any object, all objects,
> every time, all the time."

My understanding of this is that if I ask Magma for a Player object 
with a minDepth of 3, it will follow references and reify objects on a 
depth of 3.

> "As a programmer, you can change this default 0, 1, 2 or 3 (or maybe
> even 4, but I wouldn't go beyond that) by supplying a ReadStrategy."

My problem is that my application is a game. And every 12h it need to 
go through the whole hierarchy of the whole players to update them. If 
I let the minDepth to 1, the read, update and commit of one player 
takes something like 15min due to the heavy number of requests to 
magma (lot of very small objects). So I want to reify the whole object 
hierarchy of my Player before updating it. Therefore I use a minDepth 
of 10 (the max depth is : 
Player->(1)Dungeon->(*)MonsterRoom->(*)Adventurer->(1)Treasure->(*)SmallInteger).

And it works great for Players without any Letters, it only takes 
something like 30s instead of several minutes. But if the Player has 
some Letters, Magma will reify the recipients and therefore other 
Players. The read-update-commit then takes ~5-7min (quite annoying to 
get a real value).

> So here are a couple of options for you.
> 
> Option 1:
> 
> The minimumDepth is the global minimum that cannot be overridden
> except by using a negative depth on a variable-specific specification;
> but I tend to prefer staying positive just for clarity.  So you could
> just specify a very low minimumDepth and then larger depths for each
> variable you want to go deeper on:
> 
> myReadStrategy := MaReadStrategy minimumDepth: 0.
> (Player allInstVarNames copyWithout: 'letters') do:
>  [ : each |
>  myReadStrategy
>    forVariableNamed: each
>    onAny: Player
>    readToDepth: 10 ]
> 
> Something like that.  Since a minimumDepth of 0 can really thrash the
> server with a lot of small requests, you should specify 1 for
> everything else.  Not too much trouble though, do you have a main
> superclass for your hierarchy?
> 
> myReadStrategy onAny: GameObject readToDepth: 1
> 
> Player, even though it inherits from FlorianGame will still employ a
> minimum-depth of 0.  This is a convenience feature for just this
> situation.

I didn't have the need to a single superclass for the whole hierarchy 
(~30 class) but it could be bothersome, but if needed I could try.

I didn't test this option because my need is the opposite : full depth 
everywhere and no depth for Desk. And the object hierarchy of a Player 
is quite complex. I could use reflection to specify a depth of 1 to 
every variable except myDesk but it's a little bit heavy.

> Option 2:
> 
> Even still, option 1 you don't get a minimumDepth of 1 for everything
> else outside your GameObject, like Associations or other
> out-of-the-box Smalltalk classes (you do with Collections, they always
> get 1).
> 
> So, another option would be to stick with a minimumDepth of 1
> everywhere but then "back up" one level just for Players letters:
> 
> myReadStrategy := (MaReadStrategy minimumDepth: 1)
>  forVariableNamed: 'letters' onAny: Player readToDepth: -1;
>  yourself.
> 
> Even though it uses a negative, this might be easier..

I tried this method :

	session readStrategy: (
		(MaReadStrategy minimumDepth: 10)
		forVariableNamed: 'myDesk' onAny: Dungeon readToDepth: -1;
		yourself
	).

But the Desk is still reified. I tried with -11 but with the same 
result :/. Did I miss something ?

Florian


> - Chris
> 
> 
> 
> On 7/5/07, Florian Minjat <florian.minjat at gmail.com> wrote:
>> Hi Chris,
>>    I did some tests and have to ask for this again :
>>    As you saw I have a Desk with letters which refers to other
>> Players. But Players also have Rooms with Adventurers and Treasure.
>> The structure can be simplified like that (varName:varType):
>>
>> Player
>> ->(1)Desk->(*)Letter
>> ->(*)Room->(*)Adventurer->(1)Treasure->(1)SmallInteger
>>
>> I don't want theses letters to be reified but I want object deeper
>> like the value of the treasure of an Adventurer to be reified. So I
>> tried something like that :
>>
>> session readStrategy: (
>>     (MaReadStrategy minimumDepth: 10)
>>        forVariableNamed: 'letters' onAny: Desk readToDepth: 0
>> )
>>
>>    But it didn't seem to work :
>> ((player instVarNamed: 'desk') instVarNamed: 'letters') class =>
>> OrderedCollection
>> (((player instVarNamed: 'desk') instVarNamed: 'letters') instVarAt: 1)
>> class => Array
>> ((((player instVarNamed: 'desk') instVarNamed: 'letters') instVarAt:
>> 1) instVarAt: 1) class => Letter
>>
>>    So how can I make the rule on Desk precedes the more global rule ?
>> Currently, retrieving a Player without Letters takes a few seconds,
>> with Letters a few minutes :/.
>>
>> Florian
>>
> 


More information about the Magma mailing list