UnitOfWork via remoting

Posts   
 
    
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 09-Apr-2008 11:45:06   

Imaging I have a single root entity on the client machine and that was fetched with a whole stack of prefetch paths and nested to multiple levels.

User then changes a single field on this root entity and clicks Save. I then Add the root entity to a UnitOfWork and send it via remoting to a server-side service. (Using UnitOfWork2 because we also collect any deleted entities too)

It seems to me that even though database-wise, only a single entity will be ultimately be changed, the whole entity graph will be serialized/deserialized (not by the UnitOfWork2 specifically but just because it happens to be in the tree with the single changed entity) on its way to the server and then, for the most part, ignored.

Is this correct?

Cheers Simon

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 09-Apr-2008 12:22:52   

Only if you added the root entity to the UnitOfWork specifying true for the recurse parameter.

public bool AddForSave( IEntity entityToSave, bool recurse )

Otherwise only the passed entity gets added to the UoW.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 09-Apr-2008 18:24:05   

To be more precise: by default the unitofwork uses optimized serialization (this is a flag on the unitofwork object). This means that it calculates the queues for persistence first, and all entities in these queues are send over. All other entities are ignored.

With fast serialization, this is different. It serializes the entities added to the unitofwork using Serialize(entitycollection). please see: FastSerializer.Serialize(UnitOfWork2 unitOfWork)

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 10-Apr-2008 06:29:20   

Otis wrote:

To be more precise: by default the unitofwork uses optimized serialization (this is a flag on the unitofwork object). This means that it calculates the queues for persistence first, and all entities in these queues are send over. All other entities are ignored.

With fast serialization, this is different. It serializes the entities added to the unitofwork using Serialize(entitycollection). please see: FastSerializer.Serialize(UnitOfWork2 unitOfWork)

Yes, I see that.

But although only one entity will be in the UnitOfWork save queue in my example, all of its member collections contents and their member/contents etc. will go with that one entity.

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 10-Apr-2008 09:40:51   

Hmm, you're right. There IS a mechanism build in which cuts off these hierarchies (used in the removedentitiestracker). I could check if this is usable here too. The main thing is that the queues contain all the entities which might be saveable. So not only the dirty entities but also the ones which have FK syncs pending (non-dirty entity which refers to new entity. If new entity is saved, the FK in the non-dirty entity gets set and the non-dirty entity is dirty as well, so is also considered a saveable target).

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 10-Apr-2008 11:15:44   

Otis wrote:

Hmm, you're right. There IS a mechanism build in which cuts off these hierarchies (used in the removedentitiestracker). I could check if this is usable here too. The main thing is that the queues contain all the entities which might be saveable. So not only the dirty entities but also the ones which have FK syncs pending (non-dirty entity which refers to new entity. If new entity is saved, the FK in the non-dirty entity gets set and the non-dirty entity is dirty as well, so is also considered a saveable target).

I see your reasoning behind a non-dirty entity still being considered a saveable target due to a pending FK sync. Definitely makes sense when the UnitOfWork is not remoted.

But doesn't remoting change this scenario? ie If the client sends the server a UnitOfWork2 and it is committed there then for our uses at least, we would never send that UnitOfWork2 back to the client so the syncing (and implicitly the transmission) entity is irrelevant.

If you were able to find a way a stripping out the hierachies, what scenarios would anything contained in the deserialized UnitOfWork2 get remoted back to the client? Even if they were updated and returned, how would those updates be reincorporated back into the client-side entities?

Maybe a feature for v3 then? Gotta keep you on your toes. wink

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 10-Apr-2008 13:15:40   

simmotech wrote:

Otis wrote:

Hmm, you're right. There IS a mechanism build in which cuts off these hierarchies (used in the removedentitiestracker). I could check if this is usable here too. The main thing is that the queues contain all the entities which might be saveable. So not only the dirty entities but also the ones which have FK syncs pending (non-dirty entity which refers to new entity. If new entity is saved, the FK in the non-dirty entity gets set and the non-dirty entity is dirty as well, so is also considered a saveable target).

I see your reasoning behind a non-dirty entity still being considered a saveable target due to a pending FK sync. Definitely makes sense when the UnitOfWork is not remoted.

But doesn't remoting change this scenario? ie If the client sends the server a UnitOfWork2 and it is committed there then for our uses at least, we would never send that UnitOfWork2 back to the client so the syncing (and implicitly the transmission) entity is irrelevant.

No, that's not the scenario I'm talking about.

Say you have an entity X which is previously associated (via an FK) to an instance of Y, namely Y1. Now, you change X to be associated with another instance of Y, Y2. Y2 is new. When Y2 is saved, the FK of X to Y2 will get the new PK value (e.g. an identity field) of Y2. This will make X dirty and it has to be saved as well (otherwise you'll lose the FK reference to Y2 in X!).

If X isn't sent to the server, you'll only get Y2 saved, but never get the new FK value for X saved. This isn't something to optimize away, so these entities have to be send over.

If you were able to find a way a stripping out the hierachies, what scenarios would anything contained in the deserialized UnitOfWork2 get remoted back to the client? Even if they were updated and returned, how would those updates be reincorporated back into the client-side entities?

Maybe a feature for v3 then? Gotta keep you on your toes. wink

Entities which are transported to the server still have their original state at the client (as they're copies), so you've to refetch the graph.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 11-Apr-2008 10:00:41   

I've planned it in for a level 2 (so not top priority) for v2.6. If time permits it's done, otherwise it's postponed. As said, there is a mechanism in place already which cuts off hierarchies in remoting. So if this can be utilized for this too, it should be rather easy.

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 13-Apr-2008 07:15:09   

Otis wrote:

I've planned it in for a level 2 (so not top priority) for v2.6. If time permits it's done, otherwise it's postponed. As said, there is a mechanism in place already which cuts off hierarchies in remoting. So if this can be utilized for this too, it should be rather easy.

To be honest, I wasn't expecting a library change anyway - I was just asking the question but now its being considered seriously, I have thought a bit more about it. smile

One problem I foresee, depending on how your existing mechanism works, is that the original client-side collection/entities might be altered because they are placed in the UnitOfWork. If those member collections/entities are bound in a grid or whatever then might they suddenly get ListChanged events and data disappears off the screen whilst they are Saving?

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 13-Apr-2008 10:08:01   

No, it's a flag inside the entity. It's currently called _markedForDeletion, and the serialization code then doesn't serialize related data into the stream when that flag is set. This is for entities which are placed in a removedentitiestracker which is then serialized: you don't want their complete graphs send with them wink

If I can refactor the code using that flag a bit (and renaming the flag) it just affects logic, not data.

Frans Bouma | Lead developer LLBLGen Pro