Resolving URIs

Poster Content
nk4um User
Posts: 54
April 23, 2008 01:20
Tony,

I appreciate the time and effort you expended to explain, or clarify, my misunderstanding about NK and ROC. It is true that I am still mapping concepts from my non-ROC background to NK and its very different view of how systems can be built.

I will read your post a few more times as questions aren''t so much needed as much as an acceptance that certain things work certain ways in NK and learning NK mechanisms will eventually make my life easier.

I feel like a marathon runner at mile 8 (or perhaps mile 12): certain in the knowledge that I still have a ways to go, but that the end is in site.

Thank you again!

Carlos
Like · Post Reply
nk4um Administrator
Posts: 607
April 22, 2008 09:33ROC Abstraction
Hi Carlos,

I see you thrashing around a bit with some of these concepts so I''ll try and explain with some background on the principles of ROC (Resource Oriented Computing) I find the comparison to DOS and UNIX glob processing unhelpful as a deeper knowledge of the abstraction will show that both approaches can be implemented with appropriate implementations of language-runtimes (shells) and accessors.

Resource Identifiers are treated as opaque by the infrastructure (the kernel). So when scheduling and resolving it is all based upon loose pattern matching. This is very important for the generality of the abstraction.

NetKernel libraries mostly (where appropriate) use the convention of active URI syntax for accessors. When accessors and their clients use the specialisation of the general URI syntax the URIs become less opaque but arguments can be extracted from the identifier. These arguments are nested URIs that are still to be treated as opaque at this level.

Accessors have a choice about how these argument URIs are treated.

1) Arguments are resource references so they can be used to issue sub-requests. I.e. the arguments are passed are references to resources that the accessor should use. Arguments are aliased into the address space seen by an accessor as: this:param:[argument-name] (excuse the legacy of this:param in the identifier). This provides a level of indirection. So for example an accessor could SOURCE the resource referenced by argument named path with:
context.source("this:param:path");

Internally to the NKF API this is translated to
context.source("env:path")

2) URI''s are treated as identifiers to be parsed and processed locally. This is a rare case. It is useful for lightweight passing of values. i.e.
active:addNumbers+a@number:1+b@number:2. Typically you would be better off using data: URIs. The problem is that constructing requests like these are hard because NKF treats "1" as a relative URI and tries to absolutize it against the  current working URI of the client. The following method allows an accessor to get the argument identifier as a string to be processed:

String INKFRequestReadOnly.getArgument(String aName);



Let us look at your example: (code not compiled so excuse typos)

A client uses the following code to issue a request to your accessor:

INKFRequest req = context.createSubRequest("active:existsOnPath");
req.addArgument("executable","data:,diff");
req.addArgument("path","env:path");
req.setAspectClass(IAspectBoolean.class);
IAspectBoolean exists = (IAspectBoolean)context.issueSubRequestForAspect(req);


This would issue a request with the following identifier:

active:existsOnPath+executable@data:,diff+path@env:path


Inside your existsOnPath accessor you can gain access to the arguments in the following ways with the following results:

// get the identifier or string value of an argument
String executableIdentifier = context.getThisRequest().getArgument("executable");
// ASSERT executableIdentifier.equals("data:,diff");


// source the resource referenced by the argument and get the result as a string
import com.ten60.netkernel.urii.aspect.IAspectString;
IAspectString sa=context.sourceForAspect("this:param:executable",IAspectString.class);
String executable = sa.getString();
//ASSERT executable.equals("diff");

In this example the accessor looks up the executable parameter''s identifier and then issues a sub-request. This sub-request will resolve to the layer1 data: URI accessor (imports willing)

Now if we tweak our client code to be the following:

INKFRequest req = context.createSubRequest("active:existsOnPath");
req.addArgument("executable","active:randomExecutable+startsWith@data:,d");
req.addArgument("path","env:path");
req.setAspectClass(IAspectBoolean.class);
IAspectBoolean exists = (IAspectBoolean)context.issueSubRequestForAspect(req);


Assume we have created an accessor that generates a random executable name bound to the identifier active:randomExecutable.

When we execute the request our existsOnPath accessor it will still work. It doesn''t know about active:randomExecutable and doesn''t need to. It is opaque and contains nested arguments. It simply makes the request for it.

I hope this description and example is helpful. I have deliberately skipped over concepts like current working URI (CWU) and Pass-by-value arguments for simplicity.

The ROC abstraction behind NetKernel has been used and refined over many generations of implementation from it''s early days in Hewlett Packard Labs. It isn''t perfect but we are pretty happy with it. Not happy enough with it that we are complacent though... we have learned a lot over the last few years guiding new users into the way. NetKernel4 is the works with it''s focus on a more coherent ROC user abstraction.
Like · Post Reply
nk4um User
Posts: 54
April 22, 2008 02:55
This is certainly interesting. I am going to slowly port my accessors to use sub-requests and see where the similarities in behavior are, if any. Quickly adding code at the AbstractAccessor level did not give me the results I was looking for and quickly became a mess.

