3b Transactions3b Transactions
DPML By Example
Home > Books > Tutorials and Training Guides > DPML By Example > 3b Transactions

Rate this page:
Really useful
Satisfactory
Not helpful
Confusing
Incorrect
Unsure
Extra comments:


What time is it Eccles?
Hold on a moment good fellow. I've got it written down on this piece of paper...

As any Spike Milligan devotee will testify, you have to commit things to documents. Sometimes even the time. DPML allows resources in the virtual filesystem to be written to as well as read, and of course it's all done with URI's.

The 1060 NetKernel is a concurrent processing environment. In the applications so far we've just assumed that it is taking care of all the resource management for us and ensuring that contention for resources is handled. However in order to write something to a resource we have to tell the operating system to ring fence it for us.

<irony> Let's demonstrate with a really cool and up to date example. Wouldn't it be great if we could count the number of times a resource is requested. Why don't we call such an application a 'Hit Counter'. You see this clever name gives it all away. It's a counter which counts 'hits', which is another way of saying accesses to a resource. The resource being an item for which a request has been made. So we'll make an 'Application which counts the number of accesses to a Resource' or a 'Hit Counter' for short. It's such a good idea it's sure to catch on. </irony>. "Humph, get on with it!!..."

View 'Hit Counter' application here
Try this application here

Not surprisingly this application increments a counter for every access. It is made safe for concurrent requests by using the lock and unlock accessors. By requesting a lock on the operand URI the developer is guaranteed synchronized access to the resource. Note however that lock and unlock are only a synchronization mechanism, an application that requires transactional access to a resource must take care to catch exceptions and take care of error processing.

What do other application instances do if we've got a lock on a resource?

If another application concurrently requests the same resource for reading it obtains the resource in whatever state it is currently in. There are no guarantees what that state will be. If another application wishes to write to that resource it will be unable to since we have a lock on it. The second application instance will block until we end the transaction.

Given that another application can read a resource whilst we're transacting it, it is generally a very good idea to keep operations on a locked resource very short and never write any semi-processed state to the resource that would cause problems for another application. As ever with concurrent design it is the application developers responsibility to ensure the value of a resource is valid for concurrent access.

Looking in detail at this app, the first instruction locks the uri of .../counter.xml, our hit counter XML resource. The second instruction uses STM which is Simple Tree Manipulation language, we created it since we frequently needed a simple way to manipulate an XML document without the complexity of XSLT. This STM operation uses the stm:set-xpath-eval operation to increment the value of the element /hits/counter, the result is targeted at the .../counter.xml URI which instructs the NetKernel to write the result to the resource. The third instruction releases the lock so that other application instances can access the resource. Finally the last instruction calls the expire accessor with an operand of this:response and a target of this:response. If we did not expire the response of this idoc it would be cached and subsequent results would obtain the cached value, therefore never executing the idoc and so the hit counter would be a static value. A detailed discussion of the dependency based caching architecture is available here

Argue all you like. It's a better MouseTrap

The observant will have noticed that the hit counter above is absolutely useless since it only counts hits to the hit counter! What we need is a general purpose hit counter that can be accessed from any application. Here's an application which uses a better hit counter.

Try this application here

As you can see we've finally reached parity with 1994's technology and have a splendid hit counter!

View the application here
View 'A Better Hit Counter' here

<instr>
  <type>dpml</type>
  <operand>app15b.idoc</operand>
  <hitcounter>mypage_counter.xml</hitcounter>
  <target>var:hits</target>
</instr>

The first instruction of this basic application is calling the general purpose hit counter. It introduces a new aspect of DPML, arguments.

We can see that the instruction is executing a sub-idoc, this time creatively called 'app15b.idoc', and that we are passing a named URI argument hitcounter.

The argument is exactly the same as any other resource reference. It can be either a URI or a literal - in this case it's a relative URI to 'mypage_counter.xml'.

In the hit counter process the URI argument 'hitcounter' is obtained from the request by using the toURI accessor.

<instr>
  <type>toURI</type>
  <operand>this:param:hitcounter</operand>
  <target>var:hitcounter</target>
</instr>

This looks at the request and obtains the URI for the given argument - the argument name is referenced in DPML with the parameter URI this:param:hitcounter. The result is returned as a canoncial URI, referenced as curi:var:hitcounter and used exactly as though it were a direct URI - don't worry about this indirection just now we'll discover more about curi: in the next section.

Arguments are very useful since they allow us to pass multiple resources to a DPML sub-idoc. They also allow us to build reusable code libraries since the sub-idoc has no hard coded URI's it uses only arguments passed in with the call from the parent idoc.

She expired peacefully in her sleep

Finally, a hit counter, by definition, shows a different value each time it is accessed. We are using the expire accessor, in order to make sure the NetKernel does not keep a cached copy of the idoc's result. This immediately expires the this:response document ensuring that it will not be cached and so is regenerated each time with the new hit count value.

Summary

In this section we learnt how DPML supports concurrent writeback synchronization with the lock accessor.

In addition we learnt that any element on a DPML instruction may be a URI or literal and will be passed as a named active URI argument on a NetKernel request.

The next section will follow indirectly...

© 2003-2007, 1060 Research Limited. 1060 registered trademark, NetKernel trademark of 1060 Research Limited.