Opened 11 years ago

Closed 11 years ago

Last modified 11 years ago

#7359 closed enhancement (fixed)

ServiceStore syncMode vs loadLazyValues

Reported by: maulin Owned by: Kris Zyp
Priority: low Milestone: 1.2
Component: DojoX Data Version: 1.1.1
Keywords: Cc: kzyp@…
Blocked By: Blocking:

Description

I'd like to rethink syncMode and loadLazyValues on ServiceStore?.

I'm trying to understand the difference, and the use cases you have in mind for them.

I think getValue is a little confusing. The logic seems to be -- if the property value itself is a lazy object and loadLazyValues = true, then we "pre-load" the rest of the lazy item. But if there is no property value in the item for the property and the item itself is lazy, it means that the property value might not have been loaded yet, so load it, but only if you are in syncMode = true. Its that last bit that seems counter-intuitive to me. It seems to me that if loadLazyValues is true, then both these cases would return a value appropriately, and that syncMode is really only for a call to fetch(). But maybe I am missing something? Its not a big deal, just so long as it is documented well.

Change History (8)

comment:1 Changed 11 years ago by Adam Peller

Component: DojoxDojoX Data
Milestone: 1.2tbd
Owner: changed from Adam Peller to Jared Jurkiewicz

what's the bug? if we're not at a point where we clearly identify one with a test case, perhaps we should move this to the forums?

comment:2 Changed 11 years ago by Kris Zyp

Owner: changed from Jared Jurkiewicz to Kris Zyp

I'd like to rethink syncMode and loadLazyValues on ServiceStore?. I'm trying to understand the difference, and the use cases you have in mind for them. I think getValue is a little confusing.

Yes, it is confusing, I certainly could be up for a different logic.

The logic seems to be -- if the property value itself is a lazy object and loadLazyValues = true, then we "pre-load" the rest of the lazy item. But if there is no property value in the item for the property and the item itself is lazy, it means that the property value might not have been loaded yet, so load it, but only if you are in syncMode = true. Its that last bit that seems counter-intuitive to me. It seems to me that if loadLazyValues is true, then both these cases would return a value appropriately, and that syncMode is really only for a call to fetch().

My thinking is that the auto-loading lazy properties is something users might want to turn off, they may actually want to actual the lazy value, it might be a lazy object with partially loaded properties, or they may want to use async loading mechanism through loadItem. On the otherhand, if you access a property that doesn't exist on an object that is lazy/not loaded yet itself, it seems like you almost certainly want it to be loaded. However, neither of these work in sync mode, and I think the latter is a more problematic when it fails (I think it goes into an endless loop), which is why I avoided the attempt unless I knew the store really supported sync (syncMode = true).

I could remove all the auto-loading code, and force users to use the ol' isItemLoaded/loadItem combo, but it seems like auto-loading through getValue is convenient. I am not sure what logic change would make this easier.

comment:3 Changed 11 years ago by maulin

I think lazy loading is a huge value add, so I wouldn;t go the isITemLoaded/loadItem route. I think "eagerly" loading a lazy object (i.e. on a call to store.getValue(item, "lazyObject") where item.lazyObject is currently {$ref:"/lazy/1"}) is what loadLazyValues does. The question is whether that is truly useful. In that scenario, I think I would probably almost always use the loadItem method if I wanted to fully load a lazy reference.

But I agree that the latter case is the most important, and its what I implicitly think of when I think of lazy properties (so this is what I thought I was getting when I set loadLazyValues = true). So if I take the lazy object above and call store.getValue(lazyObject, "foo"), then I EXPECT that I will get foo back, which will trigger a lazy load of the whole lazy object. I think the first scenario is more of an "eager" load scenario. I can see its utility if a user expects to be able to do lazyObject.foo style access after a call to getValue, but really I don't think thats so common that it needs to be addressed.

The syncMode thing took me reading the source to figure out why a call to store.getValue(lazyObject, "foo") wasn't working. I don't really want my whole store to always behave in syncMode (i.e. fetch, etc. should be asynchronous) but I really want synchronous calls in this and only this scenario.

So I guess my suggestion to simplify the code and the documentation is to:

  1. keep syncMode to force fetch, fetchItemByIdentity, loadItem, etc to use synchronous xhr
  2. keep loadLazyValues, but change its meaning -- don't eagerly fetch a lazy object, but instead, fetch the lazy object only when one of its properties that isn't already loaded is requested
  3. get rid of the the current meaning of loadLazyValues

The scenario where this may break is when you have a lazy _property_ as opposed to a lazy object. the current way to handle this is to create a property of an object that, although its "true" value is a native (string, numeric, etc), its "lazy" value is a lazy object:

lazyObject = {

$ref:"/lazy/1" someStringValue:{$ref:"/lazyString/1"}

}

when when you call store.getValue(lazyObject, "someStringValue"), I think you never want to get a the {$ref:"/lazyString/1"} object back.

But honestly, I think if we are solving the 80% case, the steps I outlined above will, IMHO, probably be the easiest to understand, and seem "right" to most users.

comment:4 Changed 11 years ago by maulin

(actually JsonRestStore? could handle the lazy property thing -- if there is a provided schema, and the property is anything but an object, then always initiate the lazy load, otherwise, just return the partially loaded lazy reference and wait for a call to one of the lazy reference's properties to do the load)

comment:5 Changed 11 years ago by Kris Zyp

Do you think we need to keep the loadLazyValues flag? Can we just always try to load on a getValue call to non-existent property on a lazy object? The idea of using the schema for determining eager loading for primitive values is clever (although it might be saved for v1.3).

comment:6 Changed 11 years ago by maulin

good point, perhaps we don't need it at all? if you *really* want asynchronous loading of an item's properties, you use loadItem, otherwise use getValue. I think loadLazyValues can go. And I think that regardless of syncMode, we always try to load on a getValue call to a non-existent property on a lazy object.

(and clearly the schema stuff is really only addressing a very small need, and is very low in priority)

thanks.

comment:7 Changed 11 years ago by Kris Zyp

Resolution: fixed
Status: newclosed

(In [14702]) Updated to honor id assignment from server, altered lazy loading mechanism, and updated CouchDBRestStore. fixes #7359 and fixes #7311

comment:8 Changed 11 years ago by dylan

Milestone: tbd1.2
Note: See TracTickets for help on using tickets.