|
From: Stiegler, M. D <mar...@hp...> - 2012-07-02 17:02:02
|
You will see another example of handling a promise, this time using a when block, in the Cookie Shop source, when it gets the amount of money back from the deposit(purse) method and figures out how many cookies have been purchased. In the passage you sent us, you didn't need to do any resolution at all since you are simply forwarding the promise on to the next guy.
You can only use call() under very special circumstances, when you are quite certain that the promise has been resolved. I still get burned myself occasionally, being almost certain that the promise is resolved, which is not quite good enough :-) A promise that will be resolved in another vat can never just be called, all the special cases are ones in which the promise is being retrieved from another object in the same vat as the requestor.
Having said that, allow me to point out a sorta exception :-) In Clusterken there is a class com.hp.pipe.AllDone, which accumulates a collection of promises and returns a Promise<Boolean> that will resolve when all the promises have finished processing. Inside the when-block for the AllDone promise, you can use call() on promises that were in the collection, because you do know that they are resolved (you still have to handle broken promises in the catch clause). This is a "sorta exception" because you are using call() on a promise fulfilled in a remote vat, but you waited in a when-block for the AllDone to finish :-)
--marcs
> -----Original Message-----
> From: Tyler Close [mailto:tyl...@gm...]
> Sent: Friday, June 29, 2012 9:14 PM
> To: Implementation and use of web-calculus technology
> Subject: Re: [Waterken-server] how to resolve a promise in java code?
>
> On Fri, Jun 29, 2012 at 8:33 AM, Hunter Kelly <re...@gm...> wrote:
> > We've been trying to use promise.call() to get the results from a
> > promise, but we get the following stack trace:
> >
> > org.ref_send.promise.Unresolved
> > at org.ref_send.promise.Eventual$Tail.call(Eventual.java:789)
> > at
> com.viscis.poc.Administrator$X.lookupMessage(Administrator.java:74)
> > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> > at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.ja
> va:39)
> > at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccesso
> rImpl.java:25)
> > at java.lang.reflect.Method.invoke(Method.java:597)
> > at org.joe_e.reflect.Reflection.invoke(Reflection.java:343)
> > at org.waterken.remote.http.Callee$1.apply(Callee.java:176)
> > at
> org.waterken.remote.http.ServerSideSession.once(ServerSideSession.java:
> 87)
> > at org.waterken.remote.http.Callee.apply(Callee.java:130)
> > at org.waterken.remote.http.AMP$3.apply(AMP.java:142)
> > at org.waterken.remote.http.AMP$3.apply(AMP.java:137)
> > at org.waterken.jos.JODB.enter(JODB.java:196)
> > at org.waterken.remote.http.AMP$1$1.call(AMP.java:102)
> > at org.waterken.remote.http.AMP$1$1.call(AMP.java:92)
> > at org.waterken.thread.Loop$1.run(Loop.java:73)
> > at
> java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
> > at
> java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
> > at java.util.concurrent.FutureTask.run(FutureTask.java:138)
> > at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecut
> or.java:886)
> > at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.j
> ava:908)
> > at java.lang.Thread.run(Thread.java:680)
> >
> >
> > Any ideas on what we are doing wrong?
> >
> > the lookupMessage method looks like this:
> >
> > @Override
> > public Promise<String> lookupMessage(String name) {
> > Vat<User> v = users.get(name);
> > if (v == null)
> > throw new IllegalArgumentException("Invalid
> user/pass");
> > String message = null;
> > try {
> > message = v.top.getMessage().call();
>
> The "top" field of a Vat is a remote reference to the object created
> in a child vat. So that getMessage() invocation in the code above is
> an asynchronous invocation that returns a promise that will only be
> resolved after the message has been sent to the child vat, processed
> and returned. Since you're invoking the call() method right away, none
> of that has happened yet, so the promise is throwing the Unresolved
> exception.
>
> So you want to rewrite this method as:
>
> public Promise<String> lookupMessage(String name) {
> Vat<User> v = users.get(name);
> if (v == null)
> throw new IllegalArgumentException("Invalid user/pass");
> return v.top.getMessage();
> }
>
> If the caller of this method needs the eventual String value of the
> promise, they'll need to use an Eventual.when() invocation.
>
> I'll try to avoid asking the meta question of why this code is
> implementing a username/password scheme on top of a capability
> infrastructure. ;)
>
> --Tyler
>
> --
> "Waterken News: Capability security on the Web"
> http://waterken.sourceforge.net/recent.html
>
> -----------------------------------------------------------------------
> -------
> Live Security Virtual Conference
> Exclusive live event will cover all the ways today's security and
> threat landscape has changed and how IT managers can respond.
> Discussions
> will include endpoint security, mobile security and the latest in
> malware
> threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
> _______________________________________________
> Waterken-server mailing list
> Wat...@li...
> https://lists.sourceforge.net/lists/listinfo/waterken-server
|