On Wed, Oct 17, 2012 at 10:29 AM, Thomas Mortagne <[email protected]> wrote: > Sounds very interesting and I'm +1 in general for the idea. > > Some remarks: > > * is it possible to decide that you don't want to clone some property > that has been declared as cloneable in the parent Context ? For > example in your isolated code you have a well know property that could > have been set in the parent context by any extension and which is > completely different from yours
Asking this because in your proposal you can't redifine a property. Maybe the answer is that we want to allow redefining a property. > * it does not seems to be possible to have a use case where you make a > property read-during for some time and then back to normal. Can you > make a property in a new EContext both inherit the value of it's > parent context and make it readonly even if the parent one is not ? > > On Wed, Oct 17, 2012 at 9:20 AM, Vincent Massol <[email protected]> wrote: >> >> On Oct 16, 2012, at 3:08 PM, Andreas Jonsson <[email protected]> wrote: >> >>> Hi, >>> >>> 2012-10-16 11:03, Vincent Massol skrev: >>>> Hi Andreas, >>>> >>>> It would be great if you could explain your real use case and the reason >>>> you wish to introduce this (I guess you have a use case where you need >>>> this :)). >>> >>> I want to put authorization information in the execution context, and I >>> want to trust that this information is carried over to any new execution >>> context that is activated in the scope of the current request. >> >> That's always true, except where there are bugs (i.e. code that doesn't >> clone the context but create a new one when it shouldn't) but that would be >> the same even with your proposal. >> >>> It is >>> also great if the object that holds the information cannot be replaced. >>> So, if you look at the code you will see that I have implemented a >>> rather aggressive enforcment of the combination of the attributes >>> read-only and inherited. >> >> Ok I'll need to read your code… :) >> >>> But also, the need for the inherited property already exists for >>> managing the properties "xwikicontext" and "velocityContext". Just look >>> at the TODO and FIXME in DefaultExecutionContextManager in the master >>> branch. >> >> I wrote that code and those TODO/FIXME :) >> >> There's only one issue and you'll still have it: it's about putting objects >> that can be cloned in the EC (that includes the velocitycontext and >> xwikicontext). >> >>> But the general idea is just to be able to associate any kind of >>> metadata with each property. It can be compared to how interpreted >>> languages handle variables. Take for instance bash, where you can just >>> set a variable to a value, wich implicitly declares the variable. But >>> you can also explicitly declare a variable, and in the declaration you >>> can provide flags that sets various attributes of the variable. (e.g, >>> declare -r variable='readonly value'.) >> >> I'd be fine if it solved a problem but so far I fail to see how your >> solution will solve the real issue we have now which is that the elements >> put in the EC are not cloneable... >> >>>> See below. >>>> >>>> On Oct 12, 2012, at 9:27 AM, Andreas Jonsson <[email protected]> wrote: >>>> >>>>> Hi everyone, >>>>> >>>>> I would like to propose to introduce a possibility to associate >>>>> properties in the execution context with metadata by declaring them. We >>>>> introduce the class 'ExecutionContextProperty' that will store the >>>>> metadata attributes, in addition to the actual property value. >>>>> >>>>> /** >>>>> * Declare a property in the execution context. >>>>> * >>>>> * @param key The key that names the property >>>>> * @param property The property to declare. >>>>> */ >>>>> public void declareProperty(String key, ExecutionContextProperty property) >>>> Does this mean the current ExecutionContext.setProperty() method would be >>>> deprecated/removed? >>>> >>>> Why not use instead: setProperty(String key, ECP property)? >>> >>> Setting and declaring a property are completely different concepts. In >>> a purely declarative model, properties would have to be declared before >>> being set. But what I'm proposing is more in line with what bash does >>> with variables. Setting a value on an undefined property will >>> implicitly declare it with default values for all attributes. You can >>> also provide an initial value when declaring the property (which of >>> course is required for read-only properties). >> >> I still think a single semantic with setProperty is simpler to understand >> for the user. He can either pass an untyped value or a type one. >> >> BTW what would the default property type? Cloned? >> >>>>> The metadata governs how the property should be treated when managing >>>>> the execution contexts. For instance, these attributes could be >>>>> supported: >>>>> >>>>> * Read-only - The value may not be updated within the the execution >>>>> context. >>>> How do you ensure this? So getProperty() would continue to return the >>>> value and not an ECP instance right? >>> >>> Yes, getProperty returns the value of the property. I have not added >>> any method to obtain the declared ECP instance as I don't see any need >>> for it right now. >>> >>> Of course, it is only the reference to the value that is guaranteed to >>> be read-only by the execution context. Depending on the application, it >>> may be desirable to make the object immutable, but that is not up to the >>> execution context to enforce. >>>> >>>> So when the user calls declareProperty() with the same key as an existing >>>> key it would be refused if it's been declared Readonly? >>> >>> A property may only be declared once in an execution context, so it will >>> be refused if the property is already declared. It doesn't matter if it >>> was an explicit or implicit declaration. Attempting to declare an >>> already existing property is an indication that something is wrong, so >>> raising an exception seems appropriate. >> >> I don't understand this. You mean that we don't have a single use case where >> we wish to update a property put in the EC? Like for example a counter that >> we want to increment… IMO there's a valid use case in modifying an existing >> property in the EC. > > You don't declare a new property in the case of a counter to use setProperty. > >> >>> If the property is read-only, then also setProperty will refuse to >>> replace the value. >> >> That one makes sense. >> >>>> Now imagine that I pass an ECP instance with a value of List. How do you >>>> prevent some from doing: getProperty("mylistkey").add(somenewelement)? >>>> >>>>> * Inherited - The property will be inherited from the current context >>>>> when replacing the execution context within the scope of a request. >>>> I don't understand this one, we create a new Execution Context for each >>>> Request. >>> >>> No, you are mistaken. We allow the creation and activation of several >>> execution contexts per request. That's why we have the kludges in >>> DefaultExecutionContextManager for copying and cloning "xwikicontext" >>> and "velocityContext". >> >> I'm pretty sure I'm right. We create a new EC for each Request and then >> there are parts of the code that require a clean context and for that they >> clean the current EC, push it and then pop it. >> >>>>> * Clone - Also clone the value when the execution context is cloned. >>>> What are the cases when we don't want to clone a property? I don't see >>>> any, for me we always want to clone them and in practice we would instead >>>> need to change our current signature to: >>>> >>>> setProperty(String key, Cloneable value) >>> >>> I do not want to clone my authorization data. It wouldn't hurt cloning >>> it, but it would serve no purpose. But I can also imagine that some >>> applications might want to put objects that are expensive to clone in >>> the execution context. >> >> Ah ok i think I understand what you mean now. You want to create a >> relationship between EC instances in the EC stack so that when reading a >> property value from the current EC, if the property is inherited it's taken >> from the next EC in the stack… >> >> So basically you wish to remove the need for cloning and replace it with >> inheritance. I get it now! :) >> >> It's interesting since it could make creating a new EC faster… I now >> understand the need for readonly. It's a bit dangerous though since it means >> there's no way of ensuring a clean EC and there's always the risk that you'd >> modify a value located in the previous EC in the stack. Unless we don't >> allow this, which would make sense (that's probably what you're doing I >> guess… :))... >> >>>>> * Type - The class of the value, for typechecking when replacing >>>>> the value. >>>> Can you explain more? Does it mean you wish that getProperty() returns a >>>> typed value? We can already do this by using generics. >>> >>> No, it just means that we can perform run-time type checking when >>> setting the value of a declared property. It would catch some errors >>> earlier, but not as early as compile time. >>> >>>>> * Non-null - The value may not be null >>>>> >>>>> So, the arguments for this proposal are at least two: >>>>> >>>>> 1. Catch errors early and simplify debugging. >>>> Can you explain more this point, I don't see the benefit over what we can >>>> already do. >>> >>> You can let the execution context provide some basic validation when >>> setting it. If you mark a value read-only, you will not need to worry >>> about if any component suddenly replaces or remove it in the middle of >>> the request. >>> >>>>> 2. Convenience of having properties automatically maintained across >>>>> execution contexts within the same request cycle. >>>> This is probably related to the inherit item which I don't understand. >>> >>> Yes it is. ;) >>> >>>>> What do you think? >>>> Honestly I don't see the need for this. >>>> >>>> What we lack IMO is proper Execution Context cloning and for this to >>>> happen we need to ensure we only cloneable items in the EC. As for the >>>> other "types" I don't really see a strong need but maybe I've >>>> misunderstood a few things (hence my questions above). >>>> >>>>> I would like to implement and merge this ASAP. >>>> We need to be very careful because the EC is a key class and introducing >>>> this means we're changing an important public API and we cannot go back >>>> easily (except through some deprecation cycles). IMO, seen the importance >>>> this should be a VOTE instead of a PROPOSAL. >>> >>> The proposal adds two methods and one class, while beeing backwards >>> compliant with current code. To me it seems that we have plenty of time >>> to change our minds before releasing 4.3-rc1 if I were to merge this >>> with master right now. Or is our policy that we have to commit to any >>> API that we have added in a milestone release? >> >> Well IMO it's much better to get an agreement before committing but you run >> the high risk to be asked to remove it in hurry at the last moment before >> the release and fix everything that's beed modified because of it + the >> stabilization risk when we're getting close to the release due to the >> rollback. >> >> We have a lazy commit rule but this rule means that any committer can ask >> for a rollback at any time. I'd have personally asked for one because I >> think this is a critical API and I would have liked to understand it before >> we put it in. >> >> Now, I've just understood your proposal and for me the winning argument is >> that your proposal makes it faster to create a new sub-EC for the same >> request and since we create an insane number of EC in the course of a >> request it can only be a good thing. Note: we need to check the place where >> we create those EC and fix them since I believe creation of a new EC is not >> always required. One such place for example is $doc.display() calls. I think >> each one create a new EC. >> >> So while your proposal adds a lot of complexity it's also interesting. I'd >> like to have other's opinion on this too. >> >> One thing that I'd like to see deprecated is the default setProperty() >> without Typing information. IMO we need to explicitly control each property >> with this proposal and not use a default. It becomes very important that >> each property's type is controlled since it can lead to important bugs. >> >> Thanks >> -Vincent >> >>> >>> I will propose a vote for it later in any event. >>> >>> >>> Best Regards, >>> >>> /Andreas >>> >>>> >>>> We would really need some feedback from several devs before going on with >>>> this IMO. ATM I'd like to understand it more before voting. >>>> >>>> Thanks >>>> -Vincent >>>> >>>> PS: Didn't get the time to read your implementation code yet >>>> >>>>> Best Regards, >>>>> >>>>> /Andreas >> _______________________________________________ >> devs mailing list >> [email protected] >> http://lists.xwiki.org/mailman/listinfo/devs > > > > -- > Thomas Mortagne -- Thomas Mortagne _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs

