cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Kienenberger <mkien...@gmail.com>
Subject Re: Creating a new ServerRuntime from an existing ServerRuntime
Date Fri, 27 Sep 2013 18:03:10 GMT
No, what you are suggesting is reasonable when there's only one
variation from the common ServerRuntime, which is currently my use
case.   What you're saying about caching this unrestricting qualifier
runtime makes sense for my situation, and I like to stick to the
recommended practices whenever possible.

The problem would be for when there are several.    In one instance, I
might need to turn off PaymentMethod's qualifiers.   In another, I
need to turn off PaymentHistory's qualifiers, in a third, turn off
both of them, in a fourth turn off a different entities.   I don't see
that this solution scales, but that's not really a problem for my
situation.

It just seems like there's no reason not to let people create a copy
of a runtime from an existing runtime so they don't have to create a
duplicate runtime out there for some obscure use case that doesn't
warrant storing it globally.

It's a hypothetical situation, so I guess it's not really an issue at present.


On Fri, Sep 27, 2013 at 1:48 PM, Andrus Adamchik <andrus@objectstyle.org> wrote:
>> I was able to do this in six easily-understandable lines of code with
>> a ServerRuntime(Modules) constructor, and I fear that your suggested
>> approach requires me to create several separate classes, store
>> configuration globally, and create new modules for each qualifier that
>> I need to disable or change.
>
> No, nothing like that :) I assume in both your and John's cases any number of runtimes
created have application scope (runtimes are not cheap, so you won't be starting them ad-hoc).
I noticed you have ServiceLocator, so keep using that. And just implement 2 methods there,
each indicating the purpose and/or flavor of a given runtime, say:
>
> - getCommonRuntime()
> - getAdminRuntime()
>
> And inside ServiceLocator in place where you create "common" runtime, create "admin"
one as well from the same set of modules. And use the same 6 lines of code to customize the
later. Those 6 lines you can either place in a subclass of XMLDataMapLoader (redefining it
in a module), or do it after the runtime is created (like you are doing now). For the purpose
of this discussion this is actually irrelevant, so I take back my earlier remark about pre
and post 3.1 way of doing things.
>
>> And John's use case is even more straight-forward than my own.
>
> Same solution.
>
> I guess I am too much of a dependency injection person, always assuming that referencing
some common object is cheap and easy. So maybe I am overlooking something?
>
> Andrus
>
>
> On Sep 27, 2013, at 8:03 PM, Mike Kienenberger <mkienenb@gmail.com> wrote:
>
>> While I can understand the desire for purity with that pattern, it
>> seems to me that it's too expensive to maintain in this use case.
>>
>> I don't want to have to maintain a factory for building runtimes and
>> track all of the configuration needed to do that, just to turn off a
>> qualifier.    The existing runtime contains everything necessary --
>> there's just no easy way to get at it.
>>
>> Maybe I am overlooking something.
>>
>> I know you are busy, but can you provide an example of how I would
>> perform the same task for which I provided code (turn off a qualifier
>> in an otherwise duplicate ServerRuntime deep inside business logic)
>> using modules?
>>
>> I was able to do this in six easily-understandable lines of code with
>> a ServerRuntime(Modules) constructor, and I fear that your suggested
>> approach requires me to create several separate classes, store
>> configuration globally, and create new modules for each qualifier that
>> I need to disable or change.
>>
>> And John's use case is even more straight-forward than my own.
>>
>>
>> On Fri, Sep 27, 2013 at 12:49 PM, Andrus Adamchik
>> <andrus@objectstyle.org> wrote:
>>>> So it looks like I can reuse modules to create my own runtime.
>>>
>>> Yes.
>>>
>>>> However, the current 3.1 API isn't very friendly toward this approach.
>>>
>>>
>>> Yes - see my other email. A common pattern is to have some kind of external factory
that defines the modules.
>>>
>>> Also I don't perceive 'copy' method as very useful. The point of a second runtime
is that it is somehow different from the first, and modules is what makes it different. I
think you are doing it in a pre-3.1-DI-way - creating a runtime first, then customizing it.
I would usually place customization code inside the modules, which are kind of deferred "closures".
>>>
>>> Andrus
>>>
>>>
>>> On Sep 27, 2013, at 7:39 PM, Mike Kienenberger <mkienenb@gmail.com> wrote:
>>>
>>>> So it looks like I can reuse modules to create my own runtime.
>>>> However, the current 3.1 API isn't very friendly toward this approach.
>>>> I had to clone the ServerRuntime class so that I could create my own
>>>> version so I could call CayenneRuntime(Module... modules) in my
>>>> constructor.
>>>>
>>>> Having a cloned ServerRuntime on which to make customizations seems
>>>> like a reasonable use case that we should support.   Can we add such a
>>>> method to ServerRuntime?   I think that's a better choice than making
>>>> it easier to create a ServerRuntime subclass.
>>>>
>>>> private ServerRuntime(Module... modules) {
>>>>   super(modules);
>>>> }
>>>>
>>>> public ServerRuntime copy() {
>>>>       return ServerRuntime(serverRuntime.getModules());
>>>> }
>>>>
>>>> It might be reasonable to make the private constructor public so that
>>>> someone can create ServerRuntimes where they are not required to pass
>>>> configurationLocation data but can provide their own alternative to
>>>> ServerModule.  This would have also worked in my case, removing the
>>>> need to have a copy() method.   However, I think the copy() method
>>>> provides assurance to the developer that this approach is viable.
>>>>
>>>>
>>>> Here's what my application code ended up looking like (using my cloned
>>>> class), and I think it's a good approach (except for the cloned class)
>>>> for these cases:
>>>>
>>>>       PaymentMethod paymentMethod = paymentHistory.getPaymentMethod();
>>>>       if (null == paymentMethod) {
>>>>           ServerRuntime currentRuntime = ServiceLocator.getCayenneRuntime();
>>>>
>>>>           // Payment method was invalidated at this point -- create
>>>> a runtime that can read invalidated payment methods
>>>>
>>>>           CopiedServerRuntime copiedRuntime = new
>>>> CopiedServerRuntime(currentRuntime);
>>>>           DataDomain dataDomain = copiedRuntime.getDataDomain();
>>>>           dataDomain.setSharedCacheEnabled(false);
>>>>
>>>>           EntityResolver entityResolver = dataDomain.getEntityResolver();
>>>>           ObjEntity paymentMethodObjEntity =
>>>> entityResolver.getObjEntity(PaymentMethod.class.getSimpleName());
>>>>           paymentMethodObjEntity.setDeclaredQualifier(null);
>>>>
>>>>           ObjectContext unrestrictedObjectContext =
>>>> copiedRuntime.getContext();
>>>>           PaymentHistory unrestrictedPaymentHistory =
>>>> unrestrictedObjectContext.localObject(paymentHistory);
>>>>           paymentMethod = unrestrictedPaymentHistory.getPaymentMethod();
>>>>       }
>>>>
>>>>
>>>> On Fri, Sep 27, 2013 at 11:46 AM, Mike Kienenberger <mkienenb@gmail.com>
wrote:
>>>>> The idea of creating a new ServerRuntime is good, but the
>>>>> implementation leaves  me with a few questions.    My ServerRuntime is
>>>>> created in the context of the web app.
>>>>>
>>>>> Is it reasonable to try to create it using the information in the
>>>>> existing ServerRuntime?   Can I pull the injector and modules out of
>>>>> the existing Runtime and reuse them to create a new runtime, or do I
>>>>> need to create copies of the existing modules and injector?   My guess
>>>>> is that each runtime needs unique injector and modules objects, but I
>>>>> want to minimize the work I need to do.
>>>>>
>>>>> It looks like I have to pull my configurationLocation out of the
>>>>> ServerModule, which doesn't really provide it.
>>>>>
>>>>> I'm not seeing an easy way to create a new ServerRuntime from scratch
>>>>> without having access to data which was only available back when the
>>>>> web application started up, short of storing that information
>>>>> somewhere globally and reusing it.
>>>>>
>>>>> On Tue, Sep 24, 2013 at 2:04 PM, Andrus Adamchik <andrus@objectstyle.org>
wrote:
>>>>>>> The "special DataContext" case where the qualifier should be
ignored can probably be handled by starting a separate ServerRuntime, where you can strip
off the qualifiers. For whatever overhead it creates (ideally not much), this has an advantage
of cleanly separating "spaces" with different ORM rules.
>>>>>>
>>>>>> Elaborating on this a bit… The old Configuration allowed multiple
DataDomains, each of those requiring its own DataMap(s) saved in the project upfront. Good
idea, but hard to use in practice.
>>>>>>
>>>>>> ServerRuntime (with single DD each) is more user-friendly. By starting
multiple independent runtimes you to easily reuse a single mapping project, tweaking each
in-memory copy local to each Runtime (as well as tweaking other parameters like cache). 2
Runtimes can reuse a single DataSource (JNDI, or otherwise), etc.
>>>>>>
>>>>>> Andrus
>>>>>>
>>>>
>>>
>>
>

Mime
View raw message