You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Andrey Razumovsky <ra...@gmail.com> on 2008/10/24 09:27:45 UTC

Nested context on ROP proposal

Nested context on ROP proposal

Preface
CayenneContext definitely misses functionality avaliable for DataContext -
nested (child) contexts. This is a description of how to implement the
feature.

Functionality
It must be logically the same as DataContext's nested contexts. Main API
usage methods are:
-creation of nested context -> ObjectContext.createChildObjectContext.
-committing changes to parent Cayennecontext ->
ObjectContext.commitChangesToParent()
-committing changes to all context tree, likely until DataContext and
underlying database -> ObjectContext.commitChanges()
-rolling back current changes -> ObjectContext.rollbackChanges and
ObjectContext.rollbackChangesLocally().

Changes should go:
-from child to parent -> through DataChannel API
-from parent to child -> through EventManager API

Once again, feature should work same as via
DataContext.createChildDataContext(), so I will not describe it here more
in detail

API changes (possibly incomplete list)
Important note here is that all changes are only increasing method's
visibility or moving them from inherited class to superclass, so no user's
code will break.
New classes/ifaces:
none. all required classes are already in Cayenne.

Method changes/additions (all in ObjectContext, BaseContext, DataContext and
CayenneContext):
ObjectContext ObjectContext.createChildObjectContext() - new method, creates
and returns a new child ObjectContext. DataContext implementation calls
createChildDataContext()
DataContext DataContext.createChildDataContext() - needs deprecation,
previous method should be used instead. This is just another step to
unification Data- and Cay- contexts
BaseContext - to implement DataChannel, because both descendants need that
API. DataContext already has implementation.
EventManager getEventManager() impl is same for both contexts and should be
moved to BaseContext
QueryResponse CayenneContext.onQuery(ObjectContext context, Query query)
should be made public since now CayenneContext supports dataChannel API

public GraphDiff DataContext.onSync(ObjectContext originatingContext,
GraphDiff changes, int syncType) method should be moved from DataContext to
BaseContext
GraphDiff DataContext.onContextRollback(ObjectContext originatingContext) -
method used by previous method, also should be moved up
GraphDiff DataContext.onContextFlush(ObjectContext originatingContext,
GraphDiff changes, boolean cascade) - should be moved up to BaseContext and
made protected and abstract, because implementations will differ.

void DataContext.fireDataChannelCommitted(Object postedBy, GraphDiff
changes)
void DataContext.fireDataChannelRolledback(Object postedBy, GraphDiff
changes)
void DataContext.fireDataChannelChanged(Object postedBy, GraphDiff changes)
- now used by both contexts, so should be moved up to BaseContext and made
protected
boolean ObjectContext.hasChanges() - returns true if there are any modified,
deleted or new objects registered with this ObjectContext. This is useful
method to add to ObjectContext. dataContext already has implementation.

/**
* "Invalidates" a Collection of persistent objects. This operation would
remove each
* object's snapshot from cache and change object's state to HOLLOW. On the
next
* access to this object, it will be refetched.
*
* @see RefreshQuery
*/
void ObjectContext.invalidateObjects(Collection objects) - another useful
method from dataContext that should be added to ObjectContext


Obsolete method - void CayenneContextGraphManager.send(GraphDiff diff,
EventSubject subject, Object eventSource) now replaced by calls to
fireDataChannel* methods described above and can be removed. It is
package-private so no user's code should break.

Tests
Everything's quite simple with junits here because dataContext's nested
contexts already have full suite of tests. All we need is to convert them to
client classes.


I'm really looking for some feedback. I think this feature is must-have for
Cayenne and I'll need it in my work

Thanks,
Andrey

Re: Nested context on ROP proposal

Posted by Andrus Adamchik <an...@objectstyle.org>.
Please go ahead. Trunk is open for new development for a couple of  
weeks now.

Cheers,
Andrus

On Dec 8, 2008, at 12:16 PM, Andrey Razumovsky wrote:

> Okay, M5 is now branched, and if noone has objections on API  
> changes, I will
> soon commit
>
> 2008/11/11, Aristedes Maniatis <ar...@ish.com.au>:
>>
>>
>> On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:
>>
>> Are you suggesting developers to keep same validation on client &  
>> server in
>>> this case? Well, this means that we prefer first solution - to do  
>>> nothing
>>> :-) Actually I can think of situations when special server  
>>> validation is
>>> needed - e.g. when it takes long time and will be much longer via  
>>> ROP.
>>>
>>
>> Absolutely we need to be able to keep them separate. Sometimes. But  
>> because
>> client and server entity classes aren't in the same inheritance  
>> tree, it is
>> really hard to share the 90% of validation code which is identical.
>>
>> In our application, we validate on each keystroke, allowing us to
>> enable/disable the save button and implement nice GUI warnings.  
>> Obviously
>> this needs to be really fast on the client. And so there is more  
>> validation
>> on the server which does not exist on the client. But we've been  
>> bitten
>> sometimes by not keeping the two in sync where they should be.
>>
>>
>> Still, I agree and think we should leave this as 'known limitation'.
>>> In fact, beside this problem, I've already implemented nested  
>>> contexts
>>> and
>>> hopefully will commit after M5 is released.
>>>
>>
>> Terrific! I can definitely say we'll be able to give it a solid  
>> workout
>> here.
>>
>>
>> Andrey, you might like to add the special limitations to be aware  
>> of on
>> this page and a note about it being available in M6:
>>
>> http://cwiki.apache.org/confluence/display/CAYDOC/Nested+DataContexts
>>
>> I know it is slightly premature, but I'm very excited :-)
>>
>>
>> Ari
>>
>>
>>
>> -------------------------->
>> ish
>> http://www.ish.com.au
>> Level 1, 30 Wilson Street Newtown 2042 Australia
>> phone +61 2 9550 5001   fax +61 2 9550 4001
>> GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A
>>
>>
>>


Re: Nested context on ROP proposal

Posted by Andrey Razumovsky <ra...@gmail.com>.
Okay, M5 is now branched, and if noone has objections on API changes, I will
soon commit

2008/11/11, Aristedes Maniatis <ar...@ish.com.au>:
>
>
> On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:
>
> Are you suggesting developers to keep same validation on client & server in
>> this case? Well, this means that we prefer first solution - to do nothing
>> :-) Actually I can think of situations when special server validation is
>> needed - e.g. when it takes long time and will be much longer via ROP.
>>
>
> Absolutely we need to be able to keep them separate. Sometimes. But because
> client and server entity classes aren't in the same inheritance tree, it is
> really hard to share the 90% of validation code which is identical.
>
> In our application, we validate on each keystroke, allowing us to
> enable/disable the save button and implement nice GUI warnings. Obviously
> this needs to be really fast on the client. And so there is more validation
> on the server which does not exist on the client. But we've been bitten
> sometimes by not keeping the two in sync where they should be.
>
>
> Still, I agree and think we should leave this as 'known limitation'.
>> In fact, beside this problem, I've already implemented nested contexts
>> and
>> hopefully will commit after M5 is released.
>>
>
> Terrific! I can definitely say we'll be able to give it a solid workout
> here.
>
>
> Andrey, you might like to add the special limitations to be aware of on
> this page and a note about it being available in M6:
>
> http://cwiki.apache.org/confluence/display/CAYDOC/Nested+DataContexts
>
> I know it is slightly premature, but I'm very excited :-)
>
>
> Ari
>
>
>
> -------------------------->
> ish
> http://www.ish.com.au
> Level 1, 30 Wilson Street Newtown 2042 Australia
> phone +61 2 9550 5001   fax +61 2 9550 4001
> GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A
>
>
>

Re: Nested context on ROP proposal

Posted by Aristedes Maniatis <ar...@ish.com.au>.
On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:

> Are you suggesting developers to keep same validation on client &  
> server in
> this case? Well, this means that we prefer first solution - to do  
> nothing
> :-) Actually I can think of situations when special server  
> validation is
> needed - e.g. when it takes long time and will be much longer via ROP.

Absolutely we need to be able to keep them separate. Sometimes. But  
because client and server entity classes aren't in the same  
inheritance tree, it is really hard to share the 90% of validation  
code which is identical.

In our application, we validate on each keystroke, allowing us to  
enable/disable the save button and implement nice GUI warnings.  
Obviously this needs to be really fast on the client. And so there is  
more validation on the server which does not exist on the client. But  
we've been bitten sometimes by not keeping the two in sync where they  
should be.


