From: Tyler C. <tyl...@gm...> - 2012-06-30 04:20:09
|
On Fri, Jun 29, 2012 at 9:14 PM, Tyler Close <tyl...@gm...> wrote: > 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.java:39) >> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.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(ThreadPoolExecutor.java:886) >> at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java: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. That when invocation looks like: class Hello extends Do<String,Promise<String>> implements Serializable { public Promise<String> fulfill(final String message) { return Eventual.ref(name + " sez: " + message); } } return _.when(v.top.getMessage(), new Hello()); --Tyler -- "Waterken News: Capability security on the Web" http://waterken.sourceforge.net/recent.html |