I will soldier forward and hope for the best. I will post my findings to the list.
Like · Post Reply
nk4um User
Posts: 54
April 22, 2008 01:34
Hmm. This could get interesting. ;) I will also admit that I am poking at various parts of NK because I think I understand how it works and I continue to find that I have incorrect/invalid/insane perspectives of how NK works.

Let''s say that I have a URI

ffcpl:/image/MyImage.jpg/crop/100/100/50/50

which resolves to the made-up-accessor:

active:myImageCrop+image@MyImage.jpg+x@100+y@100+width@50+height@50


Now let''s assume that myImageCrop returns an ImageAspect like the existing accessor imageCrop. Anyone who nests this accessor call in their URI already knows what they are getting. Once the accessor gets this result it can then transform it into anything it wants.

In addition if the accessor needs this result converted into something else prior to it becoming the final argument, couldn''t it also nest this call in a transreptor? If it wants to do a manual transformation there is nothing stopping it from doing that as well.

Also, all accessors have known return types (strings, images, streams, etc.). Why wouldn''t it be safe to assume that in a nested URI? I have been taking the results of my accessors and wrapping them in StringToCanonicalBoolean. That is a major assumption (that a string boolean is being returned), but it seems to work based on my assumption that the URIs I am nesting resolve to strings.

I will need some more convincing to believe that NK can''t execute nested URIs and simply give the calling accessor the un-transrepted result. If an accessor were to change its result format wouldn''t it break a lot of things? I realize that the accessors can do all kinds of things to prevent this, but the average accessor I am writing, perhaps incorrectly, assumes that things will work a certain way and that they will continue to work that way.

Now, with all that said, I realize that NK works the way it works. I am going to add some code to my personal AbstractAccessor that will treat any and all incoming arguments like sub-requests. This way, when my accessor asks for any incoming arguments the fully (?) resolved arguments will be returned. It just feels weird handling something that seems custom-made for the NK URI resolver. I will get to see up-front-and-personal how the results of the nested calls look and how my perspective is incomplete/incorrect/insane.

I appreciate your patience!
Like · Post Reply
nk4um Administrator
Posts: 158
April 22, 2008 00:10
Carlos,

In response to your other post I explained the two phases NetKernel uses when processing a request: http://1060.org/forum/topic/386/1

In the final part of your post you wonder if NetKernel should process a sub-request for "path:env" prior to binding to and scheduling the endpoint. You suggest that a string should be returned. That approach might work in Unix where the standard representation form is text. NetKernel is a much richer environment and in fact any representation type can be requested. In NetKernel it is up to the endpoint itself to specify if it needs the returned representation as IAspectString, IAspectDOM or any other of the many available representation types.

-- Randy
Like · Post Reply
nk4um User
Posts: 54
April 21, 2008 23:57
Let me see if I understand this.

In Unix, when I run the following from ksh:

ls *


the shell expands the * to whatever files/folders are in the directory in which the command is being run.

In DOS, when I run the equivalent command:

dir *


the DOS shell does nothing. It is up to the dir command to take the incoming * and use it as a filter on the list of possible files/folders.

NK is acting like DOS. I would submit that it should act like Unix.

EVERY accessor has to assume that any arguments passed to it, if it is expecting any arguments, may be sub-requests. Therefore EVERY accessor has to pre-process every argument on the off-chance that it reflects a sub-request. This forces EVERY accessor to act like the DOS version of a command which is responsible for everything, instead of like the Unix version which is only responsible for its specific behavior.

NK is acting like the DOS shell when (I believe) it should be acting like a Unix shell. NK already has too much boilerplate code.

I guess I will post this on the feature request list.

Menzo, thanks for taking the time to address this. Randy and I have had a discussion about this as well which is where the above comparison comes from.
Like · Post Reply
nk4um User
Posts: 111
April 21, 2008 07:55
You need to resolve the URI your parameter contains. Here is what I do in one of my JavaScript accessors:


var uri = req.getArgument("myArg");
var val = req.getArgumentValue(uri);
if (val == null)
   val = uri;


So in some cases, and probably your case, you get the URI which you need to resolve to get the value. In other cases you the argument contains the value directly.

Hope this helps,

Menzo
Like · Post Reply
nk4um User
Posts: 54
April 20, 2008 23:22Resolving URIs
I have just written an accessor. I am passing another URI to it as an argument. I thought that the NK engine would resolve URIs as long as it was able to resolve them, but that does not seem to be the case.

I have an accessor that can return the value of an environment variable:

env:path

This would return, for example, /usr/bin:/bin.

My second accessor wants a string of paths sent to it to determine if a program exists on somewhere along those paths.

I defined a URI with both accessors like this:

active:existsOnPath+executable@diff+path@path:env

The existsOnPath accessor sees the string "path:env" when it checks the path argument. Shouldn''t it have found the /usr/bin:/bin string instead? Am I hoping that the NK engine is doing more than it really is?
Like · Post Reply