> Still, I agree and think we should leave this as 'known limitation'.
> In fact, beside this problem, I've already implemented nested  
> contexts and
> hopefully will commit after M5 is released.

Terrific! I can definitely say we'll be able to give it a solid  
workout here.


Andrey, you might like to add the special limitations to be aware of  
on this page and a note about it being available in M6:

http://cwiki.apache.org/confluence/display/CAYDOC/Nested+DataContexts

I know it is slightly premature, but I'm very excited :-)


Ari



-------------------------->
ish
http://www.ish.com.au
Level 1, 30 Wilson Street Newtown 2042 Australia
phone +61 2 9550 5001   fax +61 2 9550 4001
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A



Re: Nested context on ROP proposal

Posted by Lachlan Deck <la...@gmail.com>.
On 11/11/2008, at 11:12 PM, Andrey Razumovsky wrote:

> Are you suggesting developers to keep same validation on client &  
> server in
> this case? Well, this means that we prefer first solution - to do  
> nothing
> :-)

Easy ;-)

> Actually I can think of situations when special server validation is
> needed - e.g. when it takes long time and will be much longer via ROP.

Additionally when for security reasons it only makes sense on the  
server.

> Still, I agree and think we should leave this as 'known limitation'.
> In fact, beside this problem, I've already implemented nested  
> contexts and
> hopefully will commit after M5 is released.

Great.

with regards,
--

Lachlan Deck




Re: Nested context on ROP proposal

Posted by Andrey Razumovsky <ra...@gmail.com>.
Thanks for your answer


>
> So validation works *on client* within
>> context which called commitChanges(). Changes to server (with server
>> validation & lifecycles) will proceed through all context hierarchy if you
>> call CayenneContext.commitChanges(),
>> not CayenneContext.commitChangesToParent().
>>
>
> What would the behaviour be for a non-nested context on client calling
> commitChangesToParent()?


I guess that should be same as with DataContext - normal commit to database.
Upper level is DB after all.

That's just the same as with
>> DataContext, I haven't invented anything new.
>>
>
> sure.
>
> As you correctly pointed out, problem occurs with the following sequence:
>> 1. Nested CayContext [with incorrect changes] is committed to parent.
>> Validation on nested client context succeeds
>>
>
> That seems normal. I mean currently during commit validation is only run on
> the server assuming success on client (where the server is like the parent).
> So it'll be the responsibility of the programmer to handle this.
>
> 2. Parent context is committed to server. Validation on client context
>> succeeds since it did in #1
>> 3. Server validation fails. Parent context changes are rolled back.
>> By default in nested context they do not.
>>
>> Right now I cannot think of ideal solution.
>> At the minimum we could just do nothing and hope that server validation
>> will
>> succeed if client did.
>>
>
> Yeah - that's fragile.
>
> We could check objects before committing to parent (i.e. do 'false' commit
>> to server), but I'm afraid that'll be too expensive.
>>
>
> Don't see this is necessary besides being expensive. This would be better
> served by allowing server/client classes to utilise a business logic shared
> static helper that can be shared between the server/client classes to
> perform validation against.


Are you suggesting developers to keep same validation on client & server in
this case? Well, this means that we prefer first solution - to do nothing
:-) Actually I can think of situations when special server validation is
needed - e.g. when it takes long time and will be much longer via ROP.
Still, I agree and think we should leave this as 'known limitation'.
In fact, beside this problem, I've already implemented nested contexts and
hopefully will commit after M5 is released.

Cheers,
Andrey

Re: Nested context on ROP proposal

Posted by Lachlan Deck <la...@gmail.com>.
On 24/10/2008, at 8:02 PM, Andrey Razumovsky wrote:

>> Would committing a nested context on the client cause a connection  
>> to be
>> made to the server and lifecycle events, validation run on the  
>> server for
>> objects in that context? If so, will changes which are made by  
>> lifecycle
>> events (eg. new objects created) be propagated to the client (which
>> currently doesn't happen) so they can be included in the parent  
>> context when
>> it is then committed?
>>
>> Or do they remain purely on the client until the parent context is
>> committed? In that case, what happens if the server validation  
>> fails for
>> objects in the child context?
>
> Nested context idea specifies that changes should be purely on the  
> client.

Indeed.

> Otherwise we lose ability to commitChangesToParent()
> Client nested context is normal CayContext, just with another  
> DataChannel,
> (i.e. source to commit changes to).


> So validation works *on client* within
> context which called commitChanges(). Changes to server (with server
> validation & lifecycles) will proceed through all context hierarchy  
> if you
> call CayenneContext.commitChanges(),
> not CayenneContext.commitChangesToParent().

What would the behaviour be for a non-nested context on client calling  
commitChangesToParent()?

> That's just the same as with
> DataContext, I haven't invented anything new.

sure.

> As you correctly pointed out, problem occurs with the following  
> sequence:
> 1. Nested CayContext [with incorrect changes] is committed to parent.
> Validation on nested client context succeeds

That seems normal. I mean currently during commit validation is only  
run on the server assuming success on client (where the server is like  
the parent). So it'll be the responsibility of the programmer to  
handle this.

> 2. Parent context is committed to server. Validation on client context
> succeeds since it did in #1
> 3. Server validation fails. Parent context changes are rolled back.
> By default in nested context they do not.
>
> Right now I cannot think of ideal solution.
> At the minimum we could just do nothing and hope that server  
> validation will
> succeed if client did.

Yeah - that's fragile.

> We could check objects before committing to parent (i.e. do 'false'  
> commit
> to server), but I'm afraid that'll be too expensive.

Don't see this is necessary besides being expensive. This would be  
better served by allowing server/client classes to utilise a business  
logic shared static helper that can be shared between the server/ 
client classes to perform validation against.

> Or we could send notification to children if parent commit failed,  
> but this
> is quite unnatural to make changes in child context behind the scenes.
> Would be great if we together thought about it
>
> Andrey

with regards,
--

Lachlan Deck




Re: Nested context on ROP proposal

Posted by Andrey Razumovsky <ra...@gmail.com>.
>
>
> Would committing a nested context on the client cause a connection to be
> made to the server and lifecycle events, validation run on the server for
> objects in that context? If so, will changes which are made by lifecycle
> events (eg. new objects created) be propagated to the client (which
> currently doesn't happen) so they can be included in the parent context when
> it is then committed?
>
> Or do they remain purely on the client until the parent context is
> committed? In that case, what happens if the server validation fails for
> objects in the child context?


Nested context idea specifies that changes should be purely on the client.
Otherwise we lose ability to commitChangesToParent()
Client nested context is normal CayContext, just with another DataChannel,
(i.e. source to commit changes to). So validation works *on client* within
context which called commitChanges(). Changes to server (with server
validation & lifecycles) will proceed through all context hierarchy if you
call CayenneContext.commitChanges(),
not CayenneContext.commitChangesToParent(). That's just the same as with
DataContext, I haven't invented anything new.
As you correctly pointed out, problem occurs with the following sequence:
1. Nested CayContext [with incorrect changes] is committed to parent.
Validation on nested client context succeeds
2. Parent context is committed to server. Validation on client context
succeeds since it did in #1
3. Server validation fails. Parent context changes are rolled back.
By default in nested context they do not.

Right now I cannot think of ideal solution.
At the minimum we could just do nothing and hope that server validation will
succeed if client did.
We could check objects before committing to parent (i.e. do 'false' commit
to server), but I'm afraid that'll be too expensive.
Or we could send notification to children if parent commit failed, but this
is quite unnatural to make changes in child context behind the scenes.
Would be great if we together thought about it

Andrey

Re: Nested context on ROP proposal

Posted by Aristedes Maniatis <ar...@ish.com.au>.
On 24/10/2008, at 6:27 PM, Andrey Razumovsky wrote:

> I'm really looking for some feedback. I think this feature is must- 
> have for
> Cayenne and I'll need it in my work

If you were closer I'd give you a hug. Your ideas on the surface look  
great.

Would committing a nested context on the client cause a connection to  
be made to the server and lifecycle events, validation run on the  
server for objects in that context? If so, will changes which are made  
by lifecycle events (eg. new objects created) be propagated to the  
client (which currently doesn't happen) so they can be included in the  
parent context when it is then committed?

Or do they remain purely on the client until the parent context is  
committed? In that case, what happens if the server validation fails  
for objects in the child context?

Ari



-------------------------->
ish
http://www.ish.com.au
Level 1, 30 Wilson Street Newtown 2042 Australia
phone +61 2 9550 5001   fax +61 2 9550 4001
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A