|
NetKernel News Volume 1 Issue 31
June 4th 2010
What's new this week?
- Several updates in the repositories including
- layer0 enhanced declarative request supporting varargs
- HttpBridge update to make requests for opaque request parts, such as URL, query params and method, cacheable even from the httpRequest: space.
- Discussion of vararg (variable argument) patterns.
Repository Updates (NKSE/EE 4.1.1)
layer0: - fix to bnf to support a?b etc - wildcards at the start of grammars - support for tolerant attribute on argument tag in decl request - support for varargs in decl request to relay any unspecified args - (BIG) implemented caching with pass by value by adding equals method on ValueSpace - fixed regex type of float in grammars - grammar encoding type of "url-query" to support the correct encoding/decoding of queryStrings from http
nkse-dev-tools: - updated grammar kitchen doc to be in sync with current state of master document - updated new module wizard to put /etc/system/Tests.xml in standard location
dpml: - made transreptor visible outside module for advanced use cases
doc-content: - various updates to reflect changes - doc to describe extending control panel with custom panels, icons and embedded tools
text-search: - Added active:textIndexDelete allowing an index item or items to be deleted from the index.
jabber-xmpp: - patch to config to disable client/server
http-server: - fix to url decoding - pass full url inc query string to bridge - added httpRequest:/query to return query string on request - (BIG) caching of requests that access only url, query and or params from httpRequest (see below).
http-client:
- Fixed documentation for default timeouts.
front/back end HTTP fulcrums: - remove query string from request url
nkse-system: - optimise startup by pre-requesting system metadata state in background at startup
visualizer - show async requests ("async" in verb column)
HttpBridge Updates
So last week I was on my high horse explaining how the relationship between a transiently scoped space affects cacheability. In particular how the HttpBridge's httpRequest: space is transient and therefore has some subtle implication for application development.
This week I'm here to say forget everything I said last week! We've taken on board the expectation that accessing opaque parts of the request (such as query parameters, or the URL) should not detrimentally affect the cachability of the application layer.
We've managed to devise a cunning pattern in which the HttpBridge now injects two transient spaces for each http request. One space contains the transient "tainted" state, such as httpRequest:/body and httpRequest:/header/xxx. The other contains the immutable extrinsic state that is opaque in the http request, such as query parameters, URL etc.
The API and model of the HttpBridge is not changed. You still consider that there are two sets of resources available in the httpRequest: and httpResponse: sets. Therefore, to the application, there is no change necessary.
However, from the system's point of view, we now have immutable opaque state coming from a separate space. This space is constructed such that its isEquals() equivalence test (which is used for the scope caching equivalence high water mark algorithm) now internally compares the immutable values and their access pattern. So two different spaces with the same immutable resources will be regarded as equal.
The net result is that even though every http request has transient state spaces injected for it. When we compare a representation's cacheability we're able to determine the overlapping equivalence between spaces and so still serve the representation from cache.
Net affect to you is that touching the httpRequest:/param/xxxx etc will still result in your response being cacheable.
As one final update, we've also made it so that the HttpBridge will pass through the explicit query parameters as part of the internal request provided that you modify the rewrite parameter to stop its stripping these off.
All this being said, the larger strategic picture I was painting last week still holds. Understanding the affect that scope plays in caching will be relevant as we move to implement the space runtime capability.
Variable Arguments (varargs)
Often you want to have an interface that supports an indeterminate set of arguments. The active grammar syntax already allows this, for example...
<identifier>active:myTransform</identifier>
<argument name="transform" min="1" max="1" />
<varargs />
</grammar>
active:myTransform+transform@foo active:myTransform+transform@foo+arg1@bar+arg2@baz
To use a grammar like this you could bind an accessor endpoint class to the address space like this...
<grammar>
<identifier>active:myTransform</identifier>
<argument name="transform" min="1" max="1" />
<varargs />
</grammar>
<class>myTransformAccessor</class>
</accessor>
The active grammar syntax supports the <varargs/> tag. But underneath this actually takes advantage of the more general identifier grammar syntax which supports <optional> groups. Therefore with the general grammar you can write very rich vararg grammmars.
For example here's a grammar that matches any number of restful paths...
<group name="all">res:/base
<group max="*" min="1">
<optional>/</optional>
<group name="path">
<regex type="alphanum" />
</group>
</group>
</group>
</grammar>
res:/base/1/2/3 res:/base/1/2/3/a/b/c
And provides internally an ordered set of arguments called "path" each with its corresponding value.
Of course an accessor doesn't really care about its grammar. It only ever needs to consider the name of the argument and its value, not how it is structured in the external request.
Ok. So that covers a regular Java accessor. But what about if you wanted to map a request to a dynamic langauge runtime using the mapper? For example, using the grammar we had before...
<config>
<endpoint>
<grammar>
<identifier>active:myTransform</identifier>
<argument name="transform" min="1" max="1" />
<varargs />
</grammar>
<request>....see below...</request>
</endpoint>
</config>
<space>...imports not shown...</space>
</mapper>
<identifier>active:groovy</identifier>
<argument name="operator">res:/resources/myTransformGroovyImpl.gy</argument>
<varargs />
</request>
active:myTransform+transform@foo
is mapped to
active:groovy+operator@res:/resources/myTransformGroovyImpl.gy+transform@foo
and
active:myTransform+transform@foo+arg1@bar+arg2@baz
is mapped to...
active:groovy+operator@res:/resources/myTransformGroovyImpl.gy +transform@foo+arg1@bar+arg2@baz
And the groovy code can do as the Java example above and inspect the request for the transform and the set of varargs.
You'll see that the declarative request doesn't care what the structure of the grammar is, so you could just as easily use <optional> general identifier grammars.
Have a great weekend.
Comments
Please feel free to comment on the NetKernel Forum
Follow on Twitter:
@pjr1060 for day-to-day NK/ROC updates
@netkernel for announcements
@tab1060 for the hard-core stuff
To subscribe for news and alerts
Join the NetKernel Portal to get news, announcements and extra features.