Graham,
On May 3, 2011, at 1:46 PM, Graham Triggs wrote:
> On 3 May 2011 20:34, Mark Diggory <mdigg...@atmire.com> wrote:
> Example: Hacking Domain Model Locally
>
> Right now, to add behavior to DSpace when Item state is altered has two
> options:
>
> a.) Alter the Item code
> b.) Write a consumer.
>
> The problem with (a) is that we need to maintain differences against core
> codebase and merge those differences over time, this is a problem when we
> have multiple projects / addons altering the core codebase. Which wins, how
> do we maintain both over time, altering the Domain Model is great until you
> have a larger community with lots of unique customizations
>
> The problem with (b) is that we can't participate in the transactional window
> and utilize the Context /database capabilities to complete our CRUD
> operations. We have to spawn our own transactional window after the current
> transaction and we cannot use foreign key constraints against the dspace data
> model tables to assure our database tables integrity, resulting in a lot of
> extra coding to roll our own integrity checking.
>
> Let's not confuse how the subsystems currently work, with how they have to
> work. Right now, when an event is 'fired', it is queued for execution after
> the current context is committed. That doesn't mean we have to restrict
> ourselves to only having those types of events - it's feasible to rework the
> event system to allow 'immediate' consumers... where they are executed as the
> event is fired, and where they participate in the active context.
I think we should work to keep the Data Access Layer and the Business Logic
Layer separate. I see the Event Manager as Business Logic layer and the DAO as
Persistence layer. If you need to enforce integrity for an Addon that works
very closely with the database, then your more than likely working in the Data
Access Layer. If your running a secondary service that needs to be informed
about changes in the Domain Model after their persistence has been successfully
completed, then the EventManager / Service is appropriate.
In DSpace 2.0 these are separate as well, with the RequestService/Interceptor
allowing in transaction work to happen while the EventService is for issuing
events to consumers/listeners that are trying to keep in sync with the platform.
When do you need your addon to be tied to the transactional window, you need it
when the Addons data is considered "as mission critical" as that of the core
data model. For instance, in the Versioning prototype I am working on, it
needs to be closely tied to the success of the persistence of the DSpaceObject,
If there is a problem in the versioning, we need to roll back the whole
transaction. We should be looking to tie the Versioning logic into the
Persistence tier, and, its highly likely that the versioning will be tied to
the underlying persistence anyhow, we will implement versioning in a legacy
dspace rdbms quite differently than we would in a Fedora repository.
I'm very wary of adding more complexity to the EventManager, and we already
have something in dspace-services to assist in abstracting the transactionality
of the DSpace Context away from the Application Code, that is the
RequestService and Request Interceptors. My latest work in the Domain Model
and supporting Repository/DAO classes place the org.dspace.core.Context into
the Request and registers a RequestInterceptor responsible for completing or
aborting it at the end of the request cycle.
For example, the following contextservice can be looked up if access to the
current context is required, but it is not necessary for calling code to get it
directly when executing DAO call.
http://scm.dspace.org/svn/repo/modules/dspace-core/trunk/impl/src/main/java/org/dspace/core/LegacyContextService.java
DSpace dspace = new DSpace();
CollectionService cs = dspace.getSingletonService(CollectionService.class);
Collection col = cs.find(id);
col.setName("Some text");
cs.update(col);
Behind the CollectionService, it will pickup the current Context from the
request when necessary and provide the commit, as opposed to
Context context = new Context();
Collection col = Collection.find(context, id);
col.setName("Some text.");
col.update();
context.commit();
So if you want to introduce additional tasks that need to occur in the request
cycle, they are added as RequestInterceptors that happen prior to Context
Intercepter being closed.
As for the EventManager/Consumers, in DSpace 2.0 we've proposed their
replacement by the EventService and Listeners
http://scm.dspace.org/svn/repo/modules/dspace-services/trunk/api/src/main/java/org/dspace/services/EventService.java
Which means that the Usage and Context Events would be merged into one
infrastructure. I think its wise to clearly separate the systems that are
within transaction (and thus need to be responsible enough to participate in
the transaction) from those that simply monitor the application and process
change/read events. It will be clearer to other developers to keep the two
separate
Also, bear in mind that by making the EventManager/Consumers participate in the
transaction, Context.commit and Context.complete get their definitions a bit
blurred, right now they are responsible for commiting/aborting the transaction
window, now suddenly they are for completing further persistence activities
prior to closing the window.
> And we can still use foreign key constraints in the 'immediate execution'
> consumers. But, for any add ons, I would strongly argue that you should not
> use foreign key constraints. Any add ins that start imposing database
> integrity constraints are going to cause havoc during upgrades if we want /
> need to make changes to the core model.
Yes and No. When the implementation its closely tied to the DAO implementation,
you will want to be able to use the actual capabilities of the persistence
platform to make your addon more efficient.
I think we should be focused on assuring those writing addons have a "best
practices" from the core developers so that we can predict how constraints will
come into the picture. an "immediate execution consumer" (or in
dspace-services, a Request Interceptor) should be able to be delivered by an
addon, and in such case that addon needs to participate "Responsibly" in the
transactional window, including knowing how to rollback what it has done in the
event the context is aborted or the request fails with an exception. If that
addon implements this internally as a foreign key or as its own integrity check
is its own private business.
>
> I offer up that the benefits of the Domain Model and the Service Manager are
> that we be able to attain the "happy medium" where Addons can participate in
> the transactional window and contribute their own database tables into DSpace.
>
> By utilizing the SOA approach, we create chained DAO services that can
> participate in the transaction window. This was Jim Rutherfords original
> idea with the Stackable DAO.
>
> https://github.com/DSpace/DSpace/blob/dspace-dao-prototype/dspace-api/src/main/java/org/dspace/dao/StackableDAO.java
>
> https://github.com/DSpace/DSpace/blob/dspace-dao-prototype/dspace-api/src/main/java/org/dspace/content/dao/ItemDAOFactory.java
>
> What James was struggling with was the means to configure the stack of DAO
> that would participate in the transactional window. I think that with the
> Spring Service Manager, we now have an opportunity to answer his question.
>
>
> I really didn't like the Stackable DAO design - I always viewed it as a
> kludge for not having immediate / in-context consumers. My biggest complaint
> is that it either makes or model more rigid, or it makes the add-in DAOs
> fragile. Every change that gets made to the DAO contracts have to be
> reflected in any add-in based off of it.
The Stackable DAO is more than an immediate in-process consumer by design, its
specifically targeting being a member of the call stack for the DAO method in
question (ItemDAO.delete(), CollectionDAO.update()) and as such, there's no
need to be messing about with "extraneous mapping of Events to consumers and
all the extra code associated with that". Its less fragile and rigid than
writing an extensive messaging framework to handle processing the transaction
that has little or no specification other than its own obtuse internal business
logic.
It is just easier to comprehend if one wired the members of the call stack
directly in Spring
ItemDAO.update() --> MyItemDAO.update() --> YourItemDAO.update();
ItemDAO.delete() --> MyItemDAO.delete() --> YourItemDAO.delete();
CollectionDAO.delete() --> MyCollectionDAO.delete() -->
YourCollectionDAO.delete();
With this at least you can predict the call stack in your configuration
As opposed to
Item.update() --> Context.addEvent(event) --> Context.commit() -->
EventManager.dispatchEvent(event) --> Dispatcher.callConsumer(event) -->
Consumer.consume(event) --> verbose conditional switch logic to figure out what
the hell generated the event and what to do with it now.
Which looks clearer to you?
> Compare that to the event notification mechanism - the API for passing
> messages being consistent, and far less likely to break add-ins, even if we
> make changes to what the DAOs do.
Bear in mind that the messaging itself originated under a proposal to introduce
asynchronous JMS style event Queues and I haven't a clue how we'd maintain a
transactional system across asynchronous queuing. Nor to I even want to think
about it. The EventManagers already a complex beast, please, lets not make it
more complex.
> A secondary issue is that a stacked DAO is as near as damn it an interceptor
> - and as interceptors are familiar design pattern, and widely used within
> Spring. So if you did go this route [and configured it through Spring] then
> it would be better to keep it consistent with standard concepts.
Both the DAO and Repository DDD DesignPatterns are also fairly prevalent
standard concepts. Call them what you want.
> But the immediate execution event mechanism is better suited to your view of
> having reliable add-ins.
I think my points have been made above...
Mark
--
Mark R. Diggory
@mire - www.atmire.com
2888 Loker Avenue East - Suite 305 - Carlsbad - CA - 92010
Technologielaan 9 - 3001 Heverlee - Belgium
------------------------------------------------------------------------------
WhatsUp Gold - Download Free Network Management Software
The most intuitive, comprehensive, and cost-effective network
management toolset available today. Delivers lowest initial
acquisition cost and overall TCO of any competing solution.
http://p.sf.net/sfu/whatsupgold-sd
_______________________________________________
Dspace-devel mailing list
Dspace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dspace-